[AWS] TransitGateway + Terrafrom Project 02
Centralized outbound routing to the internet
Inception
Hello everyone, This article is part of The Terraform + AWS series, the Examples in this series is built in sequence, I use this series to publish out Projects & Knowledge.
Overview
Hello Gurus, ๐จ๐พ๐บ ๐ป๐๐๐๐๐๐๐ฎ๐๐๐๐๐๐ acts as a ๐๐๐๐๐๐๐ ๐ฏ๐๐ for your network connections, ๐บ๐๐๐๐๐๐๐ and ๐๐๐๐๐๐๐ your Network across ๐ฝ๐ท๐ช๐, ๐จ๐พ๐บ ๐จ๐๐๐๐๐๐๐, and ๐ถ๐-๐๐๐๐๐๐๐๐, This connection simplifies your network and puts an ๐๐๐ ๐๐ ๐๐๐๐๐๐๐ ๐๐๐๐๐๐๐ ๐๐๐๐๐๐๐๐๐๐๐๐๐. Transit Gateway acts as a highly scalable cloud routerโeach new connection is made only once.
Today's Article will configure a ๐ป๐๐๐๐๐๐ ๐ฎ๐๐๐๐๐๐ to route outbound internet traffic from a VPC without an internet gateway to a VPC that contains a NAT gateway and an internet gateway, Using ๐ป๐๐๐๐๐๐๐๐.โจ
The Architecture Design will be as the below Diagram
Terraform Resources + Code Steps
Will start out by building the main.tf
file as the following steps
.tf
filesConfigure AWS Provider
Let's start out by set our AWS Provider configurations
# Configure aws provider
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# Configure aws provider
provider "aws" {
region = "us-east-1"
profile = "eraki" # This is a good practice if you have
# multiple aws accounts configured, to ensure you're deploy on this one
}
Setup Variables
variable "dev_vpc1_cidr_block" {}
variable "dev_vpc2_cidr_block" {}
variable "dev_vpc3_cidr_block" {}
variable "dev_subnet1_cidr_block" {}
variable "dev_subnet2_cidr_block" {}
variable "dev_subnet3_cidr_block" {}
variable "dev_subnet4_cidr_block" {}
variable "environment" {}
Set variables values
Let's set the variables values into terraform-dev.tfvars
file
terraform-dev.tfvars
file instead of the default one terraform.tfvars
, This is a good practice if you run the terraform code on multiple stages/zones (e.g. Dev, UAT, and Production zone) and each one contains its stage valuesdev_vpc1_cidr_block = "12.0.0.0/16"
dev_vpc2_cidr_block = "13.0.0.0/16"
dev_vpc3_cidr_block = "14.0.0.0/16"
dev_subnet1_cidr_block = "12.0.1.0/24"
dev_subnet2_cidr_block = "13.0.1.0/24"
dev_subnet3_cidr_block = "14.0.1.0/24"
dev_subnet4_cidr_block = "14.0.2.0/24"
environment = "DEV"
VPC One & VPC One contents
Now, Let's start out creating our first resource in the main.tf
file.
Create a VPC-1 Resource, Private Subnet, Route table that route all traffic to the Transit gateway, And EC2 Instance with Security group that allow 22 port and key pair.
################
# Create VPC-1 #
################
resource "aws_vpc" "vpc-1" {
cidr_block = var.dev_vpc1_cidr_block
tags = {
Name = "${var.environment}-vpc-1"
}
}
# create Subnet-1 for VPC-1
resource "aws_subnet" "subnet-1" {
vpc_id = aws_vpc.vpc-1.id
cidr_block= var.dev_subnet1_cidr_block
tags = {
Name = "${var.environment}-subnet-1"
}
}
# Create a route table to route to transit gateway for VPC-1
resource "aws_route_table" "rt-1" {
vpc_id = aws_vpc.vpc-1.id
route { # Route all traffic through the Transit Gateway
cidr_block = "0.0.0.0/0"
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
}
tags = {
Name = "${var.environment}-rt-1"
}
}
# Create Route table association to Subnet-1 in VPC-1
resource "aws_route_table_association" "rt-ass-1" {
subnet_id = aws_subnet.subnet-1.id
route_table_id = aws_route_table.rt-1.id
}
# Create key pair for SSH access into EC2 instances
resource "aws_key_pair" "kp-1" {
key_name = "server_key"
public_key = file("~/.ssh/id_rsa.pub")
}
# Create Security Group to allow SSH connection to EC2-1
resource "aws_security_group" "secgrp-1" {
name = "secgrp-1"
description = "Allow SSH from anywhere."
vpc_id = aws_vpc.vpc-1.id
}
# Create egress rules for secgrp-1 for VPC-1
resource "aws_vpc_security_group_egress_rule" "outbound-secgrp-1" {
security_group_id = aws_security_group.secgrp-1.id
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = "-1" # equivalent to all ports
}
# Create ingress rules for secgrp-1 for VPC-1
resource "aws_vpc_security_group_ingress_rule" "inbound-secgrp-1" {
security_group_id = aws_security_group.secgrp-1.id
cidr_ipv4 = "0.0.0.0/0" # do Not apply such subnet in production, just for test
ip_protocol = "tcp"
from_port = 22
to_port = 22
}
# Create EC2-1 for VPC-1
resource "aws_instance" "ec2-1" {
ami = "ami-0a3c3a20c09d6f377"
instance_type = "t2.micro"
#associate_public_ip_address = true
subnet_id = aws_subnet.subnet-1.id
vpc_security_group_ids = [aws_security_group.secgrp-1.id]
key_name = aws_key_pair.kp-1.key_name
tags = {
Name = "${var.environment}-EC2-1"
}
}
VPC Two & VPC Two contents
Here will create the same resources as VPC-1.
Will Create a VPC-2 Resource, Private Subnet, Route table that route all traffic to the Transit gateway, And EC2 Instance with Security group that allow 22 port and use the key pair created in VPC-1.
################
# Create VPC-2 #
################
resource "aws_vpc" "vpc-2" {
cidr_block = var.dev_vpc2_cidr_block
tags = {
Name = "${var.environment}-vpc-2"
}
}
# create Subnet-2 for VPC-2
resource "aws_subnet" "subnet-2" {
vpc_id = aws_vpc.vpc-2.id
cidr_block= var.dev_subnet2_cidr_block
tags = {
Name = "${var.environment}-subnet-2"
}
}
# Create a route table to route to transit gateway for VPC-2
resource "aws_route_table" "rt-2" {
vpc_id = aws_vpc.vpc-2.id
route { # Route all traffic through the Transit Gateway
cidr_block = "0.0.0.0/0"
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
}
tags = {
Name = "${var.environment}-rt-2"
}
}
# Create Route table association to Subnet-2 in VPC-2
resource "aws_route_table_association" "rt-ass-2" {
subnet_id = aws_subnet.subnet-2.id
route_table_id = aws_route_table.rt-2.id
}
# Create Security Group to allow SSH connection to EC2-2
resource "aws_security_group" "secgrp-2" {
name = "secgrp-2"
description = "Allow SSH from anywhere."
vpc_id = aws_vpc.vpc-2.id
}
# Create egress rules for secgrp-2 for VPC-2
resource "aws_vpc_security_group_egress_rule" "outbound-secgrp-2" {
security_group_id = aws_security_group.secgrp-2.id
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = "-1" # equivalent to all ports
}
# Create ingress rules for secgrp-2 for VPC-2
resource "aws_vpc_security_group_ingress_rule" "inbound-secgrp-2" {
security_group_id = aws_security_group.secgrp-2.id
cidr_ipv4 = "0.0.0.0/0" # do not apply such subnet in production, just for test
ip_protocol = "tcp"
from_port = 22
to_port = 22
}
# Create EC2-2 for VPC-2
resource "aws_instance" "ec2-2" {
ami = "ami-0a3c3a20c09d6f377"
instance_type = "t2.micro"
#associate_public_ip_address = true
subnet_id = aws_subnet.subnet-2.id
vpc_security_group_ids = [aws_security_group.secgrp-2.id]
key_name = aws_key_pair.kp-1.key_name # use the same key
tags = {
Name = "${var.environment}-EC2-2"
}
}
VPC Three & VPC Three contents
Create a VPC-3 Resource, Public & Private Subnets, Internet gateway IGW, Nat gateway to route the traffic from private subnet to the internet, Route table to Route traffic to the internet and internal to transitgateway attachments.
################
# Create VPC-3 #
################
resource "aws_vpc" "vpc-3" {
cidr_block = var.dev_vpc3_cidr_block
tags = {
Name = "${var.environment}-vpc-3"
}
}
# Create an internet gateway
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc-3.id
tags = {
Name = "${var.environment}-igw"
}
}
# Create subnet-4 for vpc-3 - Public subnet
resource "aws_subnet" "subnet-4" {
vpc_id = aws_vpc.vpc-3.id
cidr_block = var.dev_subnet4_cidr_block
availability_zone = "us-east-1c" # subnet 3 & 4 must be at the same zone
tags = {
Name = "${var.environment}-subnet-4-Pub"
}
}
# Create route for subnet-4 to internet gateway - public subnet
resource "aws_route_table" "rtable-pub" {
vpc_id = aws_vpc.vpc-3.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
route { # route to vpc-1
cidr_block = var.dev_vpc1_cidr_block
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
}
route { # route to vpc-2
cidr_block = var.dev_vpc2_cidr_block
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
}
}
# Associate the route table to public subnet
resource "aws_route_table_association" "rt-ass-Pub" {
subnet_id = aws_subnet.subnet-4.id
route_table_id = aws_route_table.rtable-pub.id
}
# Create an elastic IP for the NAT Gateway
resource "aws_eip" "nat-eip" {
#vpc = true
domain = "vpc"
}
# Create a NAT Gateway in the public subnet for vpc-3
resource "aws_nat_gateway" "nat-gw" {
subnet_id = aws_subnet.subnet-4.id
allocation_id = aws_eip.nat-eip.id
}
# Create subnet-3 for vpc-3
# The private subnet should be in the same Availability Zone as the public subnet
resource "aws_subnet" "subnet-3" {
vpc_id = aws_vpc.vpc-3.id
cidr_block = var.dev_subnet3_cidr_block
availability_zone = "us-east-1c" # subnet 3 & 4 must be at the same zone
tags = {
Name = "${var.environment}-subnet-3-Prv"
}
}
# Create a route table for the private subnet
resource "aws_route_table" "private-rt" {
vpc_id = aws_vpc.vpc-3.id
}
# Add a route to the private route table to direct all traffic to the NAT Gateway
resource "aws_route" "private-route" {
route_table_id = aws_route_table.private-rt.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat-gw.id
}
# Associate the private route table with the private subnet
resource "aws_route_table_association" "private_subnet_association" {
subnet_id = aws_subnet.subnet-3.id
route_table_id = aws_route_table.private-rt.id
}
Transit gateway Resources
At this Step, Will Create a Transit gateway Resource, Attachment for each VPC, and Transit gateway route table.
# Create Transitgateway
resource "aws_ec2_transit_gateway" "tgw" {
description = "Development Main Transitgateway"
default_route_table_association = "disable"
/*default_route_table_propagation = "disable"
dns_support = "enable"
vpn_ecmp_support = "enable"*/
tags = {
Name = "${var.environment}-tgw"
}
}
# Create an attachment to subnet-1
resource "aws_ec2_transit_gateway_vpc_attachment" "tgw-att-1" {
vpc_id = aws_vpc.vpc-1.id
subnet_ids = [aws_subnet.subnet-1.id]
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
#transit_gateway_default_route_table_propagation = true
tags = {
Name = "${var.environment}-tgw-att-1"
}
}
# Associate the route table to attachment
resource "aws_ec2_transit_gateway_route_table_association" "tgw-rt-ass-01" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-1.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
}
# Create an attachment to subnet-2
resource "aws_ec2_transit_gateway_vpc_attachment" "tgw-att-2" {
vpc_id = aws_vpc.vpc-2.id
subnet_ids = [aws_subnet.subnet-2.id]
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
#transit_gateway_default_route_table_propagation = true
tags = {
Name = "${var.environment}-tgw-att-2"
}
}
# Associate the route table to attachment
resource "aws_ec2_transit_gateway_route_table_association" "tgw-rt-ass-02" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-2.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
}
# Create an attachment to subnet-4
resource "aws_ec2_transit_gateway_vpc_attachment" "tgw-att-4" {
vpc_id = aws_vpc.vpc-3.id
#subnet_ids = [aws_subnet.subnet-3.id, aws_subnet.subnet-4.id]
subnet_ids = [aws_subnet.subnet-3.id]
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
##transit_gateway_default_route_table_propagation = true
tags = {
Name = "${var.environment}-tgw-att-4"
}
}
# Associate the route table to attachment
resource "aws_ec2_transit_gateway_route_table_association" "tgw-rt-ass-03" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-4.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
}
# Create a transit gateway route table
resource "aws_ec2_transit_gateway_route_table" "tgw-rtb" {
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
tags = {
Name = "${var.environment}-tgw-rtb"
}
}
# Create transit gateway route rules for subnet 1
resource "aws_ec2_transit_gateway_route" "tgw-route-subnet-1" {
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
destination_cidr_block = var.dev_subnet1_cidr_block # The CIDR block for the development VPC Subnet 1
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-1.id
}
# Create transit gateway route rules for subnet 2
resource "aws_ec2_transit_gateway_route" "tgw-route-subnet-2" {
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
destination_cidr_block = var.dev_subnet2_cidr_block # The CIDR block for the development VPC Subnet 1
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-2.id
}
# Create transit gateway route rules for subnet 4
resource "aws_ec2_transit_gateway_route" "tgw-route-subnet-4" {
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
destination_cidr_block = var.dev_subnet3_cidr_block
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-4.id
}
# Create transit gateway route rules for subnet 4
resource "aws_ec2_transit_gateway_route" "tgw-route-subnet-4-all" {
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
destination_cidr_block = "0.0.0.0/0"
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-4.id
}
Entire Terraform Code
As mentioned above, Down below is my main.tf
file content.
you can skip this section and got to the Apply Terrafrom Code section.
# Configure aws provider
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# Configure aws provider
provider "aws" {
region = "us-east-1"
profile = "eraki"
}
#######################
## Variables Section ##
#######################
variable "dev_vpc1_cidr_block" {}
variable "dev_vpc2_cidr_block" {}
variable "dev_vpc3_cidr_block" {}
variable "dev_subnet1_cidr_block" {}
variable "dev_subnet2_cidr_block" {}
variable "dev_subnet3_cidr_block" {}
variable "dev_subnet4_cidr_block" {}
variable "environment" {}
#######################
## Resources Section ##
#######################
################
# Create VPC-1 #
################
resource "aws_vpc" "vpc-1" {
cidr_block = var.dev_vpc1_cidr_block
tags = {
Name = "${var.environment}-vpc-1"
}
}
# create Subnet-1 for VPC-1
resource "aws_subnet" "subnet-1" {
vpc_id = aws_vpc.vpc-1.id
cidr_block= var.dev_subnet1_cidr_block
tags = {
Name = "${var.environment}-subnet-1"
}
}
# Create a route table to route to transit gateway for VPC-1
resource "aws_route_table" "rt-1" {
vpc_id = aws_vpc.vpc-1.id
route { # Route all traffic through the Transit Gateway
cidr_block = "0.0.0.0/0"
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
}
tags = {
Name = "${var.environment}-rt-1"
}
}
# Create Route table association to Subnet-1 in VPC-1
resource "aws_route_table_association" "rt-ass-1" {
subnet_id = aws_subnet.subnet-1.id
route_table_id = aws_route_table.rt-1.id
}
# Create key pair for SSH access into EC2 instances
resource "aws_key_pair" "kp-1" {
key_name = "server_key"
public_key = file("~/.ssh/id_rsa.pub")
}
# Create Security Group to allow SSH connection to EC2-1
resource "aws_security_group" "secgrp-1" {
name = "secgrp-1"
description = "Allow SSH from anywhere."
vpc_id = aws_vpc.vpc-1.id
}
# Create egress rules for secgrp-1 for VPC-1
resource "aws_vpc_security_group_egress_rule" "outbound-secgrp-1" {
security_group_id = aws_security_group.secgrp-1.id
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = "-1" # equivalent to all ports
}
# Create ingress rules for secgrp-1 for VPC-1
resource "aws_vpc_security_group_ingress_rule" "inbound-secgrp-1" {
security_group_id = aws_security_group.secgrp-1.id
cidr_ipv4 = "0.0.0.0/0" # do Not apply such subnet in production, just for test
ip_protocol = "tcp"
from_port = 22
to_port = 22
}
# Create EC2-1 for VPC-1
resource "aws_instance" "ec2-1" {
ami = "ami-0a3c3a20c09d6f377"
instance_type = "t2.micro"
#associate_public_ip_address = true
subnet_id = aws_subnet.subnet-1.id
vpc_security_group_ids = [aws_security_group.secgrp-1.id]
key_name = aws_key_pair.kp-1.key_name
tags = {
Name = "${var.environment}-EC2-1"
}
}
################
# Create VPC-2 #
################
resource "aws_vpc" "vpc-2" {
cidr_block = var.dev_vpc2_cidr_block
tags = {
Name = "${var.environment}-vpc-2"
}
}
# create Subnet-2 for VPC-2
resource "aws_subnet" "subnet-2" {
vpc_id = aws_vpc.vpc-2.id
cidr_block= var.dev_subnet2_cidr_block
tags = {
Name = "${var.environment}-subnet-2"
}
}
# Create a route table to route to transit gateway for VPC-2
resource "aws_route_table" "rt-2" {
vpc_id = aws_vpc.vpc-2.id
route { # Route all traffic through the Transit Gateway
cidr_block = "0.0.0.0/0"
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
}
tags = {
Name = "${var.environment}-rt-2"
}
}
# Create Route table association to Subnet-2 in VPC-2
resource "aws_route_table_association" "rt-ass-2" {
subnet_id = aws_subnet.subnet-2.id
route_table_id = aws_route_table.rt-2.id
}
# Create Security Group to allow SSH connection to EC2-2
resource "aws_security_group" "secgrp-2" {
name = "secgrp-2"
description = "Allow SSH from anywhere."
vpc_id = aws_vpc.vpc-2.id
}
# Create egress rules for secgrp-2 for VPC-2
resource "aws_vpc_security_group_egress_rule" "outbound-secgrp-2" {
security_group_id = aws_security_group.secgrp-2.id
cidr_ipv4 = "0.0.0.0/0"
ip_protocol = "-1" # equivalent to all ports
}
# Create ingress rules for secgrp-2 for VPC-2
resource "aws_vpc_security_group_ingress_rule" "inbound-secgrp-2" {
security_group_id = aws_security_group.secgrp-2.id
cidr_ipv4 = "0.0.0.0/0" # do not apply such subnet in production, just for test
ip_protocol = "tcp"
from_port = 22
to_port = 22
}
# Create EC2-2 for VPC-2
resource "aws_instance" "ec2-2" {
ami = "ami-0a3c3a20c09d6f377"
instance_type = "t2.micro"
#associate_public_ip_address = true
subnet_id = aws_subnet.subnet-2.id
vpc_security_group_ids = [aws_security_group.secgrp-2.id]
key_name = aws_key_pair.kp-1.key_name # use the same key
tags = {
Name = "${var.environment}-EC2-2"
}
}
################
# Create VPC-3 #
################
resource "aws_vpc" "vpc-3" {
cidr_block = var.dev_vpc3_cidr_block
tags = {
Name = "${var.environment}-vpc-3"
}
}
# Create an internet gateway
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc-3.id
tags = {
Name = "${var.environment}-igw"
}
}
# Create subnet-4 for vpc-3 - Public subnet
resource "aws_subnet" "subnet-4" {
vpc_id = aws_vpc.vpc-3.id
cidr_block = var.dev_subnet4_cidr_block
availability_zone = "us-east-1c" # subnet 3 & 4 must be at the same zone
tags = {
Name = "${var.environment}-subnet-4-Pub"
}
}
# Create route for subnet-4 to internet gateway - public subnet
resource "aws_route_table" "rtable-pub" {
vpc_id = aws_vpc.vpc-3.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
route { # route to vpc-1
cidr_block = var.dev_vpc1_cidr_block
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
}
route { # route to vpc-2
cidr_block = var.dev_vpc2_cidr_block
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
}
}
# Associate the route table to public subnet
resource "aws_route_table_association" "rt-ass-Pub" {
subnet_id = aws_subnet.subnet-4.id
route_table_id = aws_route_table.rtable-pub.id
}
# Create an elastic IP for the NAT Gateway
resource "aws_eip" "nat-eip" {
#vpc = true
domain = "vpc"
}
# Create a NAT Gateway in the public subnet for vpc-3
resource "aws_nat_gateway" "nat-gw" {
subnet_id = aws_subnet.subnet-4.id
allocation_id = aws_eip.nat-eip.id
}
# Create subnet-3 for vpc-3
# The private subnet should be in the same Availability Zone as the public subnet
resource "aws_subnet" "subnet-3" {
vpc_id = aws_vpc.vpc-3.id
cidr_block = var.dev_subnet3_cidr_block
availability_zone = "us-east-1c" # subnet 3 & 4 must be at the same zone
tags = {
Name = "${var.environment}-subnet-3-Prv"
}
}
# Create a route table for the private subnet
resource "aws_route_table" "private-rt" {
vpc_id = aws_vpc.vpc-3.id
}
# Add a route to the private route table to direct all traffic to the NAT Gateway
resource "aws_route" "private-route" {
route_table_id = aws_route_table.private-rt.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat-gw.id
}
# Associate the private route table with the private subnet
resource "aws_route_table_association" "private_subnet_association" {
subnet_id = aws_subnet.subnet-3.id
route_table_id = aws_route_table.private-rt.id
}
# Create Transitgateway
resource "aws_ec2_transit_gateway" "tgw" {
description = "Development Main Transitgateway"
default_route_table_association = "disable"
/*default_route_table_propagation = "disable"
dns_support = "enable"
vpn_ecmp_support = "enable"*/
tags = {
Name = "${var.environment}-tgw"
}
}
# Create an attachment to subnet-1
resource "aws_ec2_transit_gateway_vpc_attachment" "tgw-att-1" {
vpc_id = aws_vpc.vpc-1.id
subnet_ids = [aws_subnet.subnet-1.id]
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
#transit_gateway_default_route_table_propagation = true
tags = {
Name = "${var.environment}-tgw-att-1"
}
}
# Associate the route table to attachment
resource "aws_ec2_transit_gateway_route_table_association" "tgw-rt-ass-01" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-1.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
}
# Create an attachment to subnet-2
resource "aws_ec2_transit_gateway_vpc_attachment" "tgw-att-2" {
vpc_id = aws_vpc.vpc-2.id
subnet_ids = [aws_subnet.subnet-2.id]
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
#transit_gateway_default_route_table_propagation = true
tags = {
Name = "${var.environment}-tgw-att-2"
}
}
# Associate the route table to attachment
resource "aws_ec2_transit_gateway_route_table_association" "tgw-rt-ass-02" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-2.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
}
# Create an attachment to subnet-4
resource "aws_ec2_transit_gateway_vpc_attachment" "tgw-att-4" {
vpc_id = aws_vpc.vpc-3.id
#subnet_ids = [aws_subnet.subnet-3.id, aws_subnet.subnet-4.id]
subnet_ids = [aws_subnet.subnet-3.id]
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
##transit_gateway_default_route_table_propagation = true
tags = {
Name = "${var.environment}-tgw-att-4"
}
}
# Associate the route table to attachment
resource "aws_ec2_transit_gateway_route_table_association" "tgw-rt-ass-03" {
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-4.id
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
}
# Create a transit gateway route table
resource "aws_ec2_transit_gateway_route_table" "tgw-rtb" {
transit_gateway_id = aws_ec2_transit_gateway.tgw.id
tags = {
Name = "${var.environment}-tgw-rtb"
}
}
# Create transit gateway route rules for subnet 1
resource "aws_ec2_transit_gateway_route" "tgw-route-subnet-1" {
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
destination_cidr_block = var.dev_subnet1_cidr_block # The CIDR block for the development VPC Subnet 1
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-1.id
}
# Create transit gateway route rules for subnet 2
resource "aws_ec2_transit_gateway_route" "tgw-route-subnet-2" {
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
destination_cidr_block = var.dev_subnet2_cidr_block # The CIDR block for the development VPC Subnet 1
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-2.id
}
# Create transit gateway route rules for subnet 4
resource "aws_ec2_transit_gateway_route" "tgw-route-subnet-4" {
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
destination_cidr_block = var.dev_subnet3_cidr_block
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-4.id
}
# Create transit gateway route rules for subnet 4
resource "aws_ec2_transit_gateway_route" "tgw-route-subnet-4-all" {
transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.tgw-rtb.id
destination_cidr_block = "0.0.0.0/0"
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.tgw-att-4.id
}
Apply Terraform Code
After configured your Code, Time for The exciting Moment to apply the code and just view it become to Real. ๐
- First the First, Let's make our code cleaner by:
terraform fmt
- Plan is always a good practice (Or even just apply ๐)
terraform plan -var-file="terraform-dev.tfvars"
- Let's apply, If there's No Errors appear and you're agree with the build resources
terraform apply -var-file="terraform-dev.tfvars" -auto-approve
Check Route Connection
After built all resources, we should have the resources as the below diagram
it's time to check the connection between ec2 instances, Follow the steps below
login at the AWS Console > Navigate to EC2 Then Press Connect on any ec2 machine.
On The EC2 instance connect > Select "Connect using EC2 Instance Connect Endpoint"
On Select an endpoint, Press create an endpoint
- Create an endpoint at the vpc-1, and subnet-1 for instance connect as below
- Press Create endpoint, and grab a cup of coffee, This step will take almost 3 minutes till get available status.
Now Login into the ec2 using endpoint.
Test route connection to internet by installing the telnet package.
sudo yum install telnet -y
- Test route connection to the ec2 that live into the vpc-2
telnet <the other ec2 IP> 22 # Test on port 22
Destroy Resources
Manually Delete the created endpoint, and wait until deleted.
use Terrform destroy command to destroy the entire environment.
terraform destroy -var-file="terrafrom-dev.tfvars" -auto-approve
That's it, Very straightforward, very fast๐. Hope this article inspired you and will appreciate your feedback. Thank you.