Centralizing Internet Output in Multiple AWS Accounts with the AWS Transit Gateway
Tags: transitgateway, natgateway, aws, network
Published: 2023-02-04 00:08:45

Hello everyone!

The objective of this theme is to share a network architecture tip and how to implement it within the AWS Cloud in order to centralize Internet output instead of having multiple NAT Gateways and Internet Gateways scattered throughout the environment.

The goal is to achieve the following benefits:

- Simplify the network architecture by routing all outgoing traffic through a centralized point, the AWS Transit Gateway.

- Reduce costs by centralizing network management and reducing the number of necessary Internet gateways.

- Improve security by having a single point of control for Internet access, reducing the attack surface and allowing centralized security policies.

Note: In this post, I will not comment on the function of each network resource. If desired, comment here because I can develop another post or share AWS documentation explaining about each resource.

So, let's get started?

# Objectives:

1 - Create the Internet Gateway and attach it;
2 - Create a NAT Gateway for each zone and attach it;
3 - Create the Transit gateway (TGW);
4 - Create the Transit gateway attachments with each VPCs;
5 - Create the Transit gateway route table for each Transit gateway attachment;
6 - Adding the routes on the TGW route tables;
7 - Adding the routes on the VPC route tables of each AWS account;
8 - Testing the connection to the internet.


**Network diagram purpose:**

This project consists of three AWS Accounts. The **Core Network AWS Account** will provide the interface to the internet for the **PROD** and **QA AWS Accounts** that do not have access to the internet through themselves, that is,  they will need to Core Network AWS Account to update them Operation System and access the services outside of the AWS environment.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/46676tt2srrl2jps7a99.png)

I consider that the VPC, subnets (private and public), and route tables have already been deployed so we can focus on the Transit Gateway, NAT Gateway, Internet Gateway, and also update the routes on the route tables.

With based on this diagram, let's deploy this environments step-by-step.

**1 - Create the Internet Gateway and attach it to the vpc-core-network on the <u>Core Network AWS Account</u>.**


On the AWS console, go to the VPC dashboard, click on the Internet gateways, and Create internet gateway botton. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lmic7c9qe78kwtiugdvy.png)

Define the Internet gateway name, and click on the Create internet gateway.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nqbuiqvs1ci6sua6383h.png)

After created Internet gateway, let's attach it to the vpc-core-network VPC

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v06uor3hi64g3fmn03f2.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1u0ta8mg30tpt83nx0l7.png)

Now let's update the public subnets' routing table with a default route (0.0.0.0/0) as the next hop to the internet gateway created in the previous steps. Then, go to the Route Tables, select the route table and edit the routes.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oimmo23c9huhgya1vvq7.png)

Create the default route, and set the Internet gateway as target, after that save the change.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rb423yb19zz5cdo1jvmd.png)



**2 - Create a NAT Gateway for each zone (us-east-1a and us-east-1b), and attach it for its respective public subnets on the <u>Core Network AWS Account</u>.**

- AWS NAT Gateway is a zone resource, which mean that it has high availabilty in the Availability Zone (AZ) where it was deployed, but if there is a issue on the AZ where the NAT Gateway was deployed the resource on that zone will lose the internet access, that's why we are going to create a NAT Gateway in two AZs to ensure higy availability.

So, go to the NAT Gateway dashboard and click on the Create NAT Gateway botton

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7myw3mup9etrsh1780dh.png)

Define a name, select the public subnet that belong to the us-east-1a AZ, allocate a Elastic IP (public ip) and create NAT Gateway.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qpg37y051t7466xfpk31.png)

Now, let's create the NAT Gateway to the subnet that belong to the us-east-1b AZ.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bhm4un6z97chg1ak1w6u.png)

The NAT Gateways created.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ar7rbntolo8wrwzayp2r.png)


**3 - Create the Transit Gateway (TGW) on the <u>Core Network AWS Account</u> and sharing it to the <u>PROD</u> and <u>QA AWS Accounts</u>**

On the AWS console, go to the VPC dashboard, click on the Transit gateways, and Create transit gateway botton. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/py0j0czi5la0qz826lnz.png)


Define the Transit gateway name, uncheck the "Default route table association" and "Default route table propagation" options, check the "Auto accept shared attachments" option, keep the other settings as default and the click on the Create transit gateway.

**Note:** the "Default route table association" and "Default route table propagation" options will associate and propagate the routes, but some case there is a requirement where some environments can't establish a connection. Then, when this options is disable Network team there will have more control between communication of the environments.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gx9dbouvmahrorxrmhov.png)

