DEV Community

Cover image for ๐Ÿš€ Seamless Network Connectivity - AWS VPC Peering Deployment
Praful Patel
Praful Patel

Posted on

๐Ÿš€ Seamless Network Connectivity - AWS VPC Peering Deployment

๐ŸŒ Introduction:
In the ever-expanding landscape of cloud computing, Virtual Private Cloud (VPC) Peering stands as a key architectural element, facilitating secure communication between distinct VPCs. This blog delves into the nuances of VPC Peering, shedding light on its significance and practical applications.
A virtual private cloud (VPC) is a virtual network dedicated to your AWS account. It is logically isolated from other virtual networks in the AWS Cloud. You can launch AWS resources, such as Amazon EC2 instances, into your VPC.

A VPC peering connection is a networking connection between two VPCs that enables you to route traffic between them using private IPv4 addresses or IPv6 addresses. Instances in either VPC can communicate with each other as if they are within the same network. You can create a VPC peering connection between your own VPCs, or with a VPC in another AWS account. The VPCs can be in different Regions (also known as an inter-Region VPC peering connection).

VPC Peering Lifecycle
A VPC peering connection goes through various stages starting from when the request is initiated. At each stage, there may be actions that you can take, and at the end of its lifecycle, the VPC peering connection remains visible in the Amazon VPC console and API or command line output for a period of time.

Image description

VPC Peering Connection Lifecycle:

Initiating-request:
A request for a VPC peering connection is initiated, moving to either pending-acceptance or failed state.

Failed:
The VPC peering connection request has failed. It remains visible for 2 hours and cannot be accepted, rejected, or deleted during this period.

Pending-acceptance:
The request awaits acceptance from the accepter VPC owner. It can be accepted, rejected, or deleted within 7 days. If no action is taken, it expires after 7 days.

Expired:
The VPC peering connection request has expired. No action can be taken, and it remains visible for 2 days to both VPC owners.

Rejected:
The accepter VPC owner rejects a pending-acceptance request. It remains visible to the requester for 2 days and to the accepter for 2 hours.

Provisioning:
The request has been accepted and is in the process of becoming active.

Active:
The VPC peering connection is active, allowing traffic flow. It can be deleted by either VPC owner but cannot be rejected.

Deleting:
Applies to an inter-Region VPC peering connection being deleted. A deletion request is submitted, and the connection transitions to deleted.

Deleted:
An active connection is deleted by either owner, or a pending-acceptance request is deleted by the requester. It remains visible for a specified duration to both parties.

๐Ÿš€ Features:

Inter-VPC Connectivity: VPC Peering establishes a connection between VPCs, enabling seamless communication using private IP addresses.
Cross-Account Connectivity: It supports secure connections between VPCs across different AWS accounts, fostering collaboration and resource sharing.
Transitive Peering: VPC Peering can be extended beyond two VPCs, creating a network topology that allows interconnectedness across multiple VPCs.

๐ŸŽฏ Objective:
This blog aims to provide a comprehensive understanding of VPC Peering, unraveling its features and showcasing a real-time use case to highlight its practical utility.

๐Ÿš€ Use Case - Real-time Web and DB VPC in Two Different Regions:
Consider a scenario where a web application hosted in one AWS region necessitates real-time access to a database residing in another region. VPC Peering plays a pivotal role in establishing a secure and efficient connection between the web and database VPCs, facilitating seamless data exchange.

๐Ÿ”— Solution Diagram:
VPC Peering Solution Diagram

Image description

provider "aws" {
  profile = var.profile
  region  = var.region_web
  alias   = "region-web"
}

provider "aws" {
  profile = var.profile
  region  = var.region_db
  alias   = "region-db"
}


#Create VPC in us-east-1
resource "aws_vpc" "vpc_useast" {
  provider             = aws.region-web
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true
  tags = {
    Name = "master-vpc-jenkins"
  }

}

#Create VPC in us-west-2
resource "aws_vpc" "vpc_uswest" {
  provider             = aws.region-db
  cidr_block           = "192.168.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true
  tags = {
    Name = "worker-vpc-jenkins"
  }

}

#Initiate Peering connection request from us-east-1
resource "aws_vpc_peering_connection" "useast1-uswest-2" {
  provider    = aws.region-web
  peer_vpc_id = aws_vpc.vpc_uswest.id
  vpc_id      = aws_vpc.vpc_useast.id
  #auto_accept = true
  peer_region = var.region_db

}

#Create IGW in us-east-1
resource "aws_internet_gateway" "igw" {
  provider = aws.region-web
  vpc_id   = aws_vpc.vpc_useast.id
}

#Create IGW in us-west-2
resource "aws_internet_gateway" "igw-oregon" {
  provider = aws.region-db
  vpc_id   = aws_vpc.vpc_uswest.id
}

