{"id":321,"date":"2025-11-17T09:51:24","date_gmt":"2025-11-17T09:51:24","guid":{"rendered":"https:\/\/infivit.com\/blog\/?p=321"},"modified":"2025-11-17T09:51:26","modified_gmt":"2025-11-17T09:51:26","slug":"multi-account-aws-networking-with-transit-gateway","status":"publish","type":"post","link":"https:\/\/infivit.com\/blog\/multi-account-aws-networking-with-transit-gateway\/","title":{"rendered":"Multi-Account AWS Networking with Transit Gateway"},"content":{"rendered":"\n<p><strong>Learn how to automate secure, multi-account networking using AWS Transit Gateway \u2014 the backbone of enterprise cloud architectures.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What You\u2019ll Learn<\/strong><\/h2>\n\n\n\n<p>In this hands-on demo, we\u2019ll explore:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>What <strong>AWS Transit Gateway (TGW)<\/strong> is and why it\u2019s better than VPC peering<\/li>\n\n\n\n<li>How to design a <strong>multi-account, multi-VPC<\/strong> architecture for scale and security<\/li>\n\n\n\n<li>How to deploy it all using <strong>Terraform and Terragrunt<\/strong> for automation and repeatability<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"672\" src=\"https:\/\/infivit.com\/blog\/wp-content\/uploads\/image-9-1024x672.png\" alt=\"\" class=\"wp-image-322\" srcset=\"https:\/\/infivit.com\/blog\/wp-content\/uploads\/image-9-1024x672.png 1024w, https:\/\/infivit.com\/blog\/wp-content\/uploads\/image-9-300x197.png 300w, https:\/\/infivit.com\/blog\/wp-content\/uploads\/image-9-768x504.png 768w, https:\/\/infivit.com\/blog\/wp-content\/uploads\/image-9-1536x1009.png 1536w, https:\/\/infivit.com\/blog\/wp-content\/uploads\/image-9.png 2021w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>An&nbsp;<strong>AWS Transit Gateway (TGW)<\/strong>&nbsp;acts as a central hub to interconnect multiple Virtual Private Clouds (VPCs) and on-premises networks. As cloud environments expand across regions,&nbsp;<strong>inter-Region peering<\/strong>&nbsp;enables Transit Gateways to seamlessly connect through the AWS Global Infrastructure, delivering secure and scalable networking.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Introduction: The Networking Challenge at Scale<\/strong><\/h2>\n\n\n\n<p>As organizations scale across AWS, managing connectivity between multiple VPCs and accounts becomes complex:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Full-mesh peering quickly becomes <strong>unmanageable<\/strong>.<\/li>\n\n\n\n<li>Route tables are <strong>hard to track<\/strong> and <strong>error-prone<\/strong>.<\/li>\n\n\n\n<li>Centralized security enforcement is nearly <strong>impossible<\/strong>.<\/li>\n<\/ul>\n\n\n\n<p>This is where <strong>AWS Transit Gateway<\/strong> steps in \u2014 acting as a <strong>centralized routing hub<\/strong> that connects VPCs, enforces consistent security, and enables scalable, multi-account networking.<\/p>\n\n\n\n<p id=\"701d\">\u2696\ufe0f <strong>Why Not Just Use VPC Peering?<\/strong><\/p>\n\n\n\n<p>VPC peering works for small setups, but once multiple accounts and inspection layers come in, it falls short.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Feature<\/th><th>VPC Peering<\/th><th>AWS Transit Gateway<\/th><\/tr><\/thead><tbody><tr><td>Connection Type<\/td><td>Point-to-Point<\/td><td>Centralized Hub<\/td><\/tr><tr><td>Route Management<\/td><td>Manual<\/td><td>Centralized<\/td><\/tr><tr><td>Cross-Account<\/td><td>Complex<\/td><td>Native Support<\/td><\/tr><tr><td>Scalability<\/td><td>Limited<\/td><td>Enterprise-Grade<\/td><\/tr><tr><td>Security Control<\/td><td>Distributed<\/td><td>Centralized<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p id=\"701d\">\ud83d\udc49 <strong>Transit Gateway wins<\/strong> for any environment beyond 2-3 VPCs or accounts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Architecture Overview<\/strong><\/h2>\n\n\n\n<p>Here\u2019s the high-level design we\u2019ll build:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        Internet\n             \u2502\n            \u25bc\n \u250c\u2500\u2500 \u2500\u2500\u2500\u2510\n  \u2502  DMZ VPC     \u2502  \u2190 ALB + WAF (Ingress)\n \u2514\u2500\u2500\u252c\u2500  \u2500\u2518\n              \u2502\n             \u25bc\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500<strong>\u2500<\/strong>\u2500\u2510\n  \u2502  Transit Gateway        \u2502  \u2190 Central Networking Hub\n \u2514\u2500 \u2500\u252c\u2500\u2500\u2500\u2500\u252c\u2500\u2518\n              \u25bc               \u25bc\n \u250c\u2500\u2500\u2500\u2500\u2510  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  \u2502Security     \u2502     \u2502    App VPCs    \u2502\n  \u2502  VPCs        \u2502     \u2502   (Dev\/Prod)    \u2502\n \u2514\u2500\u2500\u2500\u2500\u2518  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n<\/code><\/pre>\n\n\n\n<p><strong>Traffic Flow:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Inbound:<\/strong> User \u2192 Ingress (ALB + WAF) \u2192 TGW \u2192 Workload VPC<\/li>\n\n\n\n<li><strong>Outbound:<\/strong> Workload \u2192 TGW \u2192 Egress (Firewall + NAT) \u2192 Internet<\/li>\n\n\n\n<li><strong>East-West:<\/strong> TGW routes control workload-to-workload communication securely<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Core Design Principles<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1. Central Networking Account<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Hosts and manages the <strong>Transit Gateway<\/strong><\/li>\n\n\n\n<li>Controls all <strong>attachments and propagations<\/strong><\/li>\n\n\n\n<li>Acts as the <strong>source of truth<\/strong> for routing<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2. Ingress \/ Egress Inspection<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Ingress VPC<\/strong>: ALB + WAF + AWS Network Firewall for inbound inspection<\/li>\n\n\n\n<li><strong>Egress VPC<\/strong>: NAT Gateways + Firewall for outbound inspection<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3. Workload Isolation<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Separate <strong>Dev<\/strong>, <strong>Prod<\/strong>, and <strong>Shared Services<\/strong> accounts<\/li>\n\n\n\n<li>No direct internet access \u2014 traffic must pass through inspection VPCs<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\u2699\ufe0f <strong>Implementation with Terraform &amp; Terragrunt<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Repository Structure<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>.\n\u251c\u2500\u2500 environments\/\n \u2502   \u251c\u2500\u2500 common\/\n \u2502    \u2502   \u251c\u2500\u2500 networking\/        # Transit Gateway\n \u2502    \u2502   \u2514\u2500\u2500 firewall-admin\/  # Security VPCs\n \u2502   \u251c\u2500\u2500 dev\/                          # Dev environments\n \u2502   \u2514\u2500\u2500production\/            # Prod environments\n\u2514\u2500modules\/                        # Reusable Terraform modules\n    \u251c\u2500\u2500 vpc\/\n    \u251c\u2500\u2500 ec2\/\n    \u251c\u2500\u2500 rds\/\n    \u251c\u2500\u2500 alb\/\n    \u251c\u2500\u2500 gwlb\/\n    \u251c\u2500\u2500 network_firewall\/\n    \u2514\u2500\u2500 waf\/\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Terragrunt Keeps It DRY<\/strong><\/h3>\n\n\n\n<p>Example parent configuration (<code>environments\/dev\/root.hcl<\/code>):<br><a href=\"https:\/\/gist.github.com\/SumitPokale7\/3cb568f654d6990d87d3131933b5c1bc\" target=\"_blank\" rel=\"noopener\">Example config overview<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>locals {\n  region     = \"us-east-2\"\n  account_id = \"390259467000\"\n}\n\nremote_state {\n  backend = \"s3\"\n  config = {\n    bucket = \"global-infra-state-us-east-2\"\n    key    = \"dev\/${path_relative_to_include()}\/terraform.tfstate\"\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Each child module simply inherits from this parent, e.g. (<code>vpc\/terragrunt.hcl<\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>include \"root\" {\n  path = find_in_parent_folders(\"root.hcl\")\n}\n\nterraform {\n  source = \"..\/..\/..\/..\/modules\/vpc\"\n}\n\ninputs = {\n  vpc_cidr = \"10.10.0.0\/16\"\n  vpc_name = \"Mezzo_Dev_VPC\"\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Cross-Account TGW Sharing<\/strong><\/h3>\n\n\n\n<p>Networking Account:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>enable_cross_account_sharing = true\nshared_account_ids = &#091;\n  \"337537076***\",  # Firewall\n  \"390259467***\",  # Dev\n  \"327903111***\",  # Prod\n]\n<\/code><\/pre>\n\n\n\n<p>Application Account:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>attach_to_tgw      = true\ntransit_gateway_id = dependency.tgw.outputs.transit_gateway_id\n<\/code><\/pre>\n\n\n\n<p>Terragrunt automatically resolves dependencies between modules \u2014 no manual waiting.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Security Layers<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1. AWS Network Firewall<\/strong><\/h3>\n\n\n\n<p>Example stateless rule:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rule_groups = {\n  allow-http = {\n    capacity = 100\n    type     = \"STATELESS\"\n    priority = 10\n    rule_group = {\n      rules_source = {\n        stateless_rules_and_custom_actions = {\n          stateless_rules = &#091;{\n            rule_definition = {\n              actions = &#091;\"aws:pass\"]\n              match_attributes = {\n                protocols         = &#091;6]\n                destination_ports = &#091;{ from_port = 80, to_port = 80 }]\n              }\n            }\n            priority = 1\n          }]\n        }\n      }\n    }\n  }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2. AWS WAF<\/strong><\/h3>\n\n\n\n<p>Protects internet-facing ALBs with managed rules and rate limiting.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>waf_common_rules = &#091;\n  {\n    name            = \"AWSManagedRulesCommonRuleSet\"\n    priority        = 1\n    vendor_name     = \"AWS\"\n  }\n]<\/code><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Deployment Steps<\/strong><\/h2>\n\n\n\n<p>1\ufe0f\u20e3 <strong>Deploy Transit Gateway<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export AWS_PROFILE=networking_account\ncd environments\/common\/networking\/transit-gateway\nterragrunt apply<\/code><\/pre>\n\n\n\n<p>2\ufe0f\u20e3 <strong>Deploy Security VPCs<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export AWS_PROFILE=firewall_account\ncd environments\/common\/firewall-admin\nterragrunt run-all apply\n<\/code><\/pre>\n\n\n\n<p>3\ufe0f\u20e3 <strong>Configure TGW Routing<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export AWS_PROFILE=networking_account\ncd environments\/common\/networking\/transit-gateway-routing\nterragrunt apply\n<\/code><\/pre>\n\n\n\n<p>4\ufe0f\u20e3 <strong>Deploy Application Environment<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export AWS_PROFILE=dev_account\ncd environments\/dev\/mezzo-dev\nterragrunt run-all apply<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Best Practices<\/strong><\/h2>\n\n\n\n<p><strong>Networking<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Host TGW in a <strong>dedicated account<\/strong><\/li>\n\n\n\n<li>Use <strong>separate route tables<\/strong> for Ingress, Egress, and Workloads<\/li>\n\n\n\n<li>Enable <strong>Flow Logs<\/strong> and <strong>CloudWatch metrics<\/strong><\/li>\n<\/ul>\n\n\n\n<p><strong>Security<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enforce <strong>IMDSv2<\/strong><\/li>\n\n\n\n<li>Inspect both <strong>inbound and outbound<\/strong> traffic<\/li>\n\n\n\n<li>Integrate <strong>GuardDuty<\/strong>, <strong>Security Hub<\/strong>, and <strong>IAM Access Analyzer<\/strong><\/li>\n<\/ul>\n\n\n\n<p><strong>Operations<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Automate everything via <strong>CI\/CD pipelines<\/strong><\/li>\n\n\n\n<li>Use <strong>Terraform Cloud or remote S3 backends<\/strong> for state<\/li>\n\n\n\n<li>Regularly review <strong>TGW quotas and costs<\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udcc9 <strong>Estimated Monthly Costs (us-east-2)<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Resource<\/th><th>Estimated Cost<\/th><\/tr><\/thead><tbody><tr><td>Transit Gateway + Attachments<\/td><td>~$360<\/td><\/tr><tr><td>NAT Gateways (2)<\/td><td>~$65<\/td><\/tr><tr><td>Network Firewall (2 AZs)<\/td><td>~$730<\/td><\/tr><tr><td>EC2 (12 \u00d7 t2.micro)<\/td><td>~$100<\/td><\/tr><tr><td>ALB<\/td><td>~$23<\/td><\/tr><tr><td><strong>Total<\/strong><\/td><td><strong>\u2248 $1,300\/month<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>Cost Tips<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use <strong>one NAT Gateway<\/strong> for Dev environments<\/li>\n\n\n\n<li>Shut down <strong>non-prod resources after hours<\/strong><\/li>\n\n\n\n<li>Prefer <strong>t3\/t4g<\/strong> over t2<\/li>\n\n\n\n<li>Use <strong>VPC Endpoints<\/strong> for S3\/DynamoDB access<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Verification Checklist<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>TGW attachments show <strong>Available<\/strong><\/li>\n\n\n\n<li>EC2 instances can reach each other (private IPs only)<\/li>\n\n\n\n<li>Internet access routes via Egress VPC<\/li>\n\n\n\n<li>WAF and Firewalls inspect all inbound\/outbound traffic<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to automate secure, multi-account networking using AWS Transit Gateway \u2014 the backbone of enterprise cloud architectures. What You\u2019ll Learn In this hands-on demo, we\u2019ll explore: An&nbsp;AWS Transit Gateway (TGW)&nbsp;acts as a central hub to interconnect multiple Virtual Private Clouds (VPCs) and on-premises networks. As cloud environments expand across regions,&nbsp;inter-Region peering&nbsp;enables Transit Gateways to &#8230; <a title=\"Multi-Account AWS Networking with Transit Gateway\" class=\"read-more\" href=\"https:\/\/infivit.com\/blog\/multi-account-aws-networking-with-transit-gateway\/\" aria-label=\"Read more about Multi-Account AWS Networking with Transit Gateway\">Read more<\/a><\/p>\n","protected":false},"author":4,"featured_media":328,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[22,24,4,25,26,23],"class_list":["post-321","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-networking","tag-aws","tag-multiaccount","tag-security","tag-terraform","tag-terragrunt","tag-transitgateway"],"_links":{"self":[{"href":"https:\/\/infivit.com\/blog\/wp-json\/wp\/v2\/posts\/321","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/infivit.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/infivit.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/infivit.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/infivit.com\/blog\/wp-json\/wp\/v2\/comments?post=321"}],"version-history":[{"count":5,"href":"https:\/\/infivit.com\/blog\/wp-json\/wp\/v2\/posts\/321\/revisions"}],"predecessor-version":[{"id":331,"href":"https:\/\/infivit.com\/blog\/wp-json\/wp\/v2\/posts\/321\/revisions\/331"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/infivit.com\/blog\/wp-json\/wp\/v2\/media\/328"}],"wp:attachment":[{"href":"https:\/\/infivit.com\/blog\/wp-json\/wp\/v2\/media?parent=321"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/infivit.com\/blog\/wp-json\/wp\/v2\/categories?post=321"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/infivit.com\/blog\/wp-json\/wp\/v2\/tags?post=321"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}