Multi-Account AWS Networking with Transit Gateway

Learn how to automate secure, multi-account networking using AWS Transit Gateway — the backbone of enterprise cloud architectures.

What You’ll Learn

In this hands-on demo, we’ll explore:

  • What AWS Transit Gateway (TGW) is and why it’s better than VPC peering
  • How to design a multi-account, multi-VPC architecture for scale and security
  • How to deploy it all using Terraform and Terragrunt for automation and repeatability

An AWS Transit Gateway (TGW) acts as a central hub to interconnect multiple Virtual Private Clouds (VPCs) and on-premises networks. As cloud environments expand across regions, inter-Region peering enables Transit Gateways to seamlessly connect through the AWS Global Infrastructure, delivering secure and scalable networking.

Introduction: The Networking Challenge at Scale

As organizations scale across AWS, managing connectivity between multiple VPCs and accounts becomes complex:

  • Full-mesh peering quickly becomes unmanageable.
  • Route tables are hard to track and error-prone.
  • Centralized security enforcement is nearly impossible.

This is where AWS Transit Gateway steps in — acting as a centralized routing hub that connects VPCs, enforces consistent security, and enables scalable, multi-account networking.

⚖️ Why Not Just Use VPC Peering?

VPC peering works for small setups, but once multiple accounts and inspection layers come in, it falls short.

FeatureVPC PeeringAWS Transit Gateway
Connection TypePoint-to-PointCentralized Hub
Route ManagementManualCentralized
Cross-AccountComplexNative Support
ScalabilityLimitedEnterprise-Grade
Security ControlDistributedCentralized

👉 Transit Gateway wins for any environment beyond 2-3 VPCs or accounts.

Architecture Overview

Here’s the high-level design we’ll build:

        Internet
             │
            ▼
 ┌── ───┐
  │  DMZ VPC     │  ← ALB + WAF (Ingress)
 └──┬─  ─┘
              │
             ▼
 ┌────────┐
  │  Transit Gateway        │  ← Central Networking Hub
 └─ ─┬────┬─┘
              ▼               ▼
 ┌────┐  ┌──────┐
  │Security     │     │    App VPCs    │
  │  VPCs        │     │   (Dev/Prod)    │
 └────┘  └──────┘

Traffic Flow:

  • Inbound: User → Ingress (ALB + WAF) → TGW → Workload VPC
  • Outbound: Workload → TGW → Egress (Firewall + NAT) → Internet
  • East-West: TGW routes control workload-to-workload communication securely

Core Design Principles

1. Central Networking Account

  • Hosts and manages the Transit Gateway
  • Controls all attachments and propagations
  • Acts as the source of truth for routing

2. Ingress / Egress Inspection

  • Ingress VPC: ALB + WAF + AWS Network Firewall for inbound inspection
  • Egress VPC: NAT Gateways + Firewall for outbound inspection

3. Workload Isolation

  • Separate Dev, Prod, and Shared Services accounts
  • No direct internet access — traffic must pass through inspection VPCs

⚙️ Implementation with Terraform & Terragrunt

Repository Structure

.
├── environments/
 │   ├── common/
 │    │   ├── networking/        # Transit Gateway
 │    │   └── firewall-admin/  # Security VPCs
 │   ├── dev/                          # Dev environments
 │   └──production/            # Prod environments
└─modules/                        # Reusable Terraform modules
    ├── vpc/
    ├── ec2/
    ├── rds/
    ├── alb/
    ├── gwlb/
    ├── network_firewall/
    └── waf/

Terragrunt Keeps It DRY

Example parent configuration (environments/dev/root.hcl):
Example config overview

locals {
  region     = "us-east-2"
  account_id = "390259467000"
}

remote_state {
  backend = "s3"
  config = {
    bucket = "global-infra-state-us-east-2"
    key    = "dev/${path_relative_to_include()}/terraform.tfstate"
  }
}

Each child module simply inherits from this parent, e.g. (vpc/terragrunt.hcl):

include "root" {
  path = find_in_parent_folders("root.hcl")
}

terraform {
  source = "../../../../modules/vpc"
}

inputs = {
  vpc_cidr = "10.10.0.0/16"
  vpc_name = "Mezzo_Dev_VPC"
}

Cross-Account TGW Sharing

Networking Account:

enable_cross_account_sharing = true
shared_account_ids = [
  "337537076***",  # Firewall
  "390259467***",  # Dev
  "327903111***",  # Prod
]

Application Account:

attach_to_tgw      = true
transit_gateway_id = dependency.tgw.outputs.transit_gateway_id

Terragrunt automatically resolves dependencies between modules — no manual waiting.


Security Layers

1. AWS Network Firewall

Example stateless rule:

rule_groups = {
  allow-http = {
    capacity = 100
    type     = "STATELESS"
    priority = 10
    rule_group = {
      rules_source = {
        stateless_rules_and_custom_actions = {
          stateless_rules = [{
            rule_definition = {
              actions = ["aws:pass"]
              match_attributes = {
                protocols         = [6]
                destination_ports = [{ from_port = 80, to_port = 80 }]
              }
            }
            priority = 1
          }]
        }
      }
    }
  }
}

2. AWS WAF

Protects internet-facing ALBs with managed rules and rate limiting.

waf_common_rules = [
  {
    name            = "AWSManagedRulesCommonRuleSet"
    priority        = 1
    vendor_name     = "AWS"
  }
]

Deployment Steps

1️⃣ Deploy Transit Gateway

export AWS_PROFILE=networking_account
cd environments/common/networking/transit-gateway
terragrunt apply

2️⃣ Deploy Security VPCs

export AWS_PROFILE=firewall_account
cd environments/common/firewall-admin
terragrunt run-all apply

3️⃣ Configure TGW Routing

export AWS_PROFILE=networking_account
cd environments/common/networking/transit-gateway-routing
terragrunt apply

4️⃣ Deploy Application Environment

export AWS_PROFILE=dev_account
cd environments/dev/mezzo-dev
terragrunt run-all apply

Best Practices

Networking

  • Host TGW in a dedicated account
  • Use separate route tables for Ingress, Egress, and Workloads
  • Enable Flow Logs and CloudWatch metrics

Security

  • Enforce IMDSv2
  • Inspect both inbound and outbound traffic
  • Integrate GuardDuty, Security Hub, and IAM Access Analyzer

Operations

  • Automate everything via CI/CD pipelines
  • Use Terraform Cloud or remote S3 backends for state
  • Regularly review TGW quotas and costs

📉 Estimated Monthly Costs (us-east-2)

ResourceEstimated Cost
Transit Gateway + Attachments~$360
NAT Gateways (2)~$65
Network Firewall (2 AZs)~$730
EC2 (12 × t2.micro)~$100
ALB~$23
Total≈ $1,300/month

Cost Tips

  • Use one NAT Gateway for Dev environments
  • Shut down non-prod resources after hours
  • Prefer t3/t4g over t2
  • Use VPC Endpoints for S3/DynamoDB access

Verification Checklist

  • TGW attachments show Available
  • EC2 instances can reach each other (private IPs only)
  • Internet access routes via Egress VPC
  • WAF and Firewalls inspect all inbound/outbound traffic