How to Create AWS VPC Peering in same account/region using Terraform

Amazon VPC peering enables the network connection between the private VPCs to route the traffic from one VPC to another. You can create VPC Peering between your own VPC with the VPC in the same region or a different region or with other VPCs in a different AWS account in a different region.

AWS create peering connection by using the existing infrastructure of the VPC. VPC peering connection is not a form of gateway or VPN connection. It helps to make easy to transfer the data from VPC to VPC.

In this guice, it is assumed that the VPCs that you want to peer have been created. If you need help creating a VPC checkout this guide. We need to create the peering request from the peering owner VPC, accept the peering connection request in the accepter account and update the route tables in both the VPCs with entries for the peering connection from either side.

Related content:

Please ensure that you have the following:

  • Terraform installed locally. I am using terraform version 1.20.0
  • Access Credentials are needed for both AWS accounts
  • There may be multiple route tables in each VPC, and peering connection entries have to be updated in all of them

Let us define some variables that we will use. Save the following under vars.tf.

variable "vpc_name" {
  type = string
  description = "Name of the requester vpc"
}

variable "name" {
  type = string
  description = "Name of the peering connection"
}

variable "accepter_vpc_name" {
  type = string
  description = "Name of the accepter vpc"
}

variable "peer_vpc_id" {
  type        = string
  description = "VPC ID's for Peer Acceptor Accounts"
}

Next, using the given vpc names, let us query our vpcs from the given names:

data "aws_vpc" "peer" {
  filter {
    name   = "tag:Name"
    values = [var.vpc_name]
  }
}

data "aws_vpc" "accepter" {
  filter {
    name   = "tag:Name"
    values = [var.accepter_vpc_name]
  }
}

Next create the vpc peering

resource "aws_vpc_peering_connection" "peer" {
  vpc_id      = data.aws_vpc.peer.id
  peer_vpc_id = var.peer_vpc_id
  auto_accept = true

  tags = {
    Name = var.name
    Side = "Requestor"
  }
}

Now that the peering connection is created, we have to update the route table entries on both sides to send traffic via the peering connection. Given that a single VPC can have multiple route tables, and I wanted the to code to work irrespective of the number of route tables each VPC has. I have created a loop using count to cycle through all the route tables and create the route entry to the other VPC via the peering connection ID. Note that the route tables are being updated with the peered VPC CIDR block. It is also possible to route specific subnets via the peering connection, but I have not done that here.

data "aws_route_tables" "peer" {
  vpc_id = data.aws_vpc.peer.id
}

data "aws_route_tables" "accepter" {
  vpc_id = data.aws_vpc.accepter.id
}

resource "aws_route" "accepter" {
  count                     = length(data.aws_route_tables.peer.ids)
  route_table_id            = data.aws_route_tables.peer.ids[count.index]
  destination_cidr_block    = data.aws_vpc.accepter.cidr_block
  vpc_peering_connection_id = aws_vpc_peering_connection.peer.id
}

resource "aws_route" "peer" {
  count                     = length(data.aws_route_tables.accepter.ids)
  route_table_id            = data.aws_route_tables.accepter.ids[count.index]
  destination_cidr_block    = data.aws_vpc.peer.cidr_block
  vpc_peering_connection_id = aws_vpc_peering_connection.peer.id
}

Here is the final code, save it in main.tf.

data "aws_vpc" "peer" {
  filter {
    name   = "tag:Name"
    values = [var.vpc_name]
  }
}

data "aws_vpc" "accepter" {
  filter {
    name   = "tag:Name"
    values = [var.accepter_vpc_name]
  }
}

data "aws_route_tables" "peer" {
  vpc_id = data.aws_vpc.peer.id
}

data "aws_route_tables" "accepter" {
  vpc_id = data.aws_vpc.accepter.id
}

resource "aws_route" "accepter" {
  count                     = length(data.aws_route_tables.peer.ids)
  route_table_id            = data.aws_route_tables.peer.ids[count.index]
  destination_cidr_block    = data.aws_vpc.accepter.cidr_block
  vpc_peering_connection_id = aws_vpc_peering_connection.peer.id
}

resource "aws_route" "peer" {
  count                     = length(data.aws_route_tables.accepter.ids)
  route_table_id            = data.aws_route_tables.accepter.ids[count.index]
  destination_cidr_block    = data.aws_vpc.peer.cidr_block
  vpc_peering_connection_id = aws_vpc_peering_connection.peer.id
}

resource "aws_vpc_peering_connection" "peer" {
  vpc_id      = data.aws_vpc.peer.id
  peer_vpc_id = var.peer_vpc_id
  auto_accept = true

  tags = {
    Name = var.name
    Side = "Requestor"
  }
}

# Conclusion

In this guide, we learnt how to create a VPC peering between two vpcs in same aws region while also adding routes to the route tables to pass traffic.

comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy