How to Create VPC in AWS using Terraform [5 Steps]

RajatRajat
5 min read

Using Terraform:

by Rajat Kumar

Home » How to Create VPC in AWS using Terraform [7 Steps]

In this article we are going to cover Install terraform, Install and configure AWS CLI, Creating IAM user in AWS , configuring AWS credentials and How to Create VPC in AWS using Terraform

Table of Contents

Step #1: Install Terraform

Follow below article to Install Terraform on Ubuntu

How to Install Terraform on Ubuntu 20.04/18.04/16.04 LTS

Step #2: Run command

aws configure

Enter your Access key and Secret Key

Step #3: Creating provider.tf file and adding AWS Region name Variable

Create provider.tf file to add AWS region name variable

sudo nano provider.tf

paste the below lines into it.

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "5.31.0"
    }
  }
}

provider "aws" {
  # Configuration options
  region = "us-east-1"
}

Step #4: How to Create VPC in AWS using Terraform

Create vpc.tf file to add VPC details

sudo nano vpc.tf

Paste the below lines into it.

# Creating VPC,name, CIDR and Tags
resource "aws_vpc" "dev" {
  cidr_block           = "10.0.0.0/16"
  instance_tenancy     = "default"
  enable_dns_support   = "true"
  enable_dns_hostnames = "true"
  enable_classiclink   = "false"
  tags = {
    Name = "dev"
  }
}

# Creating Public Subnets in VPC
resource "aws_subnet" "dev-public-1" {
  vpc_id                  = aws_vpc.dev.id
  cidr_block              = "10.0.1.0/24"
  map_public_ip_on_launch = "true"
  availability_zone       = "ap-south-1a"

  tags = {
    Name = "dev-public-1"
  }
}

resource "aws_subnet" "dev-public-2" {
  vpc_id                  = aws_vpc.dev.id
  cidr_block              = "10.0.2.0/24"
  map_public_ip_on_launch = "true"
  availability_zone       = "ap-south-1b"

  tags = {
    Name = "dev-public-2"
  }
}

# Creating Private Subnets in VPC
resource "aws_subnet" "dev-private-1" {
  vpc_id                  = aws_vpc.dev.id
  cidr_block              = "10.0.3.0/24"
  map_public_ip_on_launch = "false"
  availability_zone       = "ap-south-1a"

  tags = {
    Name = "dev-private-1"
  }
}

resource "aws_subnet" "dev-private-2" {
  vpc_id                  = aws_vpc.dev.id
  cidr_block              = "10.0.4.0/24"
  map_public_ip_on_launch = "false"
  availability_zone       = "ap-south-1b"

  tags = {
    Name = "dev-private-2"
  }
}


# Creating Internet Gateway in AWS VPC
resource "aws_internet_gateway" "dev-gw" {
  vpc_id = aws_vpc.dev.id

  tags = {
    Name = "dev"
  }
}

# Creating Route Tables for Internet gateway
resource "aws_route_table" "dev-public" {
  vpc_id = aws_vpc.dev.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.dev-gw.id
  }

  tags = {
    Name = "dev-public-1"
  }
}

# Creating Route Associations public subnets
resource "aws_route_table_association" "dev-public-1-a" {
  subnet_id      = aws_subnet.dev-public-1.id
  route_table_id = aws_route_table.dev-public.id
}

resource "aws_route_table_association" "dev-public-2-a" {
  subnet_id      = aws_subnet.dev-public-2.id
  route_table_id = aws_route_table.dev-public.id
}

Step #5: Creating NAT Gateway and Routes Tables in AWS VPC

Create nat.tf file to add VPC NAT gateway and route tables for private subnets

sudo nano nat.tf

Paster the below lines into it.

# Creating Nat Gateway
resource "aws_eip" "nat" {
  vpc = true
}

resource "aws_nat_gateway" "nat-gw" {
  allocation_id = aws_eip.nat.id
  subnet_id     = aws_subnet.dev-public-1.id
  depends_on    = [aws_internet_gateway.dev-gw]
}

# Add routes for VPC
resource "aws_route_table" "dev-private" {
  vpc_id = aws_vpc.dev.id
  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat-gw.id
  }

  tags = {
    Name = "dev-private-1"
  }
}

# Creating route associations for private Subnets
resource "aws_route_table_association" "dev-private-1-a" {
  subnet_id      = aws_subnet.dev-private-1.id
  route_table_id = aws_route_table.dev-private.id
}

resource "aws_route_table_association" "dev-private-2-a" {
  subnet_id      = aws_subnet.dev-private-2.id
  route_table_id = aws_route_table.dev-private.id
}

Run the terraform init in current directory

terraform init

Run the terraform plan in current directory

terraform plan

Sample Output:

