Setting Up VPC Peering in AWS using Terraform: A Step-by-Step Guide
AWS VPC Peering allows you to connect two VPCs, enabling them to communicate with each other using private IP addresses. In this blog, we will walk through the process of creating a VPC peering connection between two VPCs in AWS using Terraform. Along the way, we will also highlight the common errors we encountered and how to resolve them.
1. Prerequisites
Before we dive into Terraform, let’s make sure you have the following prerequisites:
- An AWS account with appropriate permissions.
- Terraform installed and configured with AWS credentials.
- Two VPCs in different regions or the same region that we will use for this setup.
- Route tables for both VPCs to route traffic via the peering connection.
We’ll create the following resources in this guide:
- VPC Peering Connection.
- Routes in both requester and accepter VPCs.
2. Terraform Setup
We will use a modular approach to manage our infrastructure. The module will handle the creation of the VPC peering connection, along with the associated route updates for both VPCs.
Terraform Configuration (Main File)
module "vpc_peering" {
source = "../../modules/vpc_peering"
requester_vpc_id = var.requester_vpc_id
accepter_vpc_id = var.accepter_vpc_id
peer_region = var.peer_region
auto_accept = false
requester_route_table_id = var.requester_route_table_id
accepter_route_table_id = var.accepter_route_table_id
requester_cidr_block = var.requester_cidr_block
accepter_cidr_block = var.accepter_cidr_block
manage_routes = var.manage_routes
tags = var.tags
}
3. Create the VPC Peering Module
The module is responsible for creating the VPC peering connection and the routes between the two VPCs.
Module Definition (modules/vpc_peering/main.tf
)
resource "aws_vpc_peering_connection" "this" {
vpc_id = var.requester_vpc_id
peer_vpc_id = var.accepter_vpc_id
peer_region = var.peer_region
auto_accept = var.auto_accept
tags = var.tags
}resource "aws_route" "requester" {
count = var.manage_routes ? 1 : 0
route_table_id = var.requester_route_table_id
destination_cidr_block = var.accepter_cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
}resource "aws_route" "accepter" {
count = var.manage_routes ? 1 : 0
route_table_id = var.accepter_route_table_id
destination_cidr_block = var.requester_cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
}
4. Define Variables
Ensure you have the necessary variables defined to pass into the module.
Variable Definitions (modules/vpc_peering/variables.tf
)
variable "requester_vpc_id" {
type = string
description = "The ID of the requester VPC"
}
variable "accepter_vpc_id" {
type = string
description = "The ID of the accepter VPC"
}variable "peer_region" {
type = string
description = "The region of the accepter VPC"
}variable "auto_accept" {
type = bool
description = "Whether to automatically accept the peering connection"
default = false
}variable "requester_route_table_id" {
type = string
description = "The ID of the route table in the requester VPC"
}variable "accepter_route_table_id" {
type = string
description = "The ID of the route table in the accepter VPC"
}variable "requester_cidr_block" {
type = string
description = "The CIDR block for the requester VPC"
}variable "accepter_cidr_block" {
type = string
description = "The CIDR block for the accepter VPC"
}variable "manage_routes" {
type = bool
description = "Whether to manage the routes for VPC peering"
default = true
}variable "tags" {
type = map(string)
description = "Tags for the VPC peering connection"
default = {}
}
5. Error Encountered: Insufficient IAM Permissions
Issue:
When attempting to create the VPC peering connection using AWS CLI or Terraform, we encountered the following error:An error occurred (UnauthorizedOperation) when calling the CreateVpcPeeringConnection operation: You are not authorized to perform this operation.
Resolution:
This error occurs because the IAM role or user we are using does not have sufficient permissions. To resolve this, we need to ensure that the IAM user/role has the ec2:CreateVpcPeeringConnection
permission for both VPCs.
You can attach a policy that includes the required permissions, such as:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:CreateVpcPeeringConnection",
"ec2:AcceptVpcPeeringConnection",
"ec2:DescribeVpcPeeringConnections",
"ec2:CreateRoute",
"ec2:ModifyVpcPeeringConnectionOptions"
],
"Resource": "*"
}
]
}
6. Error Encountered: Terraform Not Resolving
Issue:
Despite the correct configuration, Terraform still wasn’t able to resolve the VPC peering connection. This issue was due to missing route updates after the VPC peering connection was created.
Resolution:
Once the VPC peering connection is established, you need to add routes in both VPCs to ensure traffic can flow between them. This was achieved by manually creating routes via AWS CLI, but ideally, Terraform should handle it through the aws_route
resource in the module.
To automate route creation in Terraform, ensure that the manage_routes
variable is set to true
and the appropriate route tables are configured.
Editresource "aws_route" "requester" {
count = var.manage_routes ? 1 : 0
route_table_id = var.requester_route_table_id
destination_cidr_block = var.accepter_cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
}
resource "aws_route" "accepter" {
count = var.manage_routes ? 1 : 0
route_table_id = var.accepter_route_table_id
destination_cidr_block = var.requester_cidr_block
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
}
7. Final Steps
Once the Terraform configurations are in place, run the following commands to apply your changes:
terraform init
terraform plan
terraform apply
Check the terraform plan
output to ensure that it will create the VPC peering connection and routes as expected. If the plan looks good, proceed with applying the changes.
Conclusion
By following these steps, we were able to successfully create a VPC peering connection between two VPCs in AWS using Terraform. We encountered a few common issues, such as insufficient IAM permissions and missing route configurations, but these were resolved with proper IAM policies and Terraform route management.
With this setup, both VPCs can now communicate with each other securely via private IP addresses. This is an essential step for many cloud architectures, especially when you need to connect multiple VPCs within a single AWS environment.