A few weeks ago, I created a peering relationship between two VPCs that belonged to separate AWS accounts using Terraform. This note captures my learning from that exercise. But before I do so, let me briefly give an overview of VPC peering and then walk through the process of creating one.
Per AWS, “Amazon Virtual Private Cloud (Amazon VPC) is a service that lets you launch AWS resources in a logically isolated virtual network that you define.” Hence resources created inside a particular VPC cannot communicate with the outside world unless specified. I was working on a use case to create a bridge between two VPCs belonging to separate AWS accounts so that communication could take place. This concept is known as VPC peering. It is a relationship that allows two-way communication between components hosted in separate VPCs. Here is the link to VPC Peering at AWS Docs.
While creating these separate VPCs in these individual AWS accounts, I was aware that I would have to create a peering relationship between the two later down the line. Hence, I allocated separate CIDR blocks to both the VPCs with no overlap. VPC peering would be possible only if the CIDR blocks have no overlap.
Before I go into explaining the code, there are three prerequisites to enable vpc-peering:
(a) both the VPCs exist, (b) do not have a CIDR block overlap, and (c) there is a trust relationship between the user account I am using in the trusted-account and the roles in the trusting-account. This relationship is required since I am using AWS-roles to apply the configuration changes across accounts.
There are three steps to create a peering relationship between two VPCs:
Step 1: Create a VPC peering connection request from the peering owner account.
I started with uniquely identifying which VPCs need to be paired and the route tables to update their CIDR blocks. Then, I used resource
aws_vpc_peering_connection to initiate a peering connection. This information is available at
Step 2: Accept the peering connection request in the accepter account.
I used the resource
aws_vpc_peering_connection_accepter to accept the peering connection. This information is available at
Step 3: Update the route tables in both the VPCs with CIDR blocks for the peering connection from either side.
Finally, I used the
aws_route resource type to update the route tables in the two VPCs. This information is available at
aws_route. If you noticed, all the resources have a
provider block associated. I had to add that since I was using assume-role to provision resources in both the accounts.
To confirm, you can log in to your AWS account (owner or accepter) and access peering connections under VPC to check the status of the peering connection that Terraform created.
Also, the route tables in both VPCs would have an entry of the destination CIDR block. For example, the below image shows a route to the destination CIDR block using the peering connection.
Note: I would suggest checking out a video on how to peer two VPCs in AWS manually. That’ll help you understand the Terraform code when you review that.
Here is the link to my GitHub repository: aws-vpc-peering-using-terraform. Please note the branchname: add-tf-config.
While working on this Terraform project, I came across a few keywords that I believe are necessary to elaborate on. These are below:
(a) data resource type: This is a resource identifier that allows Terraform to uniquely identify resources not managed by itself in the current configuration. Both the VPCs are identified by Terraform using the data
"aws_vpc" "owner" code in the existing configuration. More information at data-sources.
(b) elements and split functions: More information at element() and split(). Using the combination of these two functions, I extracted the account numbers of the VPC owners.
(c) alias keyword: Terraform uses Alias to uniquely identify the Terraform provider, when multiple providers of the same type are being used. In this case, I used two AWS providers, one for the peer owner VPC and the second for the peer accepter VPC. More information on alias is available at alias-multiple-provider-configurations.
(d) assume-role: I haven’t seen a better article than the one below to explain this concept. I would highly recommend going through that to understand how to use AWS assume-role to provision resources in multiple AWS accounts.
In this project, I learned about VPC peering and how to do so using Terraform. Let me know if you find this note helpful.