How to Create AWS VPC Using Terraform

terraform aws vpc

In this blog, you will learn to create AWS VPC using well structure terraform modules. It is a step by step guide for beginners with detailed information.

Prerequisites

To follow this guide you need to have the following.

  1. The latest Terraform binary is installed and configured in your system.
  2. AWS CLI installed and configured with a Valid AWS account with full permissions to create and manage AWS VPC service.
  3. If you are using terraform on an ec2 instance, ensure you have a valid IAM role attached to the instance with VPC provisioning permissions.

Terraform AWS VPC Code Repository

AWS VPC terraform code is part of the terraform AWS repository. Clone it to your workstation to follow the guide.

git clone https://github.com/techiescamp/terraform-aws.git

Fork and clone the repository if you intend to reuse and make changes as per your requirements.

Terraform AWS VPC Creation Workflow

The VPC terraform code is structured in the following way.

├── infra
│   └── vpc
│       ├── main.tf
│       └── variables.tf
├── modules
│   └── vpc
│       ├── endpoint.tf
│       ├── internet-gateway.tf
│       ├── nacl.tf
│       ├── nat-gateway.tf
│       ├── outputs.tf
│       ├── route-tables.tf
│       ├── subnet.tf
│       ├── variables.tf
│       └── vpc.tf
└── vars
    └── dev
        └── vpc.tfvars

vars folder contains the variables file named vpc.tfvars . It is the only file that needs modification

The modules/vpc folder contains the following VPC related resources. All the resource provisioning logic is part of these resources.

  1. endpoint
  2. internet-gateway
  3. nacl
  4. nat-gateway
  5. route-tables
  6. subnet
  7. vpc

The infra/vpc/main.tf file calls all the vpc module with all the VPC resources using the variables we pass using the vpc.tfvars file

Create VPC Using Terraform

Note: The VPC and subnets for this demo is created based on the VPC design document.

We will be creating the VPC with the following

  1. CIDR Block: 10.0.0.0/16
  2. Region: us-west-2
  3. Availability Zones: us-west-2a, us-west-2b, us-west-2c
  4. Subnets: 15 Subnets (One per availability Zone)
    • Public Sunets (3)
    • App Subets (3)
    • DB Subnets (3)
    • Management Subnet (3)
    • Platform Subnet (3)
  5. NAT Gateway for Private subnets
  6. Internet Gateway for public subnets.
  7. Enabled Endpoints: s3, Cloudwatch & Secrets Manager
  8. Dedicated NACLs for 4 set of subnets.

Follow the steps give below to create VPC using Terraform code.

Step 1: CD in the Cloned Repository

If you haven’t already cloned the repo, clone it using the following command.

git clone https://github.com/techiescamp/terraform-aws.git

Then cd in to the terraform-aws folder

cd terraform-aws

Step 2: Modify the vpc.tfvars

Note: Open the repository folder in your favorite IDE, as it makes editing and reviewing the code easier.

Modify the vars/dev/vpc.tfvars file as per your requirements. I have highlighted the key parameters in bold.

