Subchapter 88.8
references/segmenting-traffic-with-route-tables.mdMarkdown13 KBView on GitHub
Domain expertise for controlling which attachments on a transit gateway can reach which, so some groups of VPCs talk to each other while others stay isolated (keeping production separate from development while both reach shared services). Covers the open default that defeats segmentation, the association-versus-propagation distinction that decides direction, the small number of route tables a real design needs, and the blackhole routes that keep isolation from leaking.
Does not cover creating the transit gateway or attaching VPCs (a separate reference), centralized egress, hybrid connectivity, peering, or multicast. Those are separate references.
Execute commands using the AWS MCP server when connected (sandboxed execution, audit logging, observability). Fall back to the AWS CLI otherwise. A transit gateway is Regional; run every command in the Region that holds the hub.
To segment traffic end to end, follow the procedure exactly. See the Procedure section below. It covers creating one route table per routing domain, associating each attachment with the table that defines what it can reach, propagating attachment routes only into the tables allowed to reach them, adding blackhole routes for ranges that must stay blocked, and surfacing the console link to verify.
The two controls do different jobs and are easy to confuse.
| Control | What it sets |
|---|---|
| Association | Which route table an attachment uses for its own outbound lookups (where its traffic can go) |
| Propagation | Which route tables learn this attachment as a reachable destination (who can reach it) |
Constraints:
With default association and propagation on, every attachment lands on one route table and can reach every other. The isolation the customer assumed is not there. Segmentation comes from association and propagation choices, not from creating the transit gateway.
Constraints:
A workable segmented design uses a small number of route tables, such as one per environment plus a shared services table, not a separate transit gateway per environment and not a route table per VPC.
Constraints:
Controlling association and propagation is not enough on its own. If a more specific route for a range exists in another table (for example propagated into a shared-services table), traffic to a range the customer meant to block can still find a path. A blackhole route drops traffic for a range explicitly.
Constraints:
Segmentation is itself a security control, so a misconfiguration silently weakens isolation rather than failing loudly. Propagating an attachment into the wrong table leaks routes between environments the customer meant to keep separate, and the gap is invisible until traffic crosses a boundary.
Constraints:
associate-transit-gateway-route-table and enable-transit-gateway-route-table-propagation callsDefault association and propagation are still on, or attachments are still on the default table. Move each attachment to its domain’s table and turn the defaults off.
Propagation is enabled into a table that should not learn that attachment, or a blackhole route is missing. Remove the propagation or add a blackhole route for the range.
The attachment is associated with the wrong table, or the destination is not propagated into the source’s table. Fix the association or enable propagation.
A more specific route exists in another table. Add an explicit blackhole route for the range.
This procedure creates the route tables, associates each attachment with its domain’s table, propagates destinations only where allowed, adds blackhole routes for blocked ranges, and surfaces the console link to verify.
Constraints for parameter acquisition:
Constraints:
aws sts get-caller-identity, and you MUST use short-lived,
ephemeral credentials scoped to least privilege for transit gateway administration, never
long-lived access keys or broad service wildcard or FullAccess policiesaws:SourceArn,
aws:SourceAccount, and kms:ViaService) so only the specific log group, bucket, or trail in the
expected account and service can use the key, preventing cross-account or cross-service misuseConstraints:
You MUST create one transit gateway route table per routing domain:
aws ec2 create-transit-gateway-route-table \
--transit-gateway-id {transit_gateway_id} --region {region}You MUST capture each TransitGatewayRouteTableId
You MUST poll until each route table reaches available:
aws ec2 describe-transit-gateway-route-tables \
--transit-gateway-route-table-ids {route_table_id} --region {region}Constraints:
You MUST first disassociate the attachment from any existing route table if it is already associated (an attachment can only be associated with one route table at a time):
aws ec2 disassociate-transit-gateway-route-table \
--transit-gateway-route-table-id {old_route_table_id} \
--transit-gateway-attachment-id {attachment_id} --region {region}You MUST associate each attachment with the route table that defines what it can reach:
aws ec2 associate-transit-gateway-route-table \
--transit-gateway-route-table-id {route_table_id} \
--transit-gateway-attachment-id {attachment_id} --region {region}You MUST poll until the association reaches associated:
aws ec2 get-transit-gateway-route-table-associations \
--transit-gateway-route-table-id {route_table_id} --region {region}Constraints:
You MUST enable propagation of an attachment into a route table only when that domain is allowed to reach the attachment:
aws ec2 enable-transit-gateway-route-table-propagation \
--transit-gateway-route-table-id {route_table_id} \
--transit-gateway-attachment-id {attachment_id} --region {region}You MUST NOT propagate an attachment into a table whose domain should not reach it
Constraints:
You MUST add a blackhole route for each range that must stay blocked:
aws ec2 create-transit-gateway-route \
--transit-gateway-route-table-id {route_table_id} \
--destination-cidr-block {blocked_range} --blackhole --region {region}Constraints:
You MUST review the routes in each table to confirm the intended reachability:
aws ec2 search-transit-gateway-routes \
--transit-gateway-route-table-id {route_table_id} \
--filters Name=state,Values=active,blackhole --region {region}You MUST present the transit gateway console link, filling {transit_gateway_id} and {region}
from the API response, and tell the customer to open it and review the route tables:
https://{region}.console.aws.amazon.com/vpc/home?region={region}#TransitGatewayRouteTables:{
"region": "us-east-1",
"transit_gateway_id": "tgw-0abc",
"domains": {
"domain-alpha": ["tgw-attach-alpha"],
"domain-beta": ["tgw-attach-beta"],
"shared": ["tgw-attach-shared"]
},
"blocked_ranges": ["10.20.0.0/16"]
}Created three route tables: domain-alpha, domain-beta, shared.
Associated each attachment with its domain's table.
Propagated shared into domain-alpha and domain-beta (both reach shared services); did not propagate
domain-alpha and domain-beta into each other (kept isolated).
Added a blackhole route for 10.20.0.0/16 in the domain-alpha and domain-beta tables.
Open the transit gateway route tables and review reachability:
https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#TransitGatewayRouteTables:They are propagated into each other’s tables, or still on the default table. Remove the propagation and confirm each is on its own domain table (Steps 3 and 4).
A more specific route exists elsewhere. Add a blackhole route for the range (Step 5).
Shared is not propagated into that domain’s table. Enable propagation of the shared attachment (Step 4).