#Accept VPC peering request in us-west-2 from us-east-1
resource "aws_vpc_peering_connection_accepter" "accept_peering" {
  provider                  = aws.region-db
  vpc_peering_connection_id = aws_vpc_peering_connection.useast1-uswest-2.id
  auto_accept               = true
}

#Create route table in us-east-1
resource "aws_route_table" "internet_route" {
  provider = aws.region-web
  vpc_id   = aws_vpc.vpc_useast.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }
  route {
    cidr_block                = "192.168.1.0/24"
    vpc_peering_connection_id = aws_vpc_peering_connection.useast1-uswest-2.id
  }
  lifecycle {
    ignore_changes = all
  }
  tags = {
    Name = "Master-Region-RT"
  }
}

#Overwrite default route table of VPC(Master) with our route table entries
resource "aws_main_route_table_association" "set-master-default-rt-assoc" {
  provider       = aws.region-web
  vpc_id         = aws_vpc.vpc_useast.id
  route_table_id = aws_route_table.internet_route.id
}
#Get all available AZ's in VPC for master region
data "aws_availability_zones" "azs" {
  provider = aws.region-web
  state    = "available"
}

#Create subnet # 1 in us-east-1
resource "aws_subnet" "subnet_1" {
  provider          = aws.region-web
  availability_zone = element(data.aws_availability_zones.azs.names, 0)
  vpc_id            = aws_vpc.vpc_useast.id
  cidr_block        = "10.0.1.0/24"
}

#Create subnet #2  in us-east-1
resource "aws_subnet" "subnet_2" {
  provider          = aws.region-web
  vpc_id            = aws_vpc.vpc_useast.id
  availability_zone = element(data.aws_availability_zones.azs.names, 1)
  cidr_block        = "10.0.2.0/24"
}


#Create subnet in us-west-2
resource "aws_subnet" "subnet_1_oregon" {
  provider   = aws.region-db
  vpc_id     = aws_vpc.vpc_uswest.id
  cidr_block = "192.168.1.0/24"
}

#Create route table in us-west-2
resource "aws_route_table" "internet_route_oregon" {
  provider = aws.region-db
  vpc_id   = aws_vpc.vpc_uswest.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw-oregon.id
  }
  route {
    cidr_block                = "10.0.1.0/24"
    vpc_peering_connection_id = aws_vpc_peering_connection.useast1-uswest-2.id
  }
  lifecycle {
    ignore_changes = all
  }
  tags = {
    Name = "Worker-Region-RT"
  }
}

#Overwrite default route table of VPC(Worker) with our route table entries
resource "aws_main_route_table_association" "set-worker-default-rt-assoc" {
  provider       = aws.region-db
  vpc_id         = aws_vpc.vpc_uswest.id
  route_table_id = aws_route_table.internet_route_oregon.id
}


