Terraform Tutorial - VPC, Subnets, RouteTable, ELB, Security Group, and Apache server I
In this article, we're going to go over how to use make VPC, subnets, and route table.
Up to this point, we've been working under a folder (terraform), however, we'll make a new folder (terraform/VPC-LoadBalancer). So, we may want to run terraform init
in the newly created directory to get proper plugins.
After all done, we'll have the following files:
$ tree VPC-LoadBalancer/ VPC-LoadBalancer/ ├── elb.tf ├── install_httpd.sh ├── instances.tf ├── provider.tf ├── security-groups.tf ├── terraform.tfstate ├── terraform.tfstate.backup ├── variables.tf └── vpc.tf
$ terraform version Terraform v0.15.0 on darwin_amd64 + provider registry.terraform.io/hashicorp/aws v3.37.0 $ terraform init
Here are the files we need to create.
provider.tf:
provider "aws" { region = var.aws_region }
variables.tf:
variable "aws_region" { default = "us-east-1" } variable "vpc_cidr" { default = "10.20.0.0/16" } variable "subnets_cidr" { type = list default = ["10.20.1.0/24", "10.20.2.0/24"] } variable "azs" { type = list default = ["us-east-1a", "us-east-1b"] }
vpc.tf:
# VPC resource "aws_vpc" "terra_vpc" { cidr_block = var.vpc_cidr tags = { Name = "TerraVPC" } } # Internet Gateway resource "aws_internet_gateway" "terra_igw" { vpc_id = aws_vpc.terra_vpc.id tags = { Name = "main" } } # Subnets : public resource "aws_subnet" "public" { count = length(var.subnets_cidr) vpc_id = aws_vpc.terra_vpc.id cidr_block = element(var.subnets_cidr,count.index) availability_zone = element(var.azs,count.index) map_public_ip_on_launch = true tags = { Name = "Subnet-${count.index+1}" } } # Route table: attach Internet Gateway resource "aws_route_table" "public_rt" { vpc_id = aws_vpc.terra_vpc.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.terra_igw.id } tags = { Name = "publicRouteTable" } } # Route table association with public subnets resource "aws_route_table_association" "a" { count = length(var.subnets_cidr) subnet_id = element(aws_subnet.public.*.id,count.index) route_table_id = aws_route_table.public_rt.id }
In order for the resources in a VPC to send and receive traffic from the internet, the followings should be done:
- An internet gateway must be attached to the VPC.
- The route tables associated with our public subnet (including custom route tables) must have a route to the internet gateway.
resource "aws_internet_gateway" "terra_igw" { vpc_id = aws_vpc.terra_vpc.id
resource "aws_route_table" "public_rt" { vpc_id = "${aws_vpc.terra_vpc.id}" route { cidr_block = "0.0.0.0/0" gateway_id = "${aws_internet_gateway.terra_igw.id}" } ... # Route table association with public subnets resource "aws_route_table_association" "a" { count = length(var.subnets_cidr) subnet_id = element(aws_subnet.public.*.id,count.index) route_table_id = aws_route_table.public_rt.id }
Note that we used length()
to loop the two subnets and element()
to get the subnet_id.
Let's see what Terraform can give us:
$ terraform apply ... + aws_internet_gateway.terra_igw ... + aws_route_table.public_rt ... + aws_route_table_association.a[0] ... + aws_route_table_association.a[1] ... + aws_subnet.public[0] ... + aws_subnet.public[1] ... + aws_vpc.terra_vpc ... Apply complete! Resources: 7 added, 0 changed, 0 destroyed.
Terraform
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization