Turbocharge AWS VPC with Terraform in 2 mins.

Abhishek Yadav
5 min readOct 4, 2023

In today’s cloud-driven landscape, setting up an Amazon Web Services (AWS) Virtual Private Cloud (VPC) is a fundamental step in building secure and efficient network infrastructures. AWS VPCs serve as the invisible framework that allows applications and services to communicate seamlessly within the cloud. However, configuring an AWS VPC can be a daunting task, filled with intricate details and potential pitfalls.

Enter Terraform, a powerful tool that simplifies infrastructure management through code. If you’ve ever felt overwhelmed by the intricacies of AWS VPC setup, Terraform is here to rescue you. It enables you to define your desired VPC configuration in code, automating the entire process. No more manual clicks or complex command-line instructions.

In this blog, we’ll introduce our Terraform VPC module, that simplifies AWS VPC setup. We’ll demonstrate how our module streamlines the process. Whether you’re a cloud pro or newcomer, learn how Terraform can make AWS VPC setup easy.

The module benefits users by:

  1. Simplicity: It abstracts the complexities of AWS VPC configuration, allowing users to define their VPC setup in a clear and concise manner using Terraform code.
  2. Time Savings: Users can save valuable time by avoiding manual setup, clicks, and commands. The module handles resource provisioning automatically.
  3. Reduced Errors: Manual configurations often lead to mistakes. With our module, users can eliminate human errors, ensuring a reliable VPC infrastructure.
  4. Flexibility: Users can customize VPC settings, including subnets, NAT gateways, and tags, to suit their specific requirements.

Features

Our Terraform VPC module provides the following features:

  • VPC Creation: Easily create a VPC in AWS.
  • Public Subnets: Automatically set up public subnets complete with an internet gateway, route table, and necessary routes with the option to select Availability Zones.
  • Private, Database, EKS Subnets: Configure private subnets with NAT gateways, route tables, and essential routes with the option to select Availability Zones.
  • VPC flow logs (Cloudwatch and S3): Set create_flow_logs_s3 or create_flow_logs_cloudwatch to true and terraform will take care of IAM roles, policy or S3 buckets.

I’ve designed this module with flexibility in mind, allowing you to pick and choose exactly what components you want to create and configure. If you’ve already set up your VPC and wish to create specific subnets (public, private, EKS, or database), you can easily do so by toggling the respective options to ‘true’ or ‘false’ and you can define the CIDR blocks and select the Availability Zones where you want to create these subnets.

Clone the repo code from here.

Prerequisite:

  • Terraform
  • AWS CLI

To use this terraform module, all you need to do is modify terraform.tfvars file.

region = "ap-south-1"  # Set the region according to your use.

Default tags: All tags in this block will be applied to all resources.

tags = {
"owner" = "Abhishek"
}

central availbilty zone: Set this list accoording to AZ's available in the region you have configured.
Note: Subnets will be created in the same order you are specifying AZ.

availability_zone = ["ap-south-1a", "ap-south-1b", "ap-south-1c"]
central vpc id: If you are creating VPC then the value here must be blank string "". if not creating `VPC` use this to pass vpc_id to all resources. values passed here will be used as vpc id. 

vpc_id = "vpc-123456789"

vpc_creation = false # Set to true to create a VPC.
vpc_name = "Production" # Name of the VPC.
vpc_cidr_block = "10.200.0.0/16" # CIDR block for the VPC.
vpc_enable_dns_hostnames = true # Enable DNS hostnames for instances in the VPC.
vpc_enable_dns_support = true # Enable DNS support for the VPC.

# Tags specific to the VPC resource.
vpc_tags = {
"Managed by" = "Terraform"
}

# Public Subnets Configuration
NOTE: Route table and routes will be created automatically.

create_public_subnets = true
igw_create = true # Required when creating Public subnets
public_subnet_name = "Production" # Name for the public subnets. You just need to specify main name, it will add public-subnet-{count index} by default.
public_subnets = ["10.200.101.0/24", "10.200.102.0/24", "10.200.103.0/24"] # List of public subnet CIDR blocks.

