AWS VPC Peering Connection using terraform.

Abstract: In this blog post, we explore the process of launching an Amazon Web Services (AWS) Virtual Private Cloud (VPC) along with its associated components such as subnets, Internet Gateways (IGWs), and Route Tables (RTs) using Terraform. Additionally, we delve into the concept of establishing a peering connection between two VPCs, enabling secure communication between them. Furthermore, we discuss the approach of connecting EC2 instances located in different AWS regions, demonstrating the flexibility and scalability offered by Terraform in managing multi-region infrastructure deployments. This comprehensive guide provides a step-by-step walkthrough, offering insights and best practices for achieving efficient and reliable networking configurations within the AWS environment.

Steps to Create VPC peering manually in AWS are shown below in the diagram

  1. Sign in to the AWS Management Console: Log in to your AWS account using the AWS Management Console.

  2. Open the VPC Dashboard: Access the VPC Dashboard to manage your VPCs and related resources.

  3. Create or select VPCs: Create new VPCs or choose existing ones that you want to connect.

  4. Create Subnets: Define subnets within the VPCs to organize your resources.

  5. Create Internet Gateway (IGW): Establish an Internet Gateway to enable internet connectivity for your VPC.

  6. Create Route Tables (RT): Set up route tables to control the traffic flow within your VPC.

  7. Navigate to "Peering Connections": Go to the "Peering Connections" section in the VPC Dashboard.

  8. Create Peering Connection: Initiate the creation of a peering connection between your VPC and the desired peer VPC.

  9. Accept the peering connection: If you own the peer VPC, accept the peering connection request from your AWS account.

  10. Configure Route Tables: Update the route tables of both VPCs to allow traffic between them by adding appropriate routes.

  11. Verify connectivity: Test the connectivity between the peered VPCs by accessing resources or pinging IP addresses.

We can perform the same task using Terraform a infrastructure-as-code tool that simplifies the process of managing infrastructure in AWS and other cloud providers. By defining your infrastructure as code, we can automate the provisioning and management of resources, ensuring consistency and reproducibility.

Detail explanation of terraform code:

  1. The Terraform code starts by declaring the required AWS provider and specifying the version.

  2. The first VPC is created in the "us-east-1" (N. Virginia) region using the aws_vpc resource. The VPC is assigned a CIDR block, instance tenancy, and tags.

  3. Within the first VPC, a public subnet is created using the aws_subnet resource. The subnet is associated with the VPC using its ID, and it is assigned a CIDR block, availability zone, tags, and the option to auto-assign public IPv4 addresses.

  4. An internet gateway is created using the aws_internet_gateway resource. It is associated with the first VPC using its ID and given a name tag.

  5. A route table is created within the first VPC using the aws_route_table resource. The route table is associated with the VPC using its ID and given a name tag. Additionally, a route is added to the route table using the route block. This route directs all traffic with a destination CIDR block of "0.0.0.0/0" to the internet gateway.

  6. The subnet is associated with the route table using the aws_route_table_association resource. The association is established by specifying the IDs of the subnet and the route table.

  7. Next, a separate AWS provider configuration is introduced with the alias "mumbairegion" to target the "ap-south-1" (Mumbai) region.

  8. Similar to the first VPC, the second VPC is created in the Mumbai region using the aws_vpc resource. The VPC is assigned a CIDR block, instance tenancy, and tags. The provider configuration is set to the "mumbairegion" alias to ensure it operates in the correct region.

  9. Within the second VPC, a public subnet is created using the aws_subnet resource. The subnet is associated with the second VPC using its ID, and it is assigned a CIDR block, availability zone, tags, and the option to auto-assign public IPv4 addresses. Again, the provider configuration is set to "mumbairegion" for the Mumbai region.

  10. An internet gateway is created using the aws_internet_gateway resource. It is associated with the second VPC using its ID, and a name tag is assigned. The provider configuration is set to "mumbairegion" to target the Mumbai region.

  11. A route table is created within the second VPC using the aws_route_table resource. The route table is associated with the VPC using its ID, and a name tag is assigned. Similar to the first VPC, a route is added to the route table that directs traffic with a destination CIDR block of "0.0.0.0/0" to the internet gateway. The provider configuration is set to "mumbairegion" for the Mumbai region.

  12. The subnet within the second VPC is associated with the route table using the aws_route_table_association resource. The association is established by specifying the IDs of the subnet and the route table. The provider configuration is set to "mumbairegion" to target the Mumbai region.

  13. A VPC peering connection is created using the aws_vpc_peering_connection resource. The peering connection is given a name tag and is configured to connect the first VPC (requester) with the second VPC (accepter) using their respective VPC

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

