Skip to main content
RunBook Academy

TerraformI · Infrastructure as Code FoundationsFoundations

Terraform in the Infrastructure Ecosystem

Foundation⏱ ~12 minbash

What you'll learn

  • Place Terraform among IaC alternatives (OpenTofu, Pulumi, Crossplane, Ansible, AWS CDK)
  • Compare Terraform Cloud, Terraform Enterprise, and self-hosted OSS Terraform on cost and lock-in
  • Explain when to choose Terraform over a configuration manager or general-purpose IaC tool
  • Reason about lock-in trade-offs between vendor-managed and open-source tooling
  • Identify the criteria that make a tool choice defensible to an audit

Prerequisites

Verified against Terraform CLI 1.9.x · OpenTofu 1.7.x · HCL 2.0 · bpg/proxmox provider 0.66+ · hashicorp/local provider 2.5+ · hashicorp/null provider 3.2+ · hashicorp/random provider 3.6+ · hashicorp/http provider 3.4+ · Ubuntu 24.04 LTS · Debian 12 (Bookworm) · 2026-08-13

Not yet marked complete on this device.

A bank ran its entire branch network on Terraform Cloud. The 2023 HashiCorp licence change triggered a board-level review. Six weeks later, the team migrated 240 workspaces to OpenTofu, self-hosted on HCP Terraform-equivalent infrastructure they had not previously specified. The migration worked. The process cost more than the licence would have.

The shape of that decision — which IaC tool, managed or self-hosted, commercial or open source — is the question this lesson is about.

The landscape, in one table

Eight tools take meaningful Terraform-adjacent workloads in 2026. The honest picture is heterogeneous.

ToolModelLanguageStrengthWeakness
Terraform (OSS)DeclarativeHCLMature provider ecosystem, push-based applyNo remote execution in OSS, no policy engine
OpenTofuDeclarativeHCLSame workflow as Terraform 1.5/1.6, BSD-licensed, community-governedSmaller provider team; some HashiCorp-only providers may lag
Terraform CloudDeclarative + remote opsHCLState, runs, policy, SSO, audit log as a serviceVendor lock-in to HashiCorp; cost scales with workspaces
Terraform EnterpriseDeclarative + governanceHCLSelf-hosted equivalent of Cloud with private networkingOperational burden; high licence cost
PulumiDeclarativeTypeScript, Go, Python, Java, .NETUse your existing language; strong type systemSmaller provider ecosystem; audit format less consistent
CrossplaneDeclarative (K8s-native)YAML (compositions)Kubernetes as the single control plane; providers are CRDsHigh learning curve; operations team must run Kubernetes
AnsibleImperative (declarative modules)YAMLBest for OS configuration, not for resource provisioningSlow at scale; no graph; no plan
AWS CDK / CDKTFSynthesised declarativeTypeScript, Go, PythonFirst-class in the language; CDKTF synthesises TerraformVendor-coupling for AWS CDK; abstraction drift

The right tool for a given team depends on three questions, in order:

  1. What is the rest of the platform running on?
  2. Who is going to maintain the IaC code in five years?
  3. What licence posture is the organisation required to adopt?

What Terraform Cloud and Enterprise actually buy you

The functionality gap between OSS Terraform and Terraform Cloud is concrete. The Cloud product provides:

  • Remote state with locking. No need to run a self-managed S3 + DynamoDB backend. The cost is per-workspace.
  • Remote runs. terraform plan and apply execute on HashiCorp infrastructure. CI does not need to be able to reach the cloud APIs.
  • SSO and RBAC. SAML and SCIM integration. Engineers authenticate via the IdP; their access is auditable.
  • Policy as code (Sentinel). Declarative guardrails that block non-compliant applies.
  • No-code provisioning. A UI for non-engineers to launch pre-approved configurations.
  • Audit log. Compliance-friendly record of every plan and apply, with the operator and the diff.

The functionality gap between Terraform Cloud and Terraform Enterprise is, broadly, where it runs and who can see it. Enterprise is self-hosted in the customer’s network, with no outbound dependencies. The functionality is comparable.

When to choose Terraform (rather than the alternatives)

The course targets Terraform 1.9.x and OpenTofu 1.7.x because both are widely deployed, mature, and use the same HCL syntax and a compatible state file. The lessons about state, drift, graph, and blast radius carry over to OpenTofu without modification. The choice between them is licensing posture, not features.

A defensible default:

  • Terraform (or OpenTofu) for resource provisioning. This lesson and every lesson after this.
  • Ansible for OS configuration. When the host is long-lived and software changes frequently, a configuration manager declares the desired state per host.
  • Pulumi when the team lives in TypeScript and is willing to operate a smaller provider ecosystem. If the team would produce better IaC in a language they already know, and the provider coverage is acceptable for the workload, Pulumi is a serious option.
  • Crossplane when Kubernetes is already the platform. The team is comfortable operating clusters. The IaC workflow is “deploy a CRD” and Kubernetes reconciles.
  • AWS CDK for AWS-only workloads with a TypeScript-fluent team. CDKTF if you want the synthesis to be Terraform underneath.

The mistake is picking a tool because the team read an article about it. The right tool is picked because the constraints point to it.

The lock-in trade-off

Vendor-managed IaC reduces operational burden. It also reduces exit optionality. The trade is rarely free.

ChoiceVendor lock-inOperational burdenCompliance posture
Terraform Cloud / EnterpriseHighLowAudit log is a managed service
Self-hosted OSS Terraform + S3 backendLowHigh (your team operates it)Your team’s audit log
Self-hosted OpenTofu + S3 backendLowestHighYour team’s audit log
Pulumi CloudHighLowAudit log is a managed service
Self-hosted Pulumi + S3MediumHighYour team’s audit log
Crossplane (self-hosted)LowHigh (Kubernetes)K8s audit log

