Terraform for AWS VPCs: A Complete Guide

“The Beauty of DevOps is Automation”

Ranjeet Jadhav
5 min readJul 10, 2023
aws-vpc-architecture

Introduction:

In the world of DevOps, automation reigns supreme. What if I told you that creating a customized VPC on the AWS cloud could take no more than 2–3 minutes? Yes, you heard that right! In this blog post, we’ll explore the wonders of Terraform — a powerful infrastructure management tool that allows you to effortlessly create, update, and destroy your infrastructure.

What is Terraform?

Terraform is a game-changing infrastructure management tool that empowers users to orchestrate their infrastructure with ease. It simplifies the process of creating, updating, and destroying infrastructure components.

The Traditional VPC Creation Process:

When creating a VPC through the AWS dashboard manually, several steps need to be followed:

  1. Create a VPC with a specified CIDR block.
  2. Create an Internet Gateway (IGW) and attach it to the VPC.
  3. Launch both public and private subnets in different availability zones within the same region.
  4. Create an Elastic IP (EIP).
  5. Create a NAT (Network Address Translation) gateway and associate it with the EIP.
  6. Create and configure a route table.

This process can take anywhere from 10 to 15 minutes to complete. Additionally, as humans, we are prone to making mistakes, which may require troubleshooting to identify and rectify any errors that occur.

The Power of Terraform:

Fortunately, Terraform offers a faster and more efficient alternative. By leveraging Terraform, you can create a fully customized VPC in just 2–3 minutes — saving time and effort. Let’s dive into the steps required to create a VPC using Terraform.

Prerequisites: Before we begin, make sure you have the following prerequisites set up on your ubuntu 20 machine:

  1. Install Terraform:
  • Run the following commands to install Terraform:
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform

2. Install AWS CLI:

  • Execute the following commands to install the AWS CLI:
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

3. Configure AWS CLI:

  • Create an access key and secret key for your IAM user, ensuring it has proper permissions to create the VPC.
  • Run the following command and provide the requested information:
aws configure

Creating a VPC Using Terraform:

Let’s get started with creating a VPC using Terraform. Follow these steps:

  1. Create a new folder to house all the configuration files:
mkdir terra-vpc-aws-demo
  1. Create the main.tf file inside the newly created folder and populate it with the following code:
provider "aws" {
region = "us-east-2"

}

data "aws_availability_zones" "available" {}

#-------------VPC and Internet Gateway------------------------------------------
resource "aws_vpc" "sbi" {
cidr_block = var.vpc_cidr
tags = merge(var.tags, { Name = "${var.env}-vpc" })
}

resource "aws_internet_gateway" "sbi" {
vpc_id = aws_vpc.sbi.id
tags = merge(var.tags, { Name = "${var.env}-igw" })
}

#-------------Public Subnets and Routing----------------------------------------
resource "aws_subnet" "public_subnets" {
count = length(var.public_subnet_cidrs)
vpc_id = aws_vpc.sbi.id
cidr_block = element(var.public_subnet_cidrs, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = merge(var.tags, { Name = "${var.env}-public-${count.index + 1}" })
}

resource "aws_route_table" "public_subnets" {
vpc_id = aws_vpc.sbi.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.sbi.id
}
tags = merge(var.tags, { Name = "${var.env}-route-public-subnets" })
}

resource "aws_route_table_association" "public_routes" {
count = length(aws_subnet.public_subnets[*].id)
route_table_id = aws_route_table.public_subnets.id
subnet_id = aws_subnet.public_subnets[count.index].id
}

#-----NAT Gateways with Elastic IPs--------------------------

resource "aws_eip" "nat" {
# count = length(var.private_subnet_cidrs)
vpc = true
tags = merge(var.tags, { Name = "${var.env}-nat-gw" })
}


resource "aws_nat_gateway" "nat" {
# count = length(var.private_subnet_cidrs)
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public_subnets[0].id
tags = merge(var.tags, { Name = "${var.env}-nat-gw" })
}

#--------------Private Subnets and Routing-------------------------
resource "aws_subnet" "private_subnets" {
count = length(var.private_subnet_cidrs)
vpc_id = aws_vpc.sbi.id
cidr_block = var.private_subnet_cidrs[count.index]
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = merge(var.tags, { Name = "${var.env}-private-${count.index + 1}" })
}

resource "aws_route_table" "private_subnets" {
# count = length(var.private_subnet_cidrs)
vpc_id = aws_vpc.sbi.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat.id
}
tags = merge(var.tags, { Name = "${var.env}-route-private-subnet" })
}

resource "aws_route_table_association" "private_routes" {
count = length(aws_subnet.private_subnets[*].id)
route_table_id = aws_route_table.private_subnets.id
subnet_id = aws_subnet.private_subnets[count.index].id
}

Explaining the Terraform Configuration:
The provided Terraform configuration file (main.tf) sets up the infrastructure for the VPC.

It includes: Provider configuration for the AWS region.
Resource definitions for VPC, internet gateway, public subnets, routing tables, and NAT gateways.

Next, create a variable.tf file within the same folder and add the following code:

variable "env" {
default = "dev"
}
variable "vpc_cidr" {
default = "10.0.0.0/16"
}
variable "public_subnet_cidrs" {
default = [
"10.0.1.0/24",
"10.0.2.0/24",
]
}
variable "private_subnet_cidrs" {
default = [
"10.0.11.0/24",
"10.0.22.0/24",
]
}
variable "tags" {
default = {
Owner = "Ranjeet JADHAV"
Project = "Terraform"
}
}

The variable.tf file defines variables used in the main.tf file to customize the VPC configuration.

You can find all the files in below git repository.

git clone https://github.com/ranjeetrj/terraform-vpc.git

Validation and Execution: Once the configuration files are in place, follow these steps to validate and execute the Terraform code:

  1. Initialize Terraform in the project directory:
terraform init

2. Validate the configuration files:

terraform validate

3. Generate a plan to preview the resources that will be created:

terraform plan

4. Execute the Terraform configuration and create the VPC:

terraform apply

This process usually takes 2–3 minutes to complete.

Modifying the VPC:

If you wish to add or remove subnets, simply modify the variable.tf file accordingly and re-execute the terraform apply command.

Destroying the VPC:

To remove the VPC and associated resources created using Terraform, execute the following command:

terraform destroy

Conclusion:

With Terraform, creating a fully customized VPC on AWS has never been easier. By leveraging the power of automation, you can save time, eliminate manual errors, and ensure consistent infrastructure deployments. So why wait? Embrace Terraform and unlock the potential of infrastructure management in the world of DevOps.

Remember, with Terraform, you can create a VPC in just a few minutes, giving you more time to focus on other important tasks. Enjoy the benefits of automation and let Terraform simplify your infrastructure management journey.

Happy coding!

--

--