# 1st VPC in N. Virginia
provider "aws" {
    region = "us-east-1"
}

# Create VPC
resource "aws_vpc" "myvpc1" {
    cidr_block = "10.0.0.0/16"
    instance_tenancy = "default"
    tags = {
        Name = "MYVPC1"
    }
}

#Create Subnet public
resource "aws_subnet" "subnet1" {
    vpc_id = aws_vpc.myvpc1.id
    cidr_block = "10.0.0.0/24"
    availability_zone = "us-east-1a"
    tags = {
      Name = "SUBNET1"
    }
    map_public_ip_on_launch = true  # Actions : Auto-assign public IPV4 
    # any instances launched within this subnet will be automatically assigned a public IP address
}

# Create Internet Gateway
resource "aws_internet_gateway" "igw1" {
    tags = {
      Name = "IGW1"
    }
    vpc_id = aws_vpc.myvpc1.id  # attach IGW to VPC
}

# Create Route Table 
resource "aws_route_table" "rt1" {
    tags = {
      Name = "RT1"
    }
    vpc_id = aws_vpc.myvpc1.id
     route {
        cidr_block = "0.0.0.0/0"
        gateway_id = aws_internet_gateway.igw1.id
    }
}

# Subnet associates in Route Table
resource "aws_route_table_association" "rt1asso" {
    subnet_id = aws_subnet.subnet1.id
    route_table_id = aws_route_table.rt1.id
}


# 2nd VPC in Mumbai
provider "aws" {
    region = "ap-south-1"
    alias = "mumbairegion"
}

# Create VPC
resource "aws_vpc" "myvpc2" {
    provider = aws.mumbairegion
    cidr_block = "11.1.0.0/16"
    instance_tenancy = "default"
    tags = {
        Name = "MYVPC2"
    }
}

#Create Subnet public
resource "aws_subnet" "subnet2" {
    provider = aws.mumbairegion
    vpc_id = aws_vpc.myvpc2.id
    cidr_block = "11.1.0.0/24"
    availability_zone = "ap-south-1a"
    tags = {
      Name = "SUBNET2"
    }
    map_public_ip_on_launch = true  # Actions : Auto-assign public IPV4 
    # any instances launched within this subnet will be automatically assigned a public IP address
}

# Create Internet Gateway
resource "aws_internet_gateway" "igw2" {
    provider = aws.mumbairegion
    tags = {
      Name = "IGW2"
    }
    vpc_id = aws_vpc.myvpc2.id  # attach IGW to VPC
}

# Create Route Table 
resource "aws_route_table" "rt2" {
    provider = aws.mumbairegion
    tags = {
      Name = "RT2"
    }
    vpc_id = aws_vpc.myvpc2.id
     route {
        cidr_block = "0.0.0.0/0"
        gateway_id = aws_internet_gateway.igw2.id
    }
}

# Subnet associates in Route Table
resource "aws_route_table_association" "rt2asso" {
    provider = aws.mumbairegion
    subnet_id = aws_subnet.subnet2.id
    route_table_id = aws_route_table.rt2.id
}

# Create VPC Peering
resource "aws_vpc_peering_connection" "vpcpeering" {
  tags = {
    Name = "VPCPEERING"
  }
  vpc_id = aws_vpc.myvpc1.id # VPC requester
  peer_region = "ap-south-1"  # Accepter region
  peer_vpc_id = aws_vpc.myvpc2.id  # VPC accepter
}

