Article summary
Want to get further ? Ask AI :
Terraform is easy to start. One engineer, one repository, one terraform apply. The trouble begins when ten teams use it on three clouds: copied modules that no longer match, state files nobody dares touch and production changes applied from someone's laptop.
None of this is a Terraform problem. It is a governance problem. This guide sets out the rules that let large teams use infrastructure as code without losing control.
Why Terraform gets messy as teams grow
The symptoms are always the same:
- Each team writes its own version of the same network or database module.
- One huge state file holds hundreds of resources, so every plan is slow and every apply is risky.
- Nobody knows whether production still matches the code.
- Security rules live in a wiki, not in the pipeline, so they are checked late or not at all.
The fix is a small set of standards, enforced by tooling rather than by goodwill.
Rule 1: choose your engine, then standardize
Since August 2023, Terraform has been distributed under the Business Source License (BUSL 1.1) instead of an open-source license. IBM completed its acquisition of HashiCorp in February 2025. The community fork, OpenTofu, stayed under the open-source MPL 2.0 license and was accepted into the Cloud Native Computing Foundation in April 2025.
The two tools have since diverged. OpenTofu added features such as client-side state encryption. HashiCorp's commercial offering added Terraform Stacks to orchestrate many configurations together.
For most companies that use Terraform internally, the license change has little practical effect. Check it with your legal team if you build products on top of Terraform. Whichever you choose, the rule is the same: one engine, one pinned version range, across all teams. Mixing both in one estate doubles your testing and support work.
Rule 2: treat modules as products
Shared modules are where scale pays off, or falls apart.
- Publish modules to a private registry instead of copying folders between repositories.
- Version them with semantic versioning, and let teams upgrade on purpose, not by accident.
- Encode your standards in them. A "database" module that always enables encryption, backups and tagging removes a whole class of review comments.
- Test them. Use the built-in
terraform testframework or your own pipeline to check that a module still deploys before you release a new version. - Keep them small. A module that tries to build an entire environment becomes impossible to change.
Rule 3: split state by blast radius
The state file is Terraform's memory. Lose it or corrupt it and Terraform no longer knows what it manages.
- Remote state only. Never keep state on a laptop or in Git. Use a remote backend with encryption and versioning.
- Locking on. Two applies on the same state at the same time corrupt it. Recent Terraform versions support native locking in the S3 backend; the older DynamoDB-based locking is deprecated.
- Small states. Split by environment and by layer: network, shared services, then applications. A mistake in an application stack should never be able to touch the network.
- Restricted access. State files can contain secrets. Only the pipeline should write to production state.
Rule 4: policy as code, before deployment
A security rule that is checked after deployment is an incident report. Check it in the pipeline instead, on every plan.
- Static scanning with tools such as Checkov or Trivy catches common misconfigurations: public storage, open security groups, missing encryption.
- Organization-specific rules written with Open Policy Agent (OPA) or, on HCP Terraform, Sentinel: allowed regions, mandatory tags, approved instance types, cost limits.
- Clear levels: some rules warn, others block. Start with warnings, measure, then make the important ones blocking.
This is also how you turn NIS2 or DORA requirements into something you can prove: every change was checked against the same written rules.
Rule 5: a pipeline for every change
Production changes should follow one path:
- A pull request triggers a
terraform plan. - The plan and the policy results are posted on the pull request.
- A second person reviews and approves.
- The pipeline, not a person, runs
applywith its own short-lived credentials.
Run a scheduled plan on each production state as well. If it shows changes nobody requested, someone changed the infrastructure outside Terraform. Drift found early is a ticket. Drift found during an incident is a crisis.
Rule 6: keep secrets out of code and state
Do not write passwords or API keys in variables files. Read them from a secrets manager at runtime, mark them as sensitive and use ephemeral values where your version supports them, so they are not stored in state.
Give pipelines short-lived cloud credentials through OpenID Connect federation rather than long-lived access keys stored as CI variables.
Beyond cloud resources
The same approach works for the rest of your platform. Identity, DNS, monitoring and API gateways can be managed as code too. Kong, for example, provides a Terraform provider for its Konnect platform, so API gateway configuration can go through the same review and policy checks as your cloud infrastructure.
A checklist for your next Terraform review
- One engine and one pinned version range across teams.
- Shared modules in a private registry, versioned and tested.
- Remote, encrypted, versioned state with locking enabled.
- State split by environment and by layer.
- Policy checks on every plan, with blocking rules for critical risks.
- Production applies only from the pipeline, after review.
- Scheduled drift detection on production.
- No secrets in code, variables files or state.
- Short-lived pipeline credentials through OIDC.
Next step
Infrastructure as code only pays off when it is governed. With the six rules above, Terraform becomes a control: every change is reviewed, checked and traceable.
Want an outside view on your setup? Ask our infrastructure team for a Terraform review, or see how we approach cloud and infrastructure automation. Building a new AWS foundation? Start with our AWS landing zone guide.

[> convert_contact: true]
Lorem ipsum
dolor sit
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.

