Skip to content

Commit 8ac2910

Browse files
sir-sigurdclaude
andcommitted
Document Transit Gateway egress mode
- README: "Transit Gateway egress" section — what it does, how to enable (enable_transit_gateway + transit_gateway_id, computed id allowed), the operator-side TGW prerequisites (RAM share/accept, egress + return routes), CIDR-uniqueness requirement, IPv6 opt-in, and reversibility. - VARIABLES: rows for enable_transit_gateway, transit_gateway_id, transit_gateway_ipv6_egress. - CHANGELOG: [Unreleased] entry for the feature. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 4baa74e commit 8ac2910

3 files changed

Lines changed: 55 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Optional release notice.
1818

1919
## [Unreleased] - YYYY-MM-DD
2020

21+
- [Added] Transit Gateway egress mode for new VPCs: set `enable_transit_gateway = true` (+ `transit_gateway_id`) to route private-subnet egress through a Transit Gateway instead of NAT gateways; IPv6 egress is opt-in via `transit_gateway_ipv6_egress`. See [Transit Gateway egress](README.md#transit-gateway-egress) ([#115](https://github.com/quiltdata/iac/pull/115))
22+
2123
## [1.7.2] - 2026-06-08
2224

2325
- [Fixed] Bump `modules/cnames` AWS provider constraint from `~> 5.0` to `~> 6.0` so it resolves alongside the `vpc` module's `aws >= 6.28` requirement — using `quilt` + `cnames` in one root previously failed `terraform init` ([#117](https://github.com/quiltdata/iac/pull/117))

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,56 @@ resource "aws_vpc_endpoint" "api_gateway_endpoint" {
771771
}
772772
```
773773

774+
### Transit Gateway egress
775+
776+
By default a new Quilt VPC reaches the internet through Quilt-created NAT
777+
gateways. If you operate a Transit Gateway (TGW) as your egress boundary, set
778+
`enable_transit_gateway = true` (only with `create_new_vpc = true`). Quilt still
779+
creates the VPC, subnets, and endpoints, but instead disables the NAT gateways
780+
and the IPv6 egress-only IGW, attaches the VPC to your TGW (in the intra
781+
subnets), and points each private route table's default route at the TGW. The
782+
S3 gateway endpoint is unchanged, so bulk S3 traffic stays on the endpoint and
783+
does **not** traverse the TGW — only genuinely external egress does.
784+
785+
```hcl
786+
module "quilt" {
787+
# ...
788+
create_new_vpc = true
789+
enable_transit_gateway = true
790+
transit_gateway_id = "tgw-0123456789abcdef0" # an existing TGW, or one created in this same config
791+
# transit_gateway_ipv6_egress = true # only if your TGW carries IPv6 egress
792+
}
793+
```
794+
795+
`transit_gateway_id` may be a value known only after apply (e.g. a TGW you
796+
create in the same Terraform configuration) — the toggle is the separate
797+
`enable_transit_gateway` bool, so this does not break planning.
798+
799+
**You must provide the egress path.** Quilt owns only the VPC→TGW leg. Before
800+
apply, your TGW must:
801+
802+
- be reachable from the deployment account — share it via AWS RAM and accept
803+
the VPC attachment (or enable auto-accept) if the TGW lives in another
804+
account;
805+
- have route tables that forward the VPC's egress out to the internet (e.g. via
806+
a central egress VPC / NAT) **and** route return traffic back to the VPC's
807+
CIDR.
808+
809+
**CIDR uniqueness:** a TGW cannot route between overlapping CIDRs, so any VPCs
810+
attached to the same TGW must have non-overlapping ranges. Set `cidr`
811+
accordingly if more than one Quilt stack shares a TGW (the default is
812+
`10.0.0.0/16`).
813+
814+
**IPv6** egress through the TGW is opt-in (`transit_gateway_ipv6_egress`,
815+
default `false`). Enable it only if your TGW actually carries IPv6 egress;
816+
otherwise leave it off — IPv6 then has no default route and falls back to IPv4,
817+
rather than being black-holed at a TGW that can't route it.
818+
819+
**Reversibility:** removing `enable_transit_gateway` (or setting it `false`)
820+
restores the NAT gateways and IPv6 egress-only IGW. Toggling it on or off for an
821+
already-deployed VPC recreates/destroys NAT gateways and their Elastic IPs and
822+
briefly interrupts egress, so do it in a maintenance window.
823+
774824
### Profile
775825
You may wish to set a specific AWS profile before executing `terraform`
776826
commands.

VARIABLES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ This document provides comprehensive documentation for all variables available i
2626
| `user_subnets` | `list(string)` | `null` | ALB subnet IDs (exactly 2 required for internal ALB with existing VPC) |
2727
| `user_security_group` | `string` | `null` | Security group ID for ALB access (required for existing VPC) |
2828
| `api_endpoint` | `string` | `null` | VPC endpoint ID for API Gateway (required for internal ALB with existing VPC) |
29+
| `enable_transit_gateway` | `bool` | `false` | Route private-subnet egress through a Transit Gateway instead of NAT gateways (`create_new_vpc = true` only). Disables NAT + the IPv6 egress-only IGW; requires `transit_gateway_id`. See [Transit Gateway egress](README.md#transit-gateway-egress). |
30+
| `transit_gateway_id` | `string` | `null` | Transit Gateway to attach to (required when `enable_transit_gateway = true`). May be a value known only after apply (e.g. a TGW created in the same configuration). |
31+
| `transit_gateway_ipv6_egress` | `bool` | `false` | Also route IPv6 (`::/0`) egress through the TGW. Leave off unless the TGW carries IPv6 egress, otherwise IPv6 traffic would be black-holed. |
2932

3033
### Database Configuration Variables
3134

0 commit comments

Comments
 (0)