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

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: Install AWS CLI and Configure AWS Credentials

Follow below article to Install AWS CLI and Configure AWS CLI

How to Install AWS CLI on Linux

Follow below article to create IAM user in AWS and allow admin access

How to Create IAM User in AWS Step by Step and setup IAM Policy to user

Export the AWS IAM User credentials using command line

export AWS_ACCESS_KEY_ID=”accesskey”
export AWS_SECRET_ACCESS_KEY=”secretkey”

Step #3: Creating a directory and versions.tf file

Create a directory to save all terraform files which required to create VPC in AWS using terraform.

sudo mkdir dev-vpc

Navigate to directory

cd  dev-vpc 

Create version.tf file

sudo nano versions.tf

paste the below lines into it

terraform {
  required_version = ">= 0.12"
}

Step #4: Creating vars.tf file and Adding AWS Region name

Create vars.tf file and add AWS region name where you want to create VPC.

sudo nano vars.tf

Paste below lines into it.

variable "AWS_REGION" {
  default = "ap-south-1"
}

Step #5: 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.

provider "aws" {
  region = var.AWS_REGION
}

Step #6: 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 #7: 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.

Reference:

Terraform VPC official page

FOSS TechNix

FOSS TechNix (Free,Open Source Software's and Technology Nix*) founded in 2019 is a community platform where you can find How-to Guides, articles for DevOps Tools,Linux and Databases.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Share via
Copy link