AWS Networking with Terraform: VPC Transit Gateway between VPCs
Tags: aws, terraform, upskilling, awscommunitybuilder
Published: 2024-02-14 16:50:41

In our previous post, we implemented an AWS networking concept, establishing a peering connection between two Virtual Private Clouds (VPCs). 

Now, we're stepping up our game by exploring how to connect multiple VPCs using the powerful AWS Transit Gateway. We'll walk through the process using Terraform modules to create distinct components seamlessly.

A transit gateway is a network transit hub that you can use to interconnect your virtual private clouds (VPCs) and on-premises networks. As your cloud infrastructure expands globally, inter-Region peering connects transit gateways together using the AWS Global Infrastructure. All network traffic between AWS data centers is automatically encrypted at the physical layer.

## Architecture Overview:
Before diving into implementation, let's outline the architecture we'll be working with:

![Transit Gateway Diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oeih0s4dh1o3mmi4ziyy.png)

## Step 1: Creating 3 VPCs with Non-overlapping CIDRs
Create vpc_a, vpc_b and vpc_c with non-overlapping cidrs. Please refer to my github repo in resources section below.

```terraform
####################################################
# Create VPCs and components
####################################################

module "vpc_a" {
  source               = "./modules/vpc"
  name                 = "VPC-A"
  aws_region           = var.aws_region
  vpc_cidr_block       = var.vpc_cidr_block_a #"10.1.0.0/16"
  public_subnets_cidrs = [cidrsubnet(var.vpc_cidr_block_a, 8, 1)]
  enable_dns_hostnames = var.enable_dns_hostnames
  aws_azs              = var.aws_azs
  common_tags          = local.common_tags
  naming_prefix        = local.naming_prefix
}


module "vpc_b" {
  source               = "./modules/vpc"
  name                 = "VPC-B"
  aws_region           = var.aws_region
  vpc_cidr_block       = var.vpc_cidr_block_b #"10.2.0.0/16"
  public_subnets_cidrs = [cidrsubnet(var.vpc_cidr_block_b, 8, 1)]
  enable_dns_hostnames = var.enable_dns_hostnames
  aws_azs              = var.aws_azs
  common_tags          = local.common_tags
  naming_prefix        = local.naming_prefix
}

module "vpc_c" {
  source               = "./modules/vpc"
  name                 = "VPC-C"
  aws_region           = var.aws_region
  vpc_cidr_block       = var.vpc_cidr_block_c #"10.3.0.0/16"
  public_subnets_cidrs = [cidrsubnet(var.vpc_cidr_block_c, 8, 1)]
  enable_dns_hostnames = var.enable_dns_hostnames
  aws_azs              = var.aws_azs
  common_tags          = local.common_tags
  naming_prefix        = local.naming_prefix
}
```

## Step 2: Deploying EC2 Instances in Each VPC
Create an EC2 instance in each VPC. Please refer to my github repo in resources section below.

```terraform
####################################################
# Create EC2 Instances
####################################################

module "vpc_a_public_host" {
  source        = "./modules/web"
  instance_type = var.instance_type
  instance_key  = var.instance_key
  subnet_id     = module.vpc_a.public_subnets[0]
  vpc_id        = module.vpc_a.vpc_id
  ec2_name      = "Public Host A"
  common_tags   = local.common_tags
  naming_prefix = local.naming_prefix
}

module "vpc_b_public_host" {
  source        = "./modules/web"
  instance_type = var.instance_type
  instance_key  = var.instance_key
  subnet_id     = module.vpc_b.public_subnets[0]
  vpc_id        = module.vpc_b.vpc_id
  ec2_name      = "Public Host B"
  common_tags   = local.common_tags
  naming_prefix = local.naming_prefix
}


module "vpc_c_public_host" {
  source        = "./modules/web"
  instance_type = var.instance_type
  instance_key  = var.instance_key
  subnet_id     = module.vpc_c.public_subnets[0]
  vpc_id        = module.vpc_c.vpc_id
  ec2_name      = "Public Host C"
  common_tags   = local.common_tags
  naming_prefix = local.naming_prefix
}
```

## Step 3: Configuring a Transit Gateway to Facilitate Inter-VPC Communication
Create Transit Gateway with route table attachments

```terraform
####################################################
# Create Transit Gateway and attachments
####################################################

module "transit_gateway" {
  source                 = "./modules/transit-gw"
  vpc_ids                = [module.vpc_c.vpc_id, module.vpc_b.vpc_id, module.vpc_a.vpc_id]
  subnet_ids             = [module.vpc_c.public_subnets[0], module.vpc_b.public_subnets[0], module.vpc_a.public_subnets[0]]
  common_tags            = local.common_tags
  naming_prefix          = local.naming_prefix
  route_table_ids        = [module.vpc_a.public_route_table_id, module.vpc_b.public_route_table_id, module.vpc_c.public_route_table_id]
  destination_cidr_block = "10.0.0.0/8"
}
```

## Steps to Run Terraform
Follow these steps to execute the Terraform configuration:
```terraform
terraform init
terraform plan 
terraform apply -auto-approve
```
Upon successful completion, Terraform will provide relevant outputs.
```terraform
Apply complete! Resources: 28 added, 0 changed, 0 destroyed.

Outputs:

transit_gateway_id = "tgw-06f795ea438d9e040"
vpc_a_public_host_IP = "3.95.224.131"
vpc_b_public_host_IP = "54.173.114.74"
vpc_c_public_host_IP = "44.203.198.154"
```

## Testing the outcome
VPCs Created with exclusive CIDRs

![VPCs with exclusive CIDRs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b8xzx4g0o1dqfrewqrum.png)

Transit Gateway and attachments

![Transit Gateway](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o0lvsaaweyxo1t0fe797.png)

![Transit Gateway Attachments](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8i221xz5sdf7spoihoul.png)

Transit Gateway Route Table:

![Transit Gateway Route Table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ra7dxxfsir90r3n4uf47.png)

Route Tables with route to transit gateway

![Route Tables](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3e38d4zf41kbqcjf5j5w.png)

Connecting to VPC-B and VPC-C Instance from VPC-A Instance

![VPC_A_to_B_C](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kpb8qdrvfbyqv9xj2zia.png)

Connecting to VPC-C and VPC-A Instance from VPC-B Instance

![VPC_B_to_C_A](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfbyb0t8h5plq6vme2ka.png)

Connecting to VPC-A and VPC-B Instance from VPC-C Instance

![VPC_C_to_A_B](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qu89uqheem633xbepgc8.png)

## Cleanup:
Remember to stop AWS components to avoid large bills.
```terraform
terraform destroy -auto-approve
```

In the upcoming module, we'll delve deeper into AWS networking capabilities by setting up VPC Interface Endpoints. These endpoints enhance security and efficiency by providing private connectivity to supported AWS services, further enriching our network architecture.

## Resources:
Github Link: https://github.com/chinmayto/terraform-aws-networking-vpc-transit-gateway
VPC Transit Gateway: https://docs.aws.amazon.com/vpc/latest/tgw/how-transit-gateways-work.html