AWS Builder Center

building a VPC with Terraform

Build a small AWS VPC with Terraform

A public subnet is just a route: building a VPC with Terraform

Many beginners think "public" and "private" are two kinds of subnet in AWS. They are not. A subnet is public only because its route table sends Internet traffic to an internet gateway. In this article we build a small VPC with Terraform and check that with one CLI command.
Everything created here is free: no instances and no NAT gateway.

Step 1: Write the infrastructure

Create a folder with a single file, main.tf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
provider "aws" {
region = "eu-west-1"
}

resource "aws_vpc" "lab" {
cidr_block = "10.0.0.0/16"
tags = { Name = "lab-vpc" }
}

resource "aws_subnet" "public" {
vpc_id = aws_vpc.lab.id
cidr_block = "10.0.1.0/24"
tags = { Name = "public" }
}

resource "aws_subnet" "private" {
vpc_id = aws_vpc.lab.id
cidr_block = "10.0.2.0/24"
tags = { Name = "private" }
}

resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.lab.id
}

resource "aws_route_table" "public" {
vpc_id = aws_vpc.lab.id

route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
}

resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}

output "vpc_id" {
value = aws_vpc.lab.id
}
The two subnets are declared the same way. The only difference is the last resource, which attaches the public subnet to a route table with a default route.

Step 2: Deploy

1
2
terraform init
terraform apply

Step 3: Check the routes

1
2
3
4
aws ec2 describe-route-tables \
--filters "Name=vpc-id,Values=$(terraform output -raw vpc_id)" \
--query "RouteTables[].Routes[].[DestinationCidrBlock,GatewayId]" \
--output table
You will see two route tables:
  • The main one, used by the private subnet, has a single route: 10.0.0.0/16 -> local.
  • The public one has the same local route plus 0.0.0.0/0 -> igw-....
That extra line is the whole difference between public and private.

Step 4: Clean up

1
terraform destroy

Conclusion

When something in a VPC can't reach the Internet, look at the route table of its subnet first. The name of the subnet tells you nothing; the routes tell you everything.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article