# Tags specific to the public subnets.
public_subnets_tags = {
"Managed by" = "Terraform"
}


# Private Subnets Configuration
NOTE: Route table and routes will be created automatically.
create_private_subnets = true
private_subnets_name = "production" # Name for the private subnets. You just need to specify main name, it will add private-subnet-{count index} by default.
private_subnet_nat = "" # ID of the NAT gateway in case you are not creating NAT from here. If creating leave it blank.


private_subnets = ["10.200.1.0/24", "10.200.2.0/24", "10.200.3.0/24"] # List of private subnet CIDR blocks. Empty the list to if not creating private subnets and make create_private_subnets = false

# Tags specific to the private subnets.
private_subnets_tags = {
"Managed by" = "Terraform"
}

# NAT Configuration
nat_create = true # If not creating NAT set it to false.
nat_name = "production" # Name for the NAT gateway.
nat_public_subnet_id = "" # Optional. If you are not creating public subnets here then specify Public subnet id to create public nat gateway. If not creating NAT (false) then specify random value. If creating then leave it blank and NAT gateway will be created in first (index) public subnet.

# Tags specific to the NAT gateway.
nat_tags = {
"Managed by" = "Terraform"
}


# Database subnets Configuration
NOTE: Route table and routes will be created automatically.

create_database_subnets = true
database_subnets_name = "production"
database_subnet_nat = "" # ID of the NAT gateway in case you are not creating NAT from here. If creating leave it blank.
database_subnets = ["10.200.4.0/24", "10.200.5.0/24", "10.200.6.0/24"] #if you are not creating database subnets then empty the list to reduce conflicts "[]" and set create_database_subnets = false.

# Tags specific to the NAT gateway.
database_subnets_tags = {
"Managed by" = "Terraform"
}

# EKS subnets Configuration
NOTE: Route table and routes will be created automatically.

create_eks_subnets = true
eks_subnets_name = "production"
eks_subnet_nat = "" # ID of the NAT gateway in case you are not creating NAT from here. If creating leave it blank.
eks_subnets = ["10.200.7.0/24", "10.200.8.0/24", "10.200.9.0/24"] #if you are not creating eks subnets then empty the list to reduce conflicts "[]" and set create_eks_subnets = false.
eks_subnets_tags = {
"Managed by" = "Terraform"
}

#flow logs cloudwatch configuration
NOTE: Cloudwatch logs group will be created with name = ${flow_logs_cloudwatch_name}-log-group by default along with the required IAM roles.

create_flow_logs_cloudwatch = false
flow_logs_cloudwatch_name = "production"

#flow logs s3 configuration
NOTE: S3 bucket will be created with name = ${var.flow_logs_s3_name}-flow-logs-bucket

create_flow_logs_s3 = true
flow_logs_s3_name = "production"

(Optional) In case you want to configure backend as S3, then you can modify providers.tf

terraform {
required_version = ">= 1.1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
backend "s3" {
bucket = "terraform-state-files"
key = "folder/terrform.tfstate"
region = "us-west-1"
}

}
}

provider "aws" {
region = var.region
shared_credentials_files = ["~/.aws/credentials"]
}

After making the required changes just run

terraform init
terraform plan #Review the plan
terraform apply

To access my Terraform module code and explore its capabilities, you can find the code in my GitHub repository: Abhishek-EN

I value community collaboration and welcome your input to make this Terraform VPC module even better. If you have suggestions, improvements, or ideas to enhance this module, i invite you to contribute.

I am open to further discussions on automation & DevOps. You can follow me on LinkedIn and Medium, I talk about DevOps, Learnings & Leadership.

--

--

Abhishek Yadav

DevOps Engineer with hands on experience and skills in deployment and automation of cloud infrastructure. Worked with startup and leading organizations