Terraform models Transit Gateway routing as separate resources
AWS provider 1.49 adds Transit Gateway support, including attachments and distinct routing relationships. Its defaults make routing policy part of the initial configuration decision.
Connecting networks through a central gateway reduces the number of direct relationships an infrastructure design has to manage. It also concentrates routing decisions in a place that needs explicit configuration. AWS provider 1.49.0, released November 27, adds Transit Gateway support with resources for those relationships as well as the gateway itself. The changelog lists VPC attachments, routes, route tables, and separate association and propagation resources.
AWS's launch announcement, published the previous day, describes a managed network connecting VPCs and external networks through a central gateway. It also describes multiple routing domains within a gateway. A shared network connection therefore does not require every attachment to participate in identical routing policy.
I find the Terraform addition useful because that policy needs a durable representation alongside the connected infrastructure. The gateway resource alone would leave too much of the network's meaning outside the configuration. Separate routing relationships give a reviewer more information about how attachments participate in the design.
The gateway's defaults already express policy
The gateway resource documentation permits a short declaration with a description. It also exposes defaults that affect attachments. Automatic association with the default association table and automatic propagation to the default propagation table are enabled unless disabled.
resource "aws_ec2_transit_gateway" "example" {
description = "Example routed network"
default_route_table_association = "disable"
default_route_table_propagation = "disable"
}
This example opts out of both defaults so a configuration can describe custom relationships. It is not a complete connected network. The point is that automatic behavior is a configuration decision even when the declaration omits the corresponding arguments.
The gateway exports identifiers for its default association and propagation route tables. These are explicit attributes, so dependent resources can refer to the relevant table without attempting to derive an identifier from the gateway's name. The resource also exports the owning account ID and gateway ARN.
Other documented options include the Amazon-side ASN and automatic acceptance of shared attachments. The latter defaults to disabled. This is another separate relationship to understand when a gateway is shared. Sharing access to a gateway and automatically accepting every attachment request are not the same setting.
Attachments identify the connected VPC
The VPC attachment resource requires subnet identifiers, the gateway identifier, and the VPC identifier. Its own default-table association and propagation arguments are booleans, both defaulting to true. Their representation differs from the gateway's string-valued enable and disable options.
resource "aws_ec2_transit_gateway_vpc_attachment" "example" {
subnet_ids = ["${aws_subnet.example.id}"]
transit_gateway_id = "${aws_ec2_transit_gateway.example.id}"
vpc_id = "${aws_vpc.example.id}"
transit_gateway_default_route_table_association = false
transit_gateway_default_route_table_propagation = false
}
This excerpt assumes an existing subnet and VPC declaration. It makes the attachment's intended use of custom routing explicit. The exported attachment ID then becomes the reference used by association and propagation resources. That identity is distinct from the gateway ID and the connected VPC ID.
The distinction between these identifiers matters in configuration review. A route points toward an attachment, while a route table belongs to a gateway. Using separate resource types allows Terraform references to express those relationships directly instead of relying on comments around manually supplied strings.
Association and propagation remain distinct
The new association resource connects an attachment identifier to a route-table identifier. A propagation resource accepts the same kinds of identifiers but manages a different relationship. These remain separate declarations in the resource model.
That separation is consistent with AWS's ability to define routing domains per attachment. The routing table associated with an attachment and the tables receiving its propagated routes describe different aspects of the design. Treating either as an incidental side effect of attaching a VPC would obscure policy that a custom routing configuration needs to make deliberate.
resource "aws_ec2_transit_gateway_route_table" "example" {
transit_gateway_id = "${aws_ec2_transit_gateway.example.id}"
}
resource "aws_ec2_transit_gateway_route_table_association" "example" {
transit_gateway_attachment_id = "${aws_ec2_transit_gateway_vpc_attachment.example.id}"
transit_gateway_route_table_id = "${aws_ec2_transit_gateway_route_table.example.id}"
}
This fragment creates a table and declares an association. It does not also request propagation. A separate propagation declaration can target the intended table, making that additional relationship visible. The route-table documentation also exports whether a table is the gateway's default association or propagation table.
I prefer seeing these relationships as configuration because a network's connectivity policy can otherwise disappear inside defaults. The additional declarations have a cost in length, but they identify precisely which attachment and table a change concerns. That is useful information when several VPCs share the gateway.
Existing VPC routes also gain a gateway target
The release extends ordinary route resources with transit_gateway_id. It also adds that target to route-table configuration and permits VPN connections to reference a Transit Gateway. The integration therefore includes the resources that direct traffic toward the gateway, rather than ending at gateway creation.
Within the gateway, the new route resource declares an IPv4 destination CIDR, an attachment target, and a gateway route table. Its documentation states that routing uses the most specific destination match. This route exists in a different table from an ordinary VPC route directing traffic to the gateway.
Those two declarations answer different questions in the network model. One directs traffic from the VPC toward a gateway. The other describes a destination and attachment within the gateway's routing configuration. A complete design needs to account for both where appropriate, alongside the chosen association and propagation behavior.
The provider also adds data sources for the gateway, route table, and VPC attachment. These let a configuration refer to existing objects without making all of them resources owned by that configuration. That is useful when network ownership is divided among configurations. Lifecycle ownership can stay with one configuration while another uses the resulting identifiers to express its own routing relationships. The distinction also makes a proposed deletion easier to interpret. A configuration that only reads a gateway has a different management responsibility from one that declares the gateway and its attachments as resources.