Prerequisites
Before you start
Section titled “Before you start”- Clone the source demo repository
- Work from the demo repository root for all commands in this walkthrough
AWS accounts and regions
Section titled “AWS accounts and regions”- Three AWS accounts —
network,dev, andsandbox - Both regions enabled on each account:
ap-southeast-2andap-southeast-6
Why these two regions?
This walkthrough uses ap-southeast-2 and ap-southeast-6 as concrete
examples — one established region plus a second for
cross-region association
VPCs in ap-southeast-6 associate with a PHZ in ap-southeast-2 — Route 53 resolves shared records across regions from one zone.. Any
two regions work if you rename stacks, update CIDRs, and set vpc_region
correctly in authorizations. Before you commit, check that Terraform and the
AWS provider support your chosen regions and that services you rely on (VPC,
Route 53, SSM endpoints, and so on) are available there — see Regional
service
gaps
below for one example.
Configure one profile per account:
[profile r53demo-network]sso_session = my-ssosso_account_id = 111111111111sso_role_name = AdministratorAccessregion = ap-southeast-2
[profile r53demo-dev]sso_session = my-ssosso_account_id = 222222222222sso_role_name = AdministratorAccessregion = ap-southeast-2
[profile r53demo-sandbox]sso_session = my-ssosso_account_id = 333333333333sso_role_name = AdministratorAccessregion = ap-southeast-2Verify before each phase:
export AWS_PROFILE=r53demo-network # or dev / sandboxaws sts get-caller-identityTerraform and provider versions
Section titled “Terraform and provider versions”| Requirement | Value |
|---|---|
| Terraform | >= 1.5.0 |
| AWS provider | 6.53.0 per stack (versions.tf) — required for ap-southeast-6 |
After cloning or pulling demo updates:
terraform -chdir=terraform/accounts/<stack> init -upgradePhase-specific variables
Section titled “Phase-specific variables”| Variable | Where | When needed |
|---|---|---|
dev_apse2_vpc_id, dev_apse6_vpc_id, sandbox_apse2_vpc_id, sandbox_apse6_vpc_id | network | Phase 2a — from workload Phase 1 outputs |
zone_id | network-apse6, all workload stacks | Phase 2b / Phase 3 — from network Phase 2a output |
Copy terraform.tfvars.example → terraform.tfvars per stack after Phase 1 outputs are captured.
Default provider tags: Project=r53demo, Account=<network|dev|sandbox>, ManagedBy=terraform.
AWS Console region picker
Section titled “AWS Console region picker”Route 53 hosted zones appear global in the console. VPC and EC2 are regional. Switching services may reset the region picker — if lists look empty, switch back to ap-southeast-2 or ap-southeast-6 before assuming deploy failed.
SSM Session Manager prerequisites
Section titled “SSM Session Manager prerequisites”Test_EC2
One minimal EC2 per stack (seven total) for in-VPC DNS checks via SSM Session Manager and `dig`. instances sit in private
subnets with no public IP. Session Manager needs either:
| Path | Requirements | Used in demo |
|---|---|---|
| VPC interface endpoints Interface endpoints for `ssm`, `ssmmessages`, and `ec2messages` — required for Session Manager in private subnets. | All three SSM services in the same region as the instance | ap-southeast-2 stacks (default) |
| Internet egress | NAT gateway Optional internet egress for private subnets on `*-apse6` stacks when full SSM shell access is needed. ( enable_nat_gateway=true) | Optional on *-apse6 stacks |
Required SSM endpoint services when using VPC endpoints:
| Service suffix | Required |
|---|---|
ssm | Yes |
ssmmessages | Yes |
ec2messages | Yes |
ap-southeast-6 SSM endpoints
Section titled “ap-southeast-6 SSM endpoints”In ap-southeast-6, AWS has launched ssm and ssmmessages interface endpoints, but not ec2messages yet. *-apse6 stacks default to the two available services so terraform apply succeeds.
| Variable | Default (*-apse2) | Default (*-apse6) |
|---|---|---|
enable_ssm_vpc_endpoints | true | true |
ssm_vpc_endpoint_services | all three | ssm, ssmmessages only |
Confirm after apply:
terraform -chdir=terraform/accounts/dev-apse6 output ssm_vpc_endpoints_enabledterraform -chdir=terraform/accounts/dev-apse6 output ssm_vpc_endpoint_services# Expected today: true, ["ssm", "ssmmessages"]Check whether ec2messages exists before adding it:
aws ec2 describe-vpc-endpoint-services \ --service-names com.amazonaws.ap-southeast-6.ec2messages \ --region ap-southeast-6 \ --query 'ServiceDetails[0].ServiceName' \ --output textOptional NAT for ap-southeast-6 SSM
Section titled “Optional NAT for ap-southeast-6 SSM”Until ec2messages exists as a VPC interface endpoint, interactive Session Manager from private subnets may need internet egress. Set enable_nat_gateway = true on network-apse6, dev-apse6, and sandbox-apse6 to enable a NAT gateway
Optional internet egress for private subnets on `*-apse6` stacks when full SSM shell access is needed..
Cost
Approximate NAT cost: ~USD 0.06/hour per gateway (~USD 1.40/day per stack). Disable NAT or destroy stacks during teardown to stop charges.
Never partial re-apply
Never re-apply with only -var="enable_nat_gateway=true" — that omits
zone_id and Terraform may destroy the Route 53 VPC association. Always use
-var-file=terraform.tfvars with full phase flags.
Limitations and lessons learned
Section titled “Limitations and lessons learned”These are operational realities of the classic pattern in this demo — not bugs in Route 53 itself.
Regional service gaps (ap-southeast-6)
Section titled “Regional service gaps (ap-southeast-6)”Regional service gaps
A region lacks a service for full verification — e.g. `ec2messages` may be unavailable in ap-southeast-6. affect
SSM, not DNS: VPC_Association
AssociateVPCWithHostedZone — workload account links its VPC to an authorized private hosted zone so the VPC resolver can query shared records. and
Route 53 resolution work regardless of SSM. SSM agents on *-apse6 instances
may register with only ssm + ssmmessages endpoints. If start-session
fails, use send-command, enable NAT, or verify with Step A in
Verification.
Two-party operations
Section titled “Two-party operations”Network_Account creates authorizations; Dev_Account and Sandbox_Account create associations — separate profiles, separate applies, fixed order.
Cross-stack coupling
Section titled “Cross-stack coupling”Manual handoff of four workload vpc_id values into network, then zone_id into five downstream stacks. Stale IDs are the most common demo failure mode.
Teardown ordering
Section titled “Teardown ordering”Route 53 blocks PHZ deletion while cross-account associations exist. Set feature flags to false on workload stacks before destroying network.
Next step
Section titled “Next step”Pre-flight checks before your first apply.