#Create SG for allowing TCP/8080 from * and TCP/22 from your IP in us-east-1
resource "aws_security_group" "jenkins-sg" {
  provider    = aws.region-web
  name        = "jenkins-sg"
  description = "Allow TCP/8080 & TCP/22"
  vpc_id      = aws_vpc.vpc_useast.id
  ingress {
    description = "Allow 22 from our public IP"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [var.external_ip]
  }
  ingress {
    description = "allow anyone on port 8080"
    from_port   = 8080
    to_port     = 8080
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    description = "allow traffic from us-west-2"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["192.168.1.0/24"]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

#Create SG for LB, only TCP/80,TCP/443 and access to jenkins-sg
resource "aws_security_group" "lb-sg" {
  provider    = aws.region-web
  name        = "lb-sg"
  description = "Allow 443 and traffic to Jenkins SG"
  vpc_id      = aws_vpc.vpc_useast.id
  ingress {
    description = "Allow 443 from anywhere"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    description = "Allow 80 from anywhere for redirection"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    description     = "Allow traffic to jenkins-sg"
    from_port       = 0
    to_port         = 0
    protocol        = "tcp"
    security_groups = [aws_security_group.jenkins-sg.id]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

#Create SG for allowing TCP/22 from your IP in us-west-2
resource "aws_security_group" "jenkins-sg-oregon" {
  provider = aws.region-db

  name        = "jenkins-sg-oregon"
  description = "Allow TCP/8080 & TCP/22"
  vpc_id      = aws_vpc.vpc_uswest.id
  ingress {
    description = "Allow 22 from our public IP"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [var.external_ip]
  }
  ingress {
    description = "Allow traffic from us-east-1"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["10.0.1.0/24"]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Enter fullscreen mode Exit fullscreen mode
variable "external_ip" {
  type    = string
  default = "0.0.0.0/0"
}

variable "profile" {
  type    = string
  default = "default"
}

variable "region_web" {
  type    = string
  default = "us-west-1"
}

variable "region_db" {
  type    = string
  default = "ca-central-1"
}

# Variables
variable "ami_web" {
  description = "AMI ID for EC2 instances"
  default = "ami-0cbd40f694b804622"
}

variable "ami_db" {
  description = "AMI ID for EC2 instances"
  default = "ami-06873c81b882339ac"
}

variable "instance_type" {
  description = "EC2 instance type"
  default     = "t2.micro"
}
# AWS EC2 Instance Key Pair
variable "instance_keypair" {
  description = "AWS EC2 Key pair that need to be associated with EC2 Instance"
  type        = string
  default     = "vpc-key.pem"
}
Enter fullscreen mode Exit fullscreen mode
output "VPC-ID-US-EAST-1" {
  value = aws_vpc.vpc_useast.id
}

output "VPC-ID-US-WEST-2" {
  value = aws_vpc.vpc_uswest.id
}

output "PEERING-CONNECTION-ID" {
  value = aws_vpc_peering_connection.useast1-uswest-2.id
}
# Output IPs of Web and DB Instances
output "web_instance_ip" {
  value = aws_instance.web_instance.private_ip
}

output "db_instance_ip" {
  value = aws_instance.db_instance.private_ip
}

Enter fullscreen mode Exit fullscreen mode

VPC Peering in an Action:

terraform init

Image description

terraform plan

Image description

Image description

terraform apply -auto-approve

Image description

Let's verify from the aws console

Us-west-1

web-instance
Image description

ca-central-a
db-instance

Image description

Verify that peering connection is Active in US-west-1

Image description

Image description

Verify vpc peering connectin in ca-central-1

Image description

Image description

Let's verify the connection from web-instance to db-instance on private connection

Image description

db-isntance private ip: 192.168.1.245

ping from web-instance to db instance on private connection is successful

Image description

ping from db-instance to web-instance on private ip 10.0.1.25
Image description

Image description

terraform destroy -auto-approve

Image description

Conclusion:
In conclusion, VPC Peering emerges as a foundational element for crafting intricate and interconnected AWS architectures. Its ability to simplify network communication, support cross-account connectivity, and enable transitive peering positions it as a versatile solution for a myriad of scenarios. As organizations navigate the complexities of modern cloud environments, VPC Peering stands as a reliable ally in building robust and scalable architectures.

Explore the power of VPC Peering to enhance the connectivity and collaboration between your AWS resources, creating a network infrastructure that aligns with the demands of today's dynamic cloud landscape.

AWS #CloudEngineering #CloudComputing #AmazonWebServices #AWSArchitecture #DevOps #CloudSolutions #CloudSecurity #InfrastructureAsCode #AWSCertification #Serverless #AWSCommunity #TechBlogs #CloudExperts #CloudMigration #CloudOps #AWSJobs #TechIndustry #CareerInTech #InnovationInCloud #devops #cloudengineerjobs #devopsjobs #azure #gcp #oci #cloudjobs, #kubernetes

๐˜Š๐˜ฐ๐˜ฏ๐˜ฏ๐˜ฆ๐˜ค๐˜ต ๐˜ธ๐˜ช๐˜ต๐˜ฉ ๐˜ฎ๐˜ฆ ๐˜ฐ๐˜ฏ ๐˜ต๐˜ฉ๐˜ฆ๐˜ด๐˜ฆ ๐˜ฑ๐˜ญ๐˜ข๐˜ต๐˜ง๐˜ฐ๐˜ณ๐˜ฎ๐˜ด ๐˜ข๐˜ฏ๐˜ฅ ๐˜ด๐˜ต๐˜ข๐˜บ ๐˜ถ๐˜ฑ๐˜ฅ๐˜ข๐˜ต๐˜ฆ๐˜ฅ ๐˜ธ๐˜ช๐˜ต๐˜ฉ ๐˜ต๐˜ฉ๐˜ฆ ๐˜ญ๐˜ข๐˜ต๐˜ฆ๐˜ด๐˜ต ๐˜ช๐˜ฏ ๐˜ต๐˜ฆ๐˜ค๐˜ฉ๐˜ฏ๐˜ฐ๐˜ญ๐˜ฐ๐˜จ๐˜บ ๐˜ข๐˜ฏ๐˜ฅ ๐˜ฅ๐˜ฆ๐˜ท๐˜ฆ๐˜ญ๐˜ฐ๐˜ฑ๐˜ฎ๐˜ฆ๐˜ฏ๐˜ต! ๐Ÿ”—

๐ŸŒ Website: praful.cloud
๐Ÿ’ป GitHub: Explore my projects
๐ŸŽฅ YouTube: Watch my tech tutorials
๐Ÿ“ Medium: Read my tech articles
๐Ÿ”— Dev: Follow my cloud/devops-centric content

PRAFUL PATEL

Top comments (0)