If you dont want the NAT gateway, set create_nat_gateway to false.

    #vpc
    region               = "us-west-2"
    vpc_cidr_block       = "10.0.0.0/16"
    instance_tenancy     = "default"
    enable_dns_support   = true
    enable_dns_hostnames = true
    
    #elastic ip
    domain = "vpc"
    
    #nat-gateway
    create_nat_gateway = true
    
    #route-table
    destination_cidr_block = "0.0.0.0/0"
    
    #tags
    owner       = "techiescamp"
    environment = "dev"
    cost_center = "techiescamp-commerce"
    application = "ecommerce"
    
    #subnet
    
    map_public_ip_on_launch       = true
    
    public_subnet_cidr_blocks     = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
    app_subnet_cidr_blocks        = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"]
    db_subnet_cidr_blocks         = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"]
    management_subnet_cidr_blocks = ["10.0.10.0/24", "10.0.11.0/24", "10.0.12.0/24"]
    platform_subnet_cidr_blocks   = ["10.0.13.0/24", "10.0.14.0/24", "10.0.15.0/24"]
    availability_zones            = ["us-west-2a", "us-west-2b", "us-west-2c"]
    
    #public nacl
    
    ingress_public_nacl_rule_no    = [100]
    ingress_public_nacl_action     = ["allow"]
    ingress_public_nacl_from_port  = [0]
    ingress_public_nacl_to_port    = [0]
    ingress_public_nacl_protocol   = ["-1"]
    ingress_public_nacl_cidr_block = ["0.0.0.0/0"]
    
    egress_public_nacl_rule_no    = [200]
    egress_public_nacl_action     = ["allow"]
    egress_public_nacl_from_port  = [0]
    egress_public_nacl_to_port    = [0]
    egress_public_nacl_protocol   = ["-1"]
    egress_public_nacl_cidr_block = ["0.0.0.0/0"]
    
    #app nacl
    
    ingress_app_nacl_rule_no    = [100]
    ingress_app_nacl_action     = ["allow"]
    ingress_app_nacl_from_port  = [0]
    ingress_app_nacl_to_port    = [0]
    ingress_app_nacl_protocol   = ["-1"]
    ingress_app_nacl_cidr_block = ["0.0.0.0/0"]
    
    egress_app_nacl_rule_no    = [200]
    egress_app_nacl_action     = ["allow"]
    egress_app_nacl_from_port  = [0]
    egress_app_nacl_to_port    = [0]
    egress_app_nacl_protocol   = ["-1"]
    egress_app_nacl_cidr_block = ["0.0.0.0/0"]
    
    ##db nacl
    
    ingress_db_nacl_rule_no    = [100]
    ingress_db_nacl_action     = ["allow"]
    ingress_db_nacl_from_port  = [0]
    ingress_db_nacl_to_port    = [0]
    ingress_db_nacl_protocol   = ["-1"]
    ingress_db_nacl_cidr_block = ["0.0.0.0/0"]
    
    egress_db_nacl_rule_no    = [200]
    egress_db_nacl_action     = ["allow"]
    egress_db_nacl_from_port  = [0]
    egress_db_nacl_to_port    = [0]
    egress_db_nacl_protocol   = ["-1"]
    egress_db_nacl_cidr_block = ["0.0.0.0/0"]
    
    ##management nacl
    
    ingress_management_nacl_rule_no    = [100]
    ingress_management_nacl_action     = ["allow"]
    ingress_management_nacl_from_port  = [0]
    ingress_management_nacl_to_port    = [0]
    ingress_management_nacl_protocol   = ["-1"]
    ingress_management_nacl_cidr_block = ["0.0.0.0/0"]
    
    egress_management_nacl_rule_no    = [200]
    egress_management_nacl_action     = ["allow"]
    egress_management_nacl_from_port  = [0]
    egress_management_nacl_to_port    = [0]
    egress_management_nacl_protocol   = ["-1"]
    egress_management_nacl_cidr_block = ["0.0.0.0/0"]
    
    #platform nacl
    
    ingress_platform_nacl_rule_no    = [100]
    ingress_platform_nacl_action     = ["allow"]
    ingress_platform_nacl_from_port  = [0]
    ingress_platform_nacl_to_port    = [0]
    ingress_platform_nacl_protocol   = ["-1"]
    ingress_platform_nacl_cidr_block = ["0.0.0.0/0"]
    
    egress_platform_nacl_rule_no    = [200]
    egress_platform_nacl_action     = ["allow"]
    egress_platform_nacl_from_port  = [0]
    egress_platform_nacl_to_port    = [0]
    egress_platform_nacl_protocol   = ["-1"]
    egress_platform_nacl_cidr_block = ["0.0.0.0/0"]
    
    #endpoint
    
    create_s3_endpoint              = true
    create_secrets_manager_endpoint = true
    create_cloudwatch_logs_endpoint = true

    Step 2: Initialize Terraform and Execute the Plan

    Now cd in to infra/vpc folder and execute the terraform plan to validate the configurations.

    cd infra/vpc

    Initialize Terraform

    terraform init

    Execute the plan

    terraform plan  -var-file=../../vars/dev/vpc.tfvars

    You should see an output with all the resources that will be created by terraform.

    Step 3: Create VPC With Terraform Apply

    Lets create the VPC and related resources using terraform apply.

    terraform apply  -var-file=../../vars/dev/vpc.tfvars

    Step 4: Validate VPC

    Head over to the AWS Console the check the Resource Map of the VPC.

    Click on the created VPC and scroll down to view the Resource Map.

    You should see 15 subnets , 6 route tables, internet gateway and NAT gateway as shown beow.

    Step 5: Cleanup the Resources

    If you have created the VPC for learning purposes and wish to clean up the resources created by Terraform, execute the following command

    terraform destroy  -var-file=../../vars/dev/vpc.tfvars

    Conclusion

    In this guide, we looked at creating aws VPC using terraform.

    When implemented in real projects, you may need to consider more VPC options, like flow logs, peering connections, etc.

    Also, tweak the Terraform code according to your requirements. If you want to gain more knowledge, go through each resource under the VPC module

    If you face any errors or have any queries or suggestions, drop a comment below.

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    You May Also Like