# aws_vpc.dev will be created
  + resource "aws_vpc" "dev" {
      + arn                              = (known after apply)
      + assign_generated_ipv6_cidr_block = false
      + cidr_block                       = "10.0.0.0/16"
      + default_network_acl_id           = (known after apply)
      + default_route_table_id           = (known after apply)
      + default_security_group_id        = (known after apply)
      + dhcp_options_id                  = (known after apply)
      + enable_classiclink               = false
      + enable_classiclink_dns_support   = (known after apply)
      + enable_dns_hostnames             = true
      + enable_dns_support               = true
      + id                               = (known after apply)
      + instance_tenancy                 = "default"
      + ipv6_association_id              = (known after apply)
      + ipv6_cidr_block                  = (known after apply)
      + main_route_table_id              = (known after apply)
      + owner_id                         = (known after apply)
      + tags                             = {
          + "Name" = "main"
        }
      + tags_all                         = {
          + "Name" = "dev"
        }
    }

Plan: 14 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Run terraform apply to create VPC in AWS using Terraform

terraform apply

Sample Output:

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_eip.nat: Creating...
aws_vpc.dev: Creating...
aws_eip.nat: Creation complete after 0s [id=eipalloc-05379158933e51915]
aws_vpc.dev: Still creating... [10s elapsed]
aws_vpc.dev: Creation complete after 11s [id=vpc-0ce7096b7733ce0c8]
aws_subnet.dev-private-2: Creating...
aws_subnet.dev-public-2: Creating...
aws_subnet.dev-public-1: Creating...
aws_subnet.dev-private-1: Creating...
aws_internet_gateway.dev-gw: Creating...
aws_internet_gateway.dev-gw: Creation complete after 0s [id=igw-0353f0af211521751]
aws_route_table.dev-public: Creating...
aws_subnet.dev-private-1: Creation complete after 0s [id=subnet-009eba556c3a60c6c]
aws_subnet.dev-private-2: Creation complete after 0s [id=subnet-058b33281fd02d4d1]
aws_route_table.dev-public: Creation complete after 0s [id=rtb-0bd1d40c43fe1d549]
aws_subnet.dev-public-2: Still creating... [10s elapsed]
aws_subnet.dev-public-1: Still creating... [10s elapsed]
aws_subnet.dev-public-2: Creation complete after 10s [id=subnet-0d2df9e3589ddb413]
aws_route_table_association.dev-public-2-a: Creating...
aws_subnet.dev-public-1: Creation complete after 10s [id=subnet-0e6e2a39eb75e2cf8]
aws_route_table_association.dev-public-1-a: Creating...
aws_nat_gateway.nat-gw: Creating...
aws_route_table_association.dev-public-2-a: Creation complete after 0s [id=rtbassoc-0e3a08d1bee9d404a]
aws_route_table_association.dev-public-1-a: Creation complete after 0s [id=rtbassoc-0a8a84a1f3a4d9cf0]
aws_nat_gateway.nat-gw: Still creating... [10s elapsed]
aws_nat_gateway.nat-gw: Still creating... [20s elapsed]
aws_nat_gateway.nat-gw: Still creating... [30s elapsed]
aws_nat_gateway.nat-gw: Still creating... [40s elapsed]
aws_nat_gateway.nat-gw: Still creating... [50s elapsed]
aws_nat_gateway.nat-gw: Still creating... [1m0s elapsed]
aws_nat_gateway.nat-gw: Still creating... [1m10s elapsed]
aws_nat_gateway.nat-gw: Still creating... [1m20s elapsed]
aws_nat_gateway.nat-gw: Still creating... [1m30s elapsed]
aws_nat_gateway.nat-gw: Still creating... [1m40s elapsed]
aws_nat_gateway.nat-gw: Creation complete after 1m44s [id=nat-09d99bb965579549c]
aws_route_table.dev-private: Creating...
aws_route_table.dev-private: Creation complete after 0s [id=rtb-09d5b62e2df8116bc]
aws_route_table_association.dev-private-2-a: Creating...
aws_route_table_association.dev-private-1-a: Creating...
aws_route_table_association.dev-private-1-a: Creation complete after 1s [id=rtbassoc-02e46253919662c35]
aws_route_table_association.dev-private-2-a: Creation complete after 1s [id=rtbassoc-0c806d1ed44a30eff]

Apply complete! Resources: 14 added, 0 changed, 0 destroyed.

Login to AWS console you will see VPC is created

How to Create VPC in AWS using Terraform [7 Steps] 1

Click on Subnets in VPC

How to Create VPC in AWS using Terraform [7 Steps] 2

Run below command to destroy the VPC in AWS

terraform destroy

Conclusion:

We have covered Install terraform, Install and configure AWS CLI, Creating IAM user in AWS , configuring AWS credentials and How to Create VPC in AWS using Terraform.

1
Subscribe to my newsletter

Read articles from Rajat directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rajat
Rajat

I'm a DevOps enthusiast from India, eager to learn and grow. Despite being a fresher, I've gained hands-on experience with AWS, Docker, Kubernetes, RHCSA, and CI/CD, and completed some Udemy courses. I'm always open to new insights and connections in the DevOps community. Let's connect!