Transit gateway available.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/99rl08ytkirzrkze2gn2.png)

Now, let's share the Core Network Account's TGW to the PROD and QA AWS Accounts.

Type RAM on the search bar, and choose the "Resource Access Manager".

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2x5lj4eknpagabsrutqg.png)

On the session "Shared by me", click in "Shared resources", and Create resource share botton.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qstyesu7bc31kiblb8n2.png)

On the Step 1, define the a name to the resource that will be share, select "Trasit Gateway" as resource that will share, select it on the Selected resources, and click in Next at the botton of the page.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5iq9eb6riqid70boknh1.png)

On the Step 2, keep these default settings, and click in Next.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7dijn6r121ohplehmnbv.png)

On the Step 3, as my other AWS Account belong of the same Organization, the "Allow sharing only within your organization" option was selected, but you can shared to anothe AWS Account that doesn't part of the owner Organization. Select the AWS Account, type AWS Account IDs, in this case it was added and selected the <u>PROD</u> and <u>QA AWS Accounts</u> as you can see on the diagram. After that, click in Next.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x7cpjtx4zmwi1khay548.png)

On the last Step, make a review, and click on the "Create resource share" at the botton of the page.

The sharing process can take a while, but once it's done, you can see its status on the "Resource shares".

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6aa4i9lusvn8uvdkd5w.png)

**4 - Create the Transit gateway attachments with each VPCs.**

Still in Core Network AWS Account, go back to the VPC dashboard, and in Transit Gateway session select the "Transit gateway attachments" option. Click on the Create transit gateway attachments to assign the TGW to the vpc-core-network VPC.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8en24nop75qttrtz4l1i.png)

On the first part of the settings, define a name for the TGW attachment, select the TGW-01 created on the previeus step, and as the attachment will be with VPC, select the VPC, but there is other options of attachment (feel free to see the other options).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8e74rsi0wbw8vs38fm5.png)

On this last part, select the "vpc-core-network" VPC, the subnets will be load, and select Private subnets related to the each AZ as you on can see on the diagram.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4zyklnival4syfnrxss2.png)

Transit gateway attachment created.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8pu6dyvz326j7vm97zhh.png)


Now, sign into each AWS account (PROD and QA account) and repeat the same Transit gateway attachment procedure for their respective VPC. As this is a simulation/study environment, the PROD and QA accounts only have one subnet (according to the diagram) in the part of selecting the subnets you will see only one subnet to select.

**5 - Create the Transit Gateway route table for each Transit gateway attachment created in the previous step.**

On the Core Network AWS Account, go to VPC dashboard and in the Transit Gateway click on the "Transit gateway route tables" option. Click in "Create transit gateway route table" botton to create a TGW route table for the vpc-core-network VPC.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/36jwf0dl9yj7j8v3q2gz.png)

Define a TGW route table name, select the TGW-01, and click in Create transit gateway route table button.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xvzd7nbrtd0ml3ykdten.png)

After created the TGW route table, let's assign the TGW attachment assigned the vpc-core-network VPC. Click on the Associations tab, and Create association button.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vynbuc6zro7cie058yih.png)

Select the TGW attachment assigned the vpc-core-network VPC, and click on the Create association.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rh1p6kj4enivp5qyeh5.png)

Now, let's create a TGW route table for the PROD and QA accounts. Follw the table with TGW attachment ID respective for PROD and QA VPC.

> **PROD Account**
**Name:** TGW-attachment-vpc-prod-us-east-1
**ID:** tgw-attach-09d24c8d49c4b0a76

> **QA Account**
**Name:** TGW-attachment-vpc-qa-us-east-1
**ID:** tgw-attach-09d24c8d49c4b0a76


**Note:** The TGW route table is created in the TGW's own account, so in this case it's the Core Network AWS Account.

**PROD Account**

Define a TGW route table name, select the TGW-01, and click in Create transit gateway route table button.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mbzhj2gj4b6m24d151jx.png)

Let's associate the created TGW route table with the TGW attachment assigned to VPC vpc-prod-us-east-1.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ugbwln2zxxurda2hbqub.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4f4xrgrw5fs2rg9mjrod.png)

**QA Account**

Define a TGW route table name, select the TGW-01, and click in Create transit gateway route table button.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5twbnha79swgwe1ib2o9.png)

Let's associate the created TGW route table with the TGW attachment assigned to VPC vpc-qa-us-east-1.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9ixngm0mdp497azzmrh.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/919g21yk7mv9rq7fseb2.png)

