Admin

AWS

AWS Multi-Account VPC Networking with Transit Gateway Setup

Configure AWS VPCs with Transit Gateway for robust multi-account networking. Optimize your cloud architecture for scale & security.

By Sujay SinghPublished: July 17, 20269 min read8 views✓ Fact Checked
AWS Multi-Account VPC Networking with Transit Gateway Setup
AWS Multi-Account VPC Networking with Transit Gateway Setup

Overview: Mastering Multi-Account Networking with AWS Transit Gateway

In the vast landscape of AWS cloud infrastructure, organizations often find themselves managing a growing number of Virtual Private Clouds (VPCs) across multiple AWS accounts. This multi-account strategy, while excellent for isolation, security, and cost management, introduces significant networking complexities. Traditionally, connecting these disparate VPCs involved a mesh of VPC peering connections, which quickly becomes unwieldy and difficult to manage as the number of VPCs scales. The transitive routing limitation of VPC peering, coupled with the management overhead, often leads to a spaghetti-like network architecture that is challenging to secure, troubleshoot, and scale.

Enter AWS Transit Gateway (TGW) – a game-changer for simplifying network topology in complex AWS environments. Transit Gateway acts as a central hub, allowing you to connect thousands of VPCs, AWS accounts, and on-premises networks through a single gateway. This hub-and-spoke model eliminates the need for numerous point-to-point connections, drastically simplifying routing, improving scalability, and reducing operational overhead. It enables centralized network management, allowing for better control over traffic flow, enhanced security posture through centralized inspection, and efficient resource sharing across your organization.

This article will guide you through a detailed, publication-ready setup of AWS VPCs utilizing Transit Gateway for multi-account networking. We will walk through the process of creating VPCs in different accounts, setting up a Transit Gateway in a dedicated network account, sharing it across organizational units using AWS Resource Access Manager (RAM), and configuring the necessary routing to achieve seamless connectivity. By the end of this guide, you will have a robust, scalable, and manageable multi-account network architecture that leverages the full power of AWS Transit Gateway.

Prerequisites

Before we dive into the implementation, ensure you have the following in place:

  • AWS Accounts: Access to at least three AWS accounts. For this guide, we'll designate them as:
    • Network Account: This account will host the Transit Gateway and any centralized networking components (e.g., shared services VPC, firewall VPC). (e.g., AWS Account ID: 123456789012)
    • Production Account: Hosts your production application VPCs. (e.g., AWS Account ID: 234567890123)
    • Development Account: Hosts your development/test application VPCs. (e.g., AWS Account ID: 345678901234)
  • IAM Permissions: Sufficient IAM permissions in all accounts to create and manage VPCs, subnets, route tables, Transit Gateways, and Resource Access Manager shares. Specifically, permissions related to ec2:* and ram:* are crucial.
  • AWS CLI: The AWS Command Line Interface (CLI) configured and authenticated for each of the accounts. Ensure you can switch profiles or configure environment variables to target the correct account for each step.
  • Basic AWS Networking Knowledge: A fundamental understanding of AWS VPCs, subnets, route tables, security groups, and Network ACLs.
  • VPC CIDR Planning: Non-overlapping CIDR blocks for all VPCs involved in the setup. This is critical for preventing IP address conflicts and ensuring correct routing. For our example, we will use:
    • Network VPC: 10.0.0.0/24
    • Production VPC: 10.1.0.0/16
    • Development VPC: 10.2.0.0/16

Step-by-step Implementation

1. Plan Your Network Architecture

A well-defined plan is the cornerstone of any robust network setup. For our scenario, we will implement a hub-and-spoke model where the AWS Transit Gateway acts as the central hub in a dedicated Network Account. The Production and Development VPCs in their respective accounts will be the spokes.

  • Region: us-east-1 (N. Virginia) for all resources. Consistency is key.
  • Account IDs:
    • Network Account: 123456789012
    • Production Account: 234567890123
    • Development Account: 345678901234
  • VPC CIDR Blocks:
    • Network VPC: 10.0.0.0/24
    • Production VPC: 10.1.0.0/16
    • Development VPC: 10.2.0.0/16
  • Subnet CIDR Blocks (examples):
    • Network VPC: 10.0.0.0/26 (subnet-A), 10.0.0.64/26 (subnet-B)
    • Production VPC: 10.1.1.0/24 (subnet-A), 10.1.2.0/24 (subnet-B)
    • Development VPC: 10.2.1.0/24 (subnet-A), 10.2.2.0/24 (subnet-B)

2. Create VPCs in Each Account

First, we'll create the necessary VPCs and their associated subnets in each of our three accounts. Ensure you are authenticated with the correct AWS CLI profile for each account when executing these commands.

Network Account (123456789012)


# Set AWS CLI profile for Network Account
export AWS_PROFILE=network-account