# # Accept request VPC peering from requester 
resource "aws_vpc_peering_connection_accepter" "vpcpeeringaccepter" {
  provider = aws.mumbairegion
  vpc_peering_connection_id = aws_vpc_peering_connection.vpcpeering.id
  auto_accept = true
}

# Route Peering connection Traffic in us-east-region
resource "aws_route" "routepeer1" {
  route_table_id            = aws_route_table.rt1.id
  destination_cidr_block    = aws_vpc.myvpc2.cidr_block
  vpc_peering_connection_id = aws_vpc_peering_connection.vpcpeering.id
}

# Route Peering Connection Traffic in ap-south-region
resource "aws_route" "routepeer2" {
  provider                  = aws.mumbairegion
  route_table_id            = aws_route_table.rt2.id
  destination_cidr_block    = aws_vpc.myvpc1.cidr_block
  vpc_peering_connection_id = aws_vpc_peering_connection.vpcpeering.id
}

Let's go through the commands terraform init, terraform plan, and terraform apply.

  1. Terraform Init: The terraform init command initializes a Terraform working directory. It downloads the necessary provider plugins and sets up the backend configuration based on the information provided in your Terraform code. It is typically the first command you run when starting a new Terraform project or when working with a new configuration.

  2. Terraform Plan: The terraform plan command generates an execution plan based on your Terraform configuration. It compares the desired state defined in your code with the current state stored in the Terraform state file. It shows you what actions Terraform will take to achieve the desired state, such as creating, modifying, or destroying resources. It helps you understand the changes that will be made before applying them.

  3. Terraform Apply: The terraform apply command applies the changes defined in your Terraform configuration to your infrastructure. It prompts for confirmation before making any modifications. Once confirmed, Terraform provisions or modifies the necessary resources according to the execution plan generated by the terraform plan command.

By running these commands in sequence (terraform init, terraform plan, and terraform apply), we can initialize the Terraform project, preview the changes to be made, and apply those changes to provision or modify your infrastructure resources in AWS or any other cloud provider.

Based on the provided Terraform code, the following AWS resources will be created:

  1. VPC: A VPC (Virtual Private Cloud) resource named "MYVPC1" will be created in the "us-east-1" (N. Virginia) region with the CIDR block "10.0.0.0/16".

  2. Subnet: A public subnet named "SUBNET1" will be created within the VPC "MYVPC1" with the CIDR block "10.0.0.0/24" in the availability zone "us-east-1a". This subnet will have auto-assign public IP enabled.

  3. Internet Gateway: An internet gateway named "IGW1" will be created and attached to the VPC "MYVPC1".

  4. Route Table: A route table named "RT1" will be created and associated with the VPC "MYVPC1". It will have a default route directing traffic to the internet gateway "IGW1".

  5. VPC Peering Connection: A VPC peering connection named "VPCPEERING" will be created between "MYVPC1" in the "us-east-1" region and "MYVPC2" in the "ap-south-1" (Mumbai) region.

  6. VPC Peering Connection Accepter: An accepter for the VPC peering connection will be created in the "ap-south-1" region, automatically accepting the peering request.

  7. Route: Two routes will be created - one in the route table of "MYVPC1" directing traffic destined for the CIDR block of "MYVPC2" through the VPC peering connection, and another in the route table of "MYVPC2" directing traffic destined for the CIDR block of "MYVPC1" through the VPC peering connection.

Create two EC2 instances on particular VPC, Subnet and check connection through ping command.

0
Subscribe to my newsletter

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

Written by

Suresh Chaudhary
Suresh Chaudhary

Highly skilled software engineer with expertise in Cloud Computing and DevOps. Experienced in developing scalable software solutions and deploying applications on Cloud platforms and Committed to optimizing the software development lifecycle (SDLC) through effective imple- mentation of DevOps principles.