The three TGW route tables created.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lggahgoy80undbyoxfnz.png)

**6 - Adding the routes on the TGW route tables**

With based on the network diagram, and the resources created let me shared some information that will help to set the routes on the TGW route tables.

> **- Core Network AWS Account**
**VPC Name:** vpc-core-network - **CIDR Block:** 10.100.0.0/16
**TGW Attachment name:** TGW-attachment-vpc-core-network
**TGW Attachment ID:** tgw-attach-0dcf709522c248333

> **- PROD AWS Account**
**VPC Name:** vpc-prod-us-east-1 - **CIDR Block:** 10.10.0.0/16
**TGW Attachment name:** TGW-attachment-vpc-prod-us-east-1
**TGW Attachment ID:** tgw-attach-09d24c8d49c4b0a76

> **- QA AWS Account**
**VPC Name:** vpc-qa-us-east-1 - **CIDR Block:** 10.20.0.0/16
**TGW Attachment name:** TGW-attachment-vpc-qa-us-east-1
**TGW Attachment ID:** tgw-attach-0d3bd1d648be67976

On the **Core Network Account**, let's create two routes to reach the network that belong **PROD AWS Account** and **QA AWS Account**.

Select the "tgw-rtb-vpc-core-network", click on the Routes tab, and then click in Create static route button.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lrtp94wh5adpuvvpjofy.png)

Define the PROD CIDR Block and PROD TGW Attachment ID.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/le3qg90bh5qw6czemtfr.png)

Create a new one rote for QA AWS Account. Define the QA CIDR Block and QA TGW Attachment ID.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/knligj323n85shaewhon.png)

Routes created.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ia36voydrp2hmod8etg.png)

Now, on the "tgw-rtb-vpc-prod-us-east-1" and "tgw-rtb-vpc-qa-us-east-1" TGW route tables, let's create a default route (0.0.0.0/0) and define as target the Core Network AWS Account TGW Attachment Id. As you can see on the next screenshot.

**tgw-rtb-vpc-prod-us-east-1**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/da5snmg6luovi0cflmqb.png)

**tgw-rtb-vpc-qa-us-east-1**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9hcvs95kdveb7n3q2rvf.png)


**7 - Adding the routes on the VPC route tables of each AWS account**

On the **Core Network Account**, let's create the routes on the route table that is attached to the Public subnet and Private subnet.

On the Public Subnet (rtb-vpc-core-network-public-subnets), add these routes as you can see on the table, and screenshot.

**CIDR Block**   |   **Next Hop**
10.100.0.0/16    |   local
10.10.0.0/16     |   TGW-01
10.20.0.0/16     |   TGW-01
0.0.0.0/0        |   IGW

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0nfvnda2qek75unornfj.png)

On the both Private Subnets, add these routes as you can see on the screenshots.

**rtb-vpc-core-network-private-subnets-us-east-1a**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8nl2zkgedgcqaztubzj.png)
As this route table belong to the private subnet of the **eu-east-1a** Zone, It should be used the NAT Gateway deployed on the **eu-east-1a** Zone as target.


**rtb-vpc-core-network-private-subnets-us-east-1b**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rbsnepqz16f6ua8zs8rc.png)
The same thing for the route table that belong to the private subnet of the **eu-east-1b** Zone, It should be used the NAT Gateway deployed on the **eu-east-1b** Zone as target.


Now, let's create a route on the **PROD** and **QA Accounts**.

Create a default route (0.0.0.0/0), and as target set the Transit gateway.

**PROD Account**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1rs9zvw3u4l92l1a3bm7.png)

**QA Account**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kn0i0qauxctvs1m25l6w.png)



**8 - Testing the connection to the internet**

From **QA Account**, it was created a EC2 instance where I ran some commands as you can below on screenshot to show that a EC2 instance assigned to a private subnet can reach the internet throught on **Core Network Account**.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pdqfsbnghg8ogl2a20qb.png)

The "curl ifconfig.me" command come back with public IP address, and if you check the NAT Gateway public IP address will valideted that the public ip address belong to the NAT Gateway of the **Core Network Account** as you can see on the screenshot below.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/etd9q270lsb7i480priy.png)

## Conclusion

NAT Gateway is a network resource that, when there is a lot of it, can bring high costs and your bill at the end of the month will get more expensive, in addition to leaving the Internet output from several places decentralized and also more complex to manage. Then, this proposed architecture comes to demonstrate a solution with high availability, low management complexity, having a single exit point and reducing the cost of the AWS account bill.

Well, I hope you enjoyed it!