# Create Network VPC
NETWORK_VPC_ID=$(aws ec2 create-vpc --cidr-block 10.0.0.0/24 --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=TechNewsVenture-Network-VPC}]' --query 'Vpc.VpcId' --output text --region us-east-1)
echo "Network VPC ID: $NETWORK_VPC_ID"

# Create Subnets in Network VPC
NETWORK_SUBNET_A_ID=$(aws ec2 create-subnet --vpc-id $NETWORK_VPC_ID --cidr-block 10.0.0.0/26 --availability-zone us-east-1a --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=TechNewsVenture-Network-Subnet-A}]' --query 'Subnet.SubnetId' --output text --region us-east-1)
NETWORK_SUBNET_B_ID=$(aws ec2 create-subnet --vpc-id $NETWORK_VPC_ID --cidr-block 10.0.0.64/26 --availability-zone us-east-1b --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=TechNewsVenture-Network-Subnet-B}]' --query 'Subnet.SubnetId' --output text --region us-east-1)
echo "Network Subnet A ID: $NETWORK_SUBNET_A_ID"
echo "Network Subnet B ID: $NETWORK_SUBNET_B_ID"

Production Account (234567890123)


# Set AWS CLI profile for Production Account
export AWS_PROFILE=prod-account

# Create Production VPC
PROD_VPC_ID=$(aws ec2 create-vpc --cidr-block 10.1.0.0/16 --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=TechNewsVenture-Prod-VPC}]' --query 'Vpc.VpcId' --output text --region us-east-1)
echo "Prod VPC ID: $PROD_VPC_ID"

# Create Subnets in Production VPC
PROD_SUBNET_A_ID=$(aws ec2 create-subnet --vpc-id $PROD_VPC_ID --cidr-block 10.1.1.0/24 --availability-zone us-east-1a --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=TechNewsVenture-Prod-Subnet-A}]' --query 'Subnet.SubnetId' --output text --region us-east-1)
PROD_SUBNET_B_ID=$(aws ec2 create-subnet --vpc-id $PROD_VPC_ID --cidr-block 10.1.2.0/24 --availability-zone us-east-1b --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=TechNewsVenture-Prod-Subnet-B}]' --query 'Subnet.SubnetId' --output text --region us-east-1)
echo "Prod Subnet A ID: $PROD_SUBNET_A_ID"
echo "Prod Subnet B ID: $PROD_SUBNET_B_ID"

Development Account (345678901234)


# Set AWS CLI profile for Development Account
export AWS_PROFILE=dev-account

# Create Development VPC
DEV_VPC_ID=$(aws ec2 create-vpc --cidr-block 10.2.0.0/16 --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=TechNewsVenture-Dev-VPC}]' --query 'Vpc.VpcId' --output text --region us-east-1)
echo "Dev VPC ID: $DEV_VPC_ID"

# Create Subnets in Development VPC
DEV_SUBNET_A_ID=$(aws ec2 create-subnet --vpc-id $DEV_VPC_ID --cidr-block 10.2.1.0/24 --availability-zone us-east-1a --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=TechNewsVenture-Dev-Subnet-A}]' --query 'Subnet.SubnetId' --output text --region us-east-1)
DEV_SUBNET_B_ID=$(aws ec2 create-subnet --vpc-id $DEV_VPC_ID --cidr-block 10.2.2.0/24 --availability-zone us-east-1b --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=TechNewsVenture-Dev-Subnet-B}]' --query 'Subnet.SubnetId' --output text --region us-east-1)
echo "Dev Subnet A ID: $DEV_SUBNET_A_ID"
echo "Dev Subnet B ID: $DEV_SUBNET_B_ID"

Note: For brevity, we are not setting up Internet Gateways or public route tables, as the focus is on internal multi-account connectivity via TGW. You may need these for specific application requirements.

3. Create the Transit Gateway (Network Account)

Now, we'll create the Transit Gateway in our dedicated Network Account.


# Set AWS CLI profile for Network Account
export AWS_PROFILE=network-account

# Create Transit Gateway
TRANSIT_GATEWAY_ID=$(aws ec2 create-transit-gateway \
    --description "TechNewsVenture Multi-Account TGW" \
    --options 'AmazonSideAsn=64512,DnsSupport=enable,AutoAcceptSharedAttachments=disable,DefaultRouteTableAssociation=enable,DefaultRouteTablePropagation=enable' \
    --tag-specifications 'ResourceType=transit-gateway,Tags=[{Key=Name,Value=TechNewsVenture-TGW}]' \
    --query 'TransitGateway.TransitGatewayId' --output text \
    --region us-east-1)
echo "Transit Gateway ID: $TRANSIT_GATEWAY_ID"

