close

Terraform Stacks: MyCoCo's Landing Zone Dependencies Done Right

How MyCoCo transformed landing zone management from a coordination nightmare into an automatically-orchestrated dependency graph

Elevator Pitch

Every growing platform team faces the same architectural challenge: shared infrastructure—networking, security, identity—must evolve independently from the applications that consume it, yet changes to these "landing zones" ripple unpredictably across downstream systems. MyCoCo's platform team discovered this the hard way when a routine networking update triggered a 47-minute production outage. Terraform Stacks, now generally available in HCP Terraform, transforms landing zone management from a coordination nightmare into an automatically-orchestrated dependency graph—making foundational infrastructure changes safe, visible, and automatically propagated to every consuming application.

TL;DR

The Problem: Landing zone changes—networking, security, IAM baselines—create invisible dependencies that break downstream applications when platform teams update shared infrastructure

The Solution: Terraform Stacks with Linked Stacks formalize landing zone relationships, automatically triggering downstream plans when foundational infrastructure changes

The Impact: MyCoCo eliminated surprise outages from landing zone updates and reduced cross-team coordination from hours of Slack messages to automatic HCP Terraform notifications

Key Implementation: Landing zone Stack publishes outputs via publish_output blocks; product Stacks consume them via upstream_input blocks with automatic change propagation

Bottom Line: If your platform team manages shared infrastructure that application teams consume, Linked Stacks turn that implicit dependency into an explicit, automatically-orchestrated relationship

Click to enlarge
Terraform Stacks Architecture Diagram

Terraform Stacks: Components for reusable modules, Deployments for environment parity, and Linked Stacks for automatic dependency orchestration

The Challenge: When Landing Zone Updates Break Everything

MyCoCo's architecture followed the pattern every scaling platform team adopts: centralized landing zones managed by the platform team, consumed by product teams through Terraform data sources. Five product teams, three environments, two regions—on paper, clean separation of concerns. In practice? Invisible dependencies everywhere.

The breaking point came on a Friday afternoon. The platform team pushed a routine subnet reorganization. GitHub Actions ran successfully. Tests passed. Three hours later, the Support team deployed an application update referencing security group IDs that had been reorganized. Production was down for 47 minutes.

"The landing zone is supposed to be the stable foundation," Sam (Senior DevOps Engineer) said during the post-incident review. "Instead, it's a source of surprise outages because we have no way to know which product stacks depend on which outputs—until something breaks."

Jordan (Platform Engineer) had been tracking Terraform Stacks since the beta. The GA release included Linked Stacks—exactly what MyCoCo needed: landing zone dependencies that are explicit, visible, and automatically coordinated.

The Solution: Stacks for Landing Zone Architecture

Terraform Stacks address the landing zone problem through three interconnected concepts: Components for reusable infrastructure definitions, Deployments for environment-specific instantiation, and Linked Stacks for formalizing cross-stack dependencies.

Important: Stacks are exclusively an HCP Terraform feature—they're not available in open-source Terraform. With RUM-based pricing, each managed resource counts toward your bill. For teams already paying the coordination tax in engineering hours, Slack threads, and incident response, the trade-off often favors Stacks. But model your costs explicitly before migrating—especially for large landing zones with many downstream consumers.

Components: Reusable Landing Zone Modules

Components wrap Terraform modules into reusable building blocks. For landing zones, this means defining networking, security, and identity components once:

# landing-zone/components.tfcomponent.hcl
component "vpc" {
  source = "./modules/vpc"

  inputs = {
    environment = var.environment
    cidr_block  = var.cidr_block
    region      = var.region
  }

  providers = {
    aws = provider.aws.main
  }
}

component "security_baseline" {
  source = "./modules/security"

  inputs = {
    vpc_id      = component.vpc.vpc_id
    environment = var.environment
  }

  providers = {
    aws = provider.aws.main
  }
}

Components automatically resolve internal dependencies—security_baseline waits for vpc without orchestration scripts.

Deployments: Environment Parity Without the Drift

Maintaining landing zones across multiple environments traditionally forces an uncomfortable choice: copy-paste your Terraform code and modify it per environment (leading to inevitable drift), or manage complex variable files with conditional logic that becomes increasingly fragile.