The lock-in value, not the lock-in cost, is what justifies the choice. The team that pays for Terraform Cloud, plans a migration to OpenTofu for years, and never migrates is paying the licence for the optionality it purchased in decisions it did not exercise. That is a real cost.

The honest framing: lock-in is a latent liability, not a present cost. Pay for it when the latency matters (regulated industries, regulated data, multi-cloud mandates). Avoid it when it does not.

How to validate a tool choice

Before adopting, the team should be able to answer five questions in writing.

  1. What is the exit path? Can a new engineer run terraform state pull, store the state on an S3 backend they own, and re-apply in 30 days?
  2. What data does the managed service hold that you cannot recreate? Audit logs? Custom Sentinel policies? Service mesh configuration? Each item is lock-in.
  3. What is the per-environment cost at scale? 50 workspaces is a small bill. 5,000 is not. The cost model differs.
  4. Which features of the managed service are operational requirements vs. nice-to-haves? SSO is usually the first; no-code provisioning is usually the last.
  5. Who reviews the renewal? A managed-service contract renews silently if no one owns the review. The cost of neglect compounds.

If a team cannot answer these five questions, the tool choice is not yet defensible. It is a preference.

Production failure modes for tooling decisions

  1. Adopting Pulumi because the team wants to use TypeScript. The provider coverage for the target cloud is incomplete. Month four, the team has hand-written wrappers around the raw AWS SDK. The IaC abstraction has reverted to imperative.
  2. Adopting Terraform Cloud because the plan UI is nice. The audit log requirement is the actual driver; the audit log was not evaluated. Terraform Cloud meets it, but so does a self-hosted backend with a $5/month S3 bill.
  3. Standardising on Ansible for resource provisioning. Ansible does not have a graph. A 200-resource apply walks sequentially. The team’s “deploy time” budget is consumed by the tool.
  4. Lock-in surprises from licence changes. A tool chosen under one licence posture (BSL, MPL) becomes a different product three years later. The migration is non-trivial.
  5. Polyglot IaC. Each team picks its own tool. The knowledge does not transfer. The platform team’s review load doubles. The audit is fragmentary.

Security implications

Tool choice has security consequences that do not show up in the comparison table.

  • State backend choice determines blast radius. A self-hosted S3 backend puts the state in your account. A managed service puts it in theirs. A breach of the managed service exposes your state.
  • Provider provenance. Both Terraform and OpenTofu download providers from their respective registries. Pinning provider sources and hashes is the control. The provider-registry is a supply-chain dependency; treat it as one.
  • Audit log retention. Most managed services retain the log for a contractual window; you may need longer for regulated workloads. Self-hosting gives you full control of retention.
  • Secrets in plan output. Both Terraform and OpenTofu can print secret values in the plan if the value is not sensitive = true. The setting is the same regardless of backend.

Performance implications

  • Remote runs scale with concurrency. Terraform Cloud caps the number of concurrent applies per organisation. Large estates may exceed the cap; the limit must be considered during adoption.
  • Self-hosted backends scale with your infrastructure. S3 plus DynamoDB scales to thousands of state files; the operational cost is consistent.
  • Crossplane scales with Kubernetes. Crossplane runs in the cluster; if the cluster is constrained, the IaC is constrained.
  • Pulumi runs in your language runtime. The same HCL equivalent may be slower; this is rarely a real constraint.

What comes next

The next lesson is reproducibility — the property that turns IaC from a notation into a recoverable system. The mechanics (provider locking, immutable module sources, the .terraform.lock.hcl file) make or break a team’s ability to recreate a production environment at 03:00.

Verification

A tooling choice is a commitment. The verification asks whether the commitment has been examined. Five checks, executed once on each new IaC adoption and at contract renewal.

# READ-ONLY: the exit path. Can a fresh engineer recreate
# the state outside the chosen service?
terraform state pull > /tmp/state-export.json
# Apply the export against a local backend in a clean directory
# and verify the plan is empty. If the plan proposes any change,
# the exit path is broken.

# READ-ONLY: what data does the managed service hold that the
# team cannot recreate?
gh api /orgs/{org}/repos \
  | jq '.[] | select(.name | test("audit"))'

# READ-ONLY: the per-environment cost at scale.
gh api /repos/{owner}/{repo}/issues \
  --paginate --jq '.total_count'

# READ-ONLY: who owns the renewal review?
gh api /repos/{owner}/{repo}/topics \
  | jq 'if .names | contains(["vendor-renewal"]) then "tagged" else "no tag" end'

# READ-ONLY: which features are operational requirements?
# An inventory of features in use, by environment.
terraform output -json | jq 'keys'

If any check returns “unknown,” the tooling decision is not yet defensible. The decision is at the disposal of opinion, not evidence. Document each answer before the next commitment to a managed-service renewal.

Knowledge check · 7 questions

  1. Q1. Which capability does Terraform Cloud provide that OSS Terraform does not?

  2. Q2. Which IaC tool uses general-purpose languages like TypeScript, Go, and Python as its authoring surface?

  3. Q3. OpenTofu is a closed-source fork of Terraform 1.5.

  4. Q4. Which criteria matter when picking an IaC tool? (Select all that apply.)

  5. Q5. Where does most of the lock-in for Terraform Cloud actually live?

  6. Q6. A regulated bank must adopt an IaC tool. The platform team proposes Terraform Cloud for the audit log. The security team pushes back on a third-party holding state. What is the right resolution?

  7. Q7. A team already standardises on Kubernetes for application orchestration. Which IaC tool aligns with the platform?

Passing score: 75%. Answers are checked in this browser.