What is a Subnet?

A subnet, short for “subnetwork,” is a range of IP addresses within your VPC (Virtual Private Cloud). When you create a VPC, you must specify a CIDR block for the VPC, which is a range of private IPv4 addresses. Within this VPC, you can define one or more subnets, also with CIDR blocks, that are smaller ranges within the VPC’s CIDR block.

Types of Subnets in AWS:

Public Subnet:

 A subnet that has a route to the Internet through an Internet Gateway.

Usage: Suitable for resources that must be directly accessible from the Internet, like a web server, load balancers etc.

Private Subnet

A subnet that does not have a route to the Internet.

Usage: Suitable for resources that shouldn’t be directly accessed from the Internet, like a database.

VPN-Only Subnet

A subnet that has a route to a Virtual Private Network (VPN) but not to the Internet.

Usage: Suitable for resources that should only be accessible through a VPN.

Note: AWS reserves 5 IP addresses (first 4 and last one) in each subnet, making it 5 IP addresses that are not available to use in a subnet.

For example 10.0.1.0/24 have these reserved IP addresses:

  1. 10.0.1.0 – Network Address 
  2. 10.0.1.1 –  Reserved by AWS for VPC router
  3. 10.0.1.2 – Reserved by AWS for mapping to Amazon-provided DNS
  4. 10.0.1.3 –  Reserved by AWS for future use
  5. 10.0.1.255 – Reserved for Network Broadcast Address. NBA is not supported in VPC  

We are going to update our code to add 6 subnets, 2 public subnets and 4 private subnets:

2 Public Subnets

# public subnet in AZ 1
resource "aws_subnet" "dev-public-subnet-AZ1" {
  vpc_id                  = aws_vpc.aws-vpc.id
  cidr_block              = "10.0.0.0/24"
  availability_zone       = "eu-west-1a"
  map_public_ip_on_launch = true


  tags = {
    Name = "dev-public-subnet-AZ1"
    env  = "dev"
  }
}


# public subnet in AZ 2
resource "aws_subnet" "dev-public-subnet-AZ2" {
  vpc_id                  = aws_vpc.aws-vpc.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "eu-west-1b"
  map_public_ip_on_launch = true


  tags = {
    Name = "dev-public-subnet-AZ2"
    env  = "dev"
  }
}

4 Private Subnets:


# private subnets in AZ 1
resource "aws_subnet" "dev-private-app-subnet-AZ1" {
  vpc_id            = aws_vpc.aws-vpc.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "eu-west-1a"


  tags = {
    Name = "dev-private-app-subnet-AZ1"
    env  = "dev"
  }
}


resource "aws_subnet" "dev-private-data-subnet-AZ1" {
  vpc_id            = aws_vpc.aws-vpc.id
  cidr_block        = "10.0.4.0/24"
  availability_zone = "eu-west-1a"


  tags = {
    Name = "dev-private-data-subnet-AZ1"
    env  = "dev"
  }
}


# private subnets in AZ 2
resource "aws_subnet" "dev-private-app-subnet-AZ2" {
  vpc_id            = aws_vpc.aws-vpc.id
  cidr_block        = "10.0.3.0/24"
  availability_zone = "eu-west-1b"


  tags = {
    Name = "dev-private-app-subnet-AZ2"
    env  = "dev"
  }
}


resource "aws_subnet" "dev-private-data-subnet-AZ2" {
  vpc_id            = aws_vpc.aws-vpc.id
  cidr_block        = "10.0.5.0/24"
  availability_zone = "eu-west-1b"


  tags = {
    Name = "dev-private-data-subnet-AZ2"
    env  = "dev"
  }
}

Next, we need to apply our changes

terraform apply
Check AWS Console.
Current architecture

Don’t forget to destroy resources if you plan to continue later

terraform destroy