Deployments solve this by letting you define your infrastructure once via Components, then create multiple instantiations with only the inputs changing:

# landing-zone/deployments.tfdeploy.hcl
deployment "development" {
  inputs = {
    environment = "dev"
    cidr_block  = "10.1.0.0/16"
    region      = "ca-central-1"
  }
}

deployment "production" {
  inputs = {
    environment = "prod"
    cidr_block  = "10.0.0.0/16"
    region      = "ca-central-1"
  }
}

Both deployments run the exact same VPC and security baseline components—just with different inputs. Each deployment maintains its own isolated state file, so changes to one environment never accidentally affect another.

The practical payoff: when your platform team updates the VPC component logic, that change rolls out consistently to both dev and prod. No more "works in dev, breaks in prod" because the configurations drifted over months of separate maintenance.

Linked Stacks: The Landing Zone Game-Changer

The killer feature for platform teams is Linked Stacks. Instead of product teams using fragile data sources to reference landing zone outputs, the relationship becomes explicit and automatically coordinated.

The landing zone Stack publishes specific outputs for downstream consumption—building on the production deployment we defined above:

# landing-zone/deployments.tfdeploy.hcl (continued)
publish_output "vpc_id" {
  description = "Production VPC for application stacks"
  value       = deployment.production.vpc_id
}

publish_output "private_subnet_ids" {
  description = "Private subnets for application workloads"
  value       = deployment.production.private_subnet_ids
}

Product Stacks declare explicit dependencies on the landing zone using upstream_input blocks:

# product-stack/deployments.tfdeploy.hcl
upstream_input "landing_zone" {
  type   = "stack"
  source = "app.terraform.io/mycoco/platform/landing-zone"
}

deployment "production" {
  inputs = {
    environment = "prod"
    vpc_id      = upstream_input.landing_zone.vpc_id
    subnet_ids  = upstream_input.landing_zone.private_subnet_ids
  }
}

The critical benefit: when the platform team updates the landing zone—adding subnets, modifying security groups, changing routing—HCP Terraform automatically triggers plans in every downstream product Stack. No more "who needs to know about this change?" conversations. No more forgotten dependencies causing Friday incidents.

Results: Landing Zone Changes Without Fear

Six weeks after migrating the landing zone to Stacks, the transformation was unmistakable.

Landing zone updates went from anxiety-inducing Slack announcements to routine operations. When networking changes are needed, HCP Terraform automatically queues plans for all five product Stacks—product teams see exactly what upstream changes triggered their plan. The "did anyone change the landing zone today?" messages disappeared entirely.

Environment drift hasn't occurred since the migration. The same components deploy identically across environments; when the platform team adds a subnet, it appears everywhere simultaneously.

"Friday deployments used to terrify me," Sam admitted. "Now the dependency graph isn't in my head anymore—it's in the configuration."

The team retired 400 lines of orchestration scripts and three GitHub Actions workflows. More importantly, they retired the on-call burden of being the human dependency resolver.

Key Takeaways

Start with your landing zone. If your platform team manages shared infrastructure consumed by application teams, migrate the landing zone first. The publish_output pattern immediately demonstrates value to downstream teams who see automatic plan triggers instead of surprise breakages.

Linked Stacks replace tribal knowledge. Every data source referencing another team's infrastructure is an implicit dependency waiting to cause an incident. upstream_input blocks make those relationships explicit, versioned, and automatically coordinated.

Automatic propagation changes team dynamics. When landing zone changes automatically trigger downstream plans, the platform team stops being a coordination bottleneck and starts being an infrastructure service provider.

Model your costs before migrating. Stacks are HCP Terraform-only. Calculate your RUM-based costs against the engineering hours you're currently spending on coordination—for most teams with complex landing zones, the math favors Stacks.

Migrate incrementally. Stacks coexist with traditional workspaces. Migrate your landing zone, connect one product Stack as a proof of concept, then expand. The upstream_input pattern works across the boundary—new Stacks can consume from existing ones.

For platform teams drowning in cross-repository dependencies and change coordination, Linked Stacks represent the most significant improvement to landing zone management since Terraform workspaces. The dependency graph you've been maintaining manually? It's finally infrastructure as code.

← Back to Logs

Explore more articles and projects