# Wait for TGW to be available (optional, but good practice)
aws ec2 describe-transit-gateways --transit-gateway-ids $TRANSIT_GATEWAY_ID --query 'TransitGateways[0].State' --output text --region us-east-1
# Expected output: available

We've set AutoAcceptSharedAttachments=disable for explicit control over attachments, which is a common best practice in production environments. DefaultRouteTableAssociation=enable and DefaultRouteTablePropagation=enable simplify initial setup by using the default TGW route table for all attachments and automatically propagating routes.

4. Share the Transit Gateway (Network Account)

The Transit Gateway needs to be shared with the Production and Development accounts using AWS Resource Access Manager (RAM). This allows those accounts to create attachments to the TGW.


# Set AWS CLI profile for Network Account
export AWS_PROFILE=network-account

# Share Transit Gateway with Prod and Dev accounts
# Replace with actual account IDs for Prod (234567890123) and Dev (345678901234)
RESOURCE_SHARE_ARN=$(aws ram create-resource-share \
    --name "TechNewsVenture-TGW-Share" \
    --resource-arns "arn:aws:ec2:us-east-1:123456789012:transit-gateway/$TRANSIT_GATEWAY_ID" \
    --principals "234567890123" "345678901234" \
    --query 'resourceShare.resourceShareArn' --output text \
    --region us-east-1)
echo "Resource Share ARN: $RESOURCE_SHARE_ARN"

5. Accept the Resource Share (Prod & Dev Accounts)

The Production and Development accounts must accept the RAM share invitation. This step needs to be performed in each of the recipient accounts.

Production Account (234567890123)


# Set AWS CLI profile for Production Account
export AWS_PROFILE=prod-account

# Get pending resource share invitations
INVITATION_ARN=$(aws ram get-resource-share-invitations \
    --query 'resourceShareInvitations[?status==`PENDING` && resourceShare.resourceShareName==`TechNewsVenture-TGW-Share`].resourceShareInvitationArn' \
    --output text --region us-east-1)
echo "Prod Account Invitation ARN: $INVITATION_ARN"

# Accept the invitation
aws ram accept-resource-share-invitation \
    --resource-share-invitation-arn $INVITATION_ARN \
    --region us-east-1
echo "Resource share accepted in Production Account."

Development Account (345678901234)


# Set AWS CLI profile for Development Account
export AWS_PROFILE=dev-account

# Get pending resource share invitations
INVITATION_ARN=$(aws ram get-resource-share-invitations \
    --query 'resourceShareInvitations[?status==`PENDING` && resourceShare.resourceShareName==`TechNewsVenture-TGW-Share`].resourceShareInvitationArn' \
    --output text --region us-east-1)
echo "Dev Account Invitation ARN: $INVITATION_ARN"

# Accept the invitation
aws ram accept-resource-share-invitation \
    --resource-share-invitation-arn $INVITATION_ARN \
    --region us-east-1
echo "Resource share accepted in Development Account."

6. Create Transit Gateway Attachments (All Accounts)

Now that the TGW is shared and accepted, each VPC can be attached to it. Note that the TransitGatewayId will be the same across all accounts as it's a shared resource. You can retrieve it in each account by running aws ec2 describe-transit-gateways --query 'TransitGateways[0].TransitGatewayId' --output text --region us-east-1 after the share is accepted.

Network Account (123456789012)


# Set AWS CLI profile for Network Account
export AWS_PROFILE=network-account

# Retrieve TGW ID (if not already set in this session)
# TRANSIT_GATEWAY_ID=$(aws ec2 describe-transit-gateways --query 'TransitGateways[0].TransitGatewayId' --output text --region us-east-1)

# Retrieve Network VPC ID (if not already set in this session)
# NETWORK_VPC_ID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=TechNewsVenture-Network-VPC" --query 'Vpcs[0].VpcId' --output text --region us-east-1)

# Retrieve Network Subnet IDs (if not already set in this session)
# NETWORK_SUBNET_A_ID=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=TechNewsVenture-Network-Subnet-A" --query 'Subnets[0].SubnetId' --output text --region us-east-1)
# NETWORK_SUBNET_B_ID=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=TechNewsVenture-Network-Subnet-B" --query 'Subnets[0].SubnetId' --output text --region us-east-1)


# Create TGW attachment for Network VPC
NETWORK_ATTACHMENT_ID=$(aws ec2 create-transit-gateway-vpc-attachment \
    --transit-gateway-id $TRANSIT_GATEWAY_ID \
    --vpc-id $NETWORK_VPC_ID \
    --subnet-ids $NETWORK_SUBNET_A_ID $NETWORK_SUBNET_B_ID \
    --tag-specifications 'ResourceType=transit-gateway-attachment,Tags=[{Key=Name,Value=TechNewsVenture-Network-VPC-Attachment}]' \
    --query 'TransitGatewayVpcAttachment.TransitGatewayAttachmentId' --output text \
    --region us-east-1)
