In this guide, we will see how to create AWS VPC in any AWS region with just one line command terraform apply
and you will have AWS VPC ready
git clone https://github.com/Muhammad-Usama-1/aws-vpc-with-terraform
after cloning the repo you would have only four files
from which one file terraform.tfvars
would be empty and we are required to add our AWS credentials access_key secret_key
to this file for creating any resource in the AWS account.
copy the Access key, and secret key and paste them to
terraform.tfvars
file
access_key=some-random-valu-from-aws
secret_key=some-secret-from-aws
Now run
terraform init
now go to the variable.tf
file in which we will need to modify the region CIDR for VPC and network for subnets and Project name
This block is setting region, availability zone for that regionavailability_zones
,
but what if we want to change the region we need to change region name ,availability zone
you need to change the region name and run terraform refresh
and it will print available zones for that region to replace the availability_zones
from new values
in this example, I am changing to ap-south-1
variable.tf
file
#ADjust project name
variable "project" {
# Change this with your Project name
default = "project-name"
type = string
}
#ADjust region name
variable "region" {
default = "ap-south-1"
type = string
}
data "aws_availability_zones" "example" {
state = "available"
}
output "availability_zones" {
value = data.aws_availability_zones.example.names
}
#ADjust region azs
variable "availability_zones" {
default =[
"ap-south-1a",
"ap-south-1b",
"ap-south-1c",
]
type = list
description = "List of availability zones"
}
variable "vpc_cidr" {
# CIDR for your new VPC , 10.0.0.0/16 means you can not change first 10.0 (16 bits) when creating subnetwork(subnet, private or piblci)
default = "10.0.0.0/16"
type = string
}
variable "public_subnet_cidr_blocks" {
# Change this if change vpc_cidr
default = ["10.0.0.0/24", "10.0.2.0/24"], now run
type = list
description = "List of public subnet CIDR blocks"
}
variable "private_subnet_cidr_blocks" {
# Change this if change vpc_cidr
default = ["10.0.100.0/24", "10.0.101.0/24"]
type = list
description = "List of private subnet CIDR blocks"
}
variable "access_key" {
description = "AWS Access Key ID"
type = string
}
variable "secret_key" {
description = "AWS Secret Access Key"
type = string
}
provider.tf
file
provider "aws" {
region = var.region
access_key = var.access_key
secret_key = var.secret_key
}
terraform.tfvars
file
access_key =
secret_key =
vpc.tf
file
# VPC
resource "aws_vpc" "default" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.project}-vpc",
}
}
# Creating Public subnets
resource "aws_subnet" "public" {
count = length(var.public_subnet_cidr_blocks)
vpc_id = aws_vpc.default.id
cidr_block = var.public_subnet_cidr_blocks[count.index]
availability_zone = var.availability_zones[count.index]
map_public_ip_on_launch = true
tags = {
# Name = "${var.project}-pub-subnet-${substr(var.availability_zones[count.index], 8, 2)}",
Name = "${var.project}-pub-subnet-${var.availability_zones[count.index]}"
}
}
# Creating Private subnets
resource "aws_subnet" "private" {
count = length(var.private_subnet_cidr_blocks)
vpc_id = aws_vpc.default.id
cidr_block = var.private_subnet_cidr_blocks[count.index]
availability_zone = var.availability_zones[count.index]
tags = {
# Name = "${var.project}-priv-subnet-${substr(var.availability_zones[count.index], 8, 2)}",
Name = "${var.project}-priv-subnet-${var.availability_zones[count.index]}"
}
}
# Creating internet gateway for accesing to internet
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.default.id
tags = {
Name = "${var.project}-igw"
}
}
# create route table with a record to internet incase of 0.0.0.0
resource "aws_route_table" "public-rt" {
vpc_id = aws_vpc.default.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
tags = {
Name = "${var.project}-public-rt"
}
}
resource "aws_eip" "nat" {
domain = "vpc"
}
resource "aws_nat_gateway" "default" {
depends_on = [aws_internet_gateway.igw]
allocation_id = aws_eip.nat.id
# Launching aws nat gateway in public subnet
subnet_id = aws_subnet.public[1].id
}
resource "aws_route_table" "private" {
vpc_id = aws_vpc.default.id
tags = {
# Name = "nat-gateway-rt"
Name = "${var.project}-nat-gateway-rt"
}
}
resource "aws_route" "private" {
route_table_id = aws_route_table.private.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.default.id
}
resource "aws_route_table_association" "private" {
count = length(var.private_subnet_cidr_blocks)
subnet_id = aws_subnet.private[count.index].id
route_table_id = aws_route_table.private.id
}
resource "aws_route_table_association" "public" {
count = length(var.public_subnet_cidr_blocks)
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public-rt.id
}
now we have adjusted the region and project name, run the terraform apply
to create a VPC
terraform apply
write yes
when it prompts, it will create the new VPC in your AWS account
It has created a whole new VPC in just 2 minutes
if we want to create another subnet in the available zone add CIDR for that in the below block
after making changes just run terraform apply
again it will make changes
Clean up
Terraform provides a command used to tear down and remove infrastructure resources provisioned using Terraform.
terraform destroy
it will ask for yes
to destroy, enter yes
Destroyed infra in a mint