Run Triggers, Outputs, and Integrations
Scenario: An application team's workspace applies successfully, but it does so before the separate network team's workspace has actually finished publishing the specific output the application configuration depends on - the apply either fails outright or, worse, silently uses a stale value.
As infrastructure gets split across multiple states and workspaces (Module 6's directory-per-environment pattern, taken further across teams), you sometimes need one workspace's completion to reliably kick off work in another. Run triggers let an upstream workspace's successful completion automatically queue a run in a downstream workspace, addressing the sequencing half of the scenario above. Sharing the actual values between them uses the same mechanisms from Module 6 - terraform_remote_state, or HCP Terraform's narrower output-sharing features.
Dynamic provider credentials are worth calling out specifically here: rather than storing long-lived cloud credentials as static secrets in every workspace, HCP Terraform and similar platforms can issue short-lived, run-scoped credentials on demand, meaningfully reducing how many standing secrets exist to ever leak in the first place. Beyond triggers and credentials, VCS webhooks (kicking off runs from pull requests), notifications, run tasks (custom checks that gate a run), and general APIs all connect Terraform into a broader review, security, cost, and deployment ecosystem. But automated sequencing alone doesn't solve compatibility: the downstream consumer still needs the upstream producer's output contract to actually be stable and versioned - a run trigger firing at the right time doesn't help if the value it delivers has silently changed shape.
Analogy: A factory's conveyor belt can absolutely move parts from one station to the next fully automatically. But if the connector at the end of the belt doesn't match the connector the next station expects, automating the belt's timing doesn't fix anything - the actual connector's dimensions still have to be versioned, documented, and kept compatible on both ends.
A worked configuration
# Upstream publishes a stable contract:
output "network_id" { value = fakecloud_network.shared.id }
# Downstream consumes only that contract.
Be deliberate about avoiding long, automatically-triggered chains of applies (workspace A triggers B triggers C triggers D) that let one small upstream change silently cascade across an entire estate with no human checkpoint along the way. Make the real blast radius of any such chain visible to whoever approves the first run in it, build in the ability to cancel a chain partway through, and require progressively stronger approval as a chain of triggered runs gets closer to production - the same principle from Module 6's promotion pattern, now applied across automated run sequencing rather than just manual promotion steps.
Common mistakes in production
- Relying on run-trigger timing alone to guarantee compatibility, without also treating the upstream workspace's outputs as a versioned, stable contract the downstream side can depend on.
- Chaining automatic run triggers across many workspaces with no human checkpoint anywhere in the chain, letting one small upstream change cascade uncontrolled all the way to production.
Goal: Treat the plan as a change contract: understand every create, update, replacement, and destroy before approving it. Reinforce this lesson in the tf-cross-state-outputs Terraform lab. Open/labs/terraformand choose slugtf-cross-state-outputs; the lab runs real Terraform against the offline FakeCloud provider.