echo "Network VPC Attachment ID: $NETWORK_ATTACHMENT_ID"

Production Account (234567890123)


# Set AWS CLI profile for Production Account
export AWS_PROFILE=prod-account

# Retrieve TGW ID (it's shared, so describe it in this account)
TRANSIT_GATEWAY_ID=$(aws ec2 describe-transit-gateways --filters "Name=owner-id,Values=123456789012" --query 'TransitGateways[0].TransitGatewayId' --output text --region us-east-1)
echo "Prod Account - Retrieved TGW ID: $TRANSIT_GATEWAY_ID"

# Retrieve Prod VPC ID (if not already set in this session)
# PROD_VPC_ID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=TechNewsVenture-Prod-VPC" --query 'Vpcs[0].VpcId' --output text --region us-east-1)

# Retrieve Prod Subnet IDs (if not already set in this session)
# PROD_SUBNET_A_ID=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=TechNewsVenture-Prod-Subnet-A" --query 'Subnets[0].SubnetId' --output text --region us-east-1)
# PROD_SUBNET_B_ID=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=TechNewsVenture-Prod-Subnet-B" --query 'Subnets[0].SubnetId' --output text --region us-east-1)

# Create TGW attachment for Production VPC
PROD_ATTACHMENT_ID=$(aws ec2 create-transit-gateway-vpc-attachment \
    --transit-gateway-id $TRANSIT_GATEWAY_ID \
    --vpc-id $PROD_VPC_ID \
    --subnet-ids $PROD_SUBNET_A_ID $PROD_SUBNET_B_ID \
    --tag-specifications 'ResourceType=transit-gateway-attachment,Tags=[{Key=Name,Value=TechNewsVenture-Prod-VPC-Attachment}]' \
    --query 'TransitGatewayVpcAttachment.TransitGatewayAttachmentId' --output text \
    --region us-east-1)
echo "Production VPC Attachment ID: $PROD_ATTACHMENT_ID"

Development Account (345678901234)


# Set AWS CLI profile for Development Account
export AWS_PROFILE=dev-account

# Retrieve TGW ID (it's shared, so describe it in this account)
TRANSIT_GATEWAY_ID=$(aws ec2 describe-transit-gateways --filters "Name=owner-id,Values=123456789012" --query 'TransitGateways[0].TransitGatewayId' --output text --region us-east-1)
echo "Dev Account - Retrieved TGW ID: $TRANSIT_GATEWAY_ID"

# Retrieve Dev VPC ID (if not already set in this session)
# DEV_VPC_ID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=TechNewsVenture-Dev-VPC" --query 'Vpcs[0].VpcId' --output text --region us-east-1)

# Retrieve Dev Subnet IDs (if not already set in this session)
# DEV_SUBNET_A_ID=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=TechNewsVenture-Dev-Subnet-A" --query 'Subnets[0].SubnetId' --output text --region us-east-1)
# DEV_SUBNET_B_ID=$(aws ec2 describe-subnets --filters "Name=tag:Name,Values=TechNewsVenture-Dev-Subnet-B" --query 'Subnets[0].SubnetId' --output text --region us-east-1)

# Create TGW attachment for Development VPC
DEV_ATTACHMENT_ID=$(aws ec2 create-transit-gateway-vpc-attachment \
    --transit-gateway-id $TRANSIT_GATEWAY_ID \
    --vpc-id $DEV_VPC_ID \
    --subnet-ids $DEV_SUBNET_A_ID $DEV_SUBNET_B_ID \
    --tag-specifications 'ResourceType=transit-gateway-attachment,Tags=[{Key=Name,Value=TechNewsVenture-Dev-VPC-Attachment}]' \
    --query 'TransitGatewayVpcAttachment.TransitGatewayAttachmentId' --output text \
    --region us-east-1)
echo "Development VPC Attachment ID: $DEV_ATTACHMENT_ID"

7. Configure Transit Gateway Route Tables

Since we enabled DefaultRouteTableAssociation=enable and DefaultRouteTablePropagation=enable when creating the TGW, attachments are automatically associated with the default TGW route table, and routes for attached VPCs are automatically propagated. This means that the TGW

📧

Enjoyed this article?

Get articles like this delivered to your inbox daily. Join 10,000+ tech professionals.

Written By

Sujay Singh

Technology Expert / Cloud Architect at Virtual Venture covering AI, cloud computing, cybersecurity, and emerging tech trends.

Sources & References

• Official company announcements and press releases

• Industry reports from Gartner, IDC, and Statista

• Peer-reviewed research and technical documentation

• On-record statements from industry experts

Last verified: July 17, 2026

Fact-checked by TechNews Venture editorial team

Leave a Comment

Comments are moderated and will appear after review.