FIELD GUIDE 21Infrastructure and security

opentofu / opentofu

OpenTofu keeps infrastructure declarative, inspectable and openly governed

The fork preserved a familiar configuration, provider and state model, then placed its future under community governance. The result is useful only when teams treat plans and state as serious operational assets.

WHAT TO KNOW FIRST

  1. OpenTofu configuration describes a dependency graph, while providers translate that graph into API operations against real systems.
  2. State is sensitive operational data and a coordination mechanism. Its storage, locking, backup and access policy are part of the architecture.
  3. MPL-2.0 is file-level copyleft, not a promise that every provider, module or dependency carries the same license. Review each distributed component separately.

01The fork is only the beginning of the story

OpenTofu is an infrastructure-as-code tool hosted by the Linux Foundation. Its configuration language, plan-and-apply workflow, provider protocol and state model are intentionally familiar to Terraform users. That continuity matters because organizations have accumulated modules, providers, automation and training around those concepts. The repository is not trying to replace declarative infrastructure with a new abstraction. It is continuing that operating model under an open governance and licensing path.

A useful review should therefore separate interface familiarity from permanent identity. OpenTofu documents compatibility goals, but it is an independently developed project with its own releases and roadmap. Compatibility reduces migration friction; it does not mean two projects must produce identical behavior forever. Teams evaluating a move should test the modules, providers, state operations and automation they actually use. The right question is not whether every configuration looks familiar. It is whether the exact production workflow remains predictable under a pinned OpenTofu release.

02Configuration is a graph, not a script

OpenTofu configuration declares resources, data sources, input variables, local values, outputs and module calls. References between those objects establish dependencies. OpenTofu uses that graph to determine ordering and parallel work, rather than expecting authors to write a procedural sequence of API commands. This is the key benefit of the language. A configuration states relationships and desired arguments, while the tool and providers work out which operations are required to move from the recorded state toward the new configuration.

The graph model also explains why seemingly small expressions matter. A reference can create an implicit dependency. A hard-coded string may hide one. Lifecycle settings can change replacement behavior. Conditional and collection expressions can expand a compact block into many resource instances whose addresses must remain stable over time. Good modules make important dependencies visible and keep resource addresses predictable. Clever expressions that save a few lines can make a plan much harder to review, especially when a later refactor changes keys or moves resources between modules.

03Plan output is a review artifact, not an oracle

The planning step compares configuration, prior state and data returned through providers to propose actions. It can show creation, in-place update, replacement and deletion before the tool asks an API to perform them. Saved plans also let automation apply the exact plan artifact that passed review. This is a substantial improvement over reviewing a script whose real effects are revealed only during execution.

A plan is still bounded by provider behavior and the information available at planning time. APIs can reject a request, apply defaults, change between plan and apply or perform side effects that the text summary cannot fully communicate. Unknown values may remain until apply. External actors can modify infrastructure after the refresh. Sensitive values can enter logs or state even when terminal output marks them as sensitive. Reviewers should treat the plan as the best available proposal, verify destructive actions carefully and keep rollback or recovery procedures appropriate to the resource being changed.

04State is the part teams cannot hand-wave

State maps resource addresses in configuration to remote objects and records values needed for later comparison. Without that mapping, OpenTofu would not know that a block corresponds to an existing network, database or identity object. State also supports dependency evaluation and can improve planning performance. It is not a disposable cache. Losing or corrupting it can force careful import and recovery work, while allowing two writers to update it without coordination can produce conflicting decisions.

The official state documentation warns that state can contain sensitive data. A backend decision is therefore a security and availability decision. Shared teams need controlled access, encryption appropriate to the backend, locking where supported, versioning or backup, and a recovery procedure. Local state may be acceptable for a disposable personal example but is a poor default for shared production resources. Workspaces or separate backends can partition environments, yet they do not replace a deliberate boundary between accounts, credentials and blast radii.

  • Do not commit live state or state backups to an ordinary source repository.
  • Make the backend and lock behavior explicit before the first shared apply.
  • Test state recovery and import on low-risk resources before an incident makes them urgent.

05Providers are both the reach and the risk

Providers implement resource types and data sources for external APIs. The dependency lock file records selected provider packages and checksums, while required-provider declarations identify sources and version constraints. This ecosystem gives OpenTofu access to clouds, software services and infrastructure systems without placing every integration in the core repository. It also means that the quality, release cadence and licensing of a provider can differ from OpenTofu itself.

Provider upgrades deserve the same care as application dependencies. A new version can change schema, defaults, validation or behavior around replacement. Broad version constraints may introduce those changes during routine initialization. Overly narrow constraints can block security or compatibility fixes. The practical middle ground is to declare intentional constraints, commit the dependency lock file where the official workflow supports it, review upgrade notes and produce a plan in a representative environment before changing the version used by production automation.

06Modules create leverage only with a stable interface

A module packages related resources behind input variables and outputs. A well-designed module can encode naming, tagging, identity, network and observability requirements once, then let application teams request a supported pattern. The public registry provides a distribution path for providers and modules, while private organizations can maintain their own controlled sources. Reuse is valuable when it removes repeated policy decisions and creates an upgrade path.

A module can also become a rigid internal product with an undocumented migration burden. Every exposed variable becomes part of an interface. Every hidden resource can surprise a caller during replacement. Deeply nested modules make plans difficult to interpret and complicate provider configuration. Prefer small modules with a clear purpose, typed and validated inputs, useful outputs and documented upgrade notes. Test changes against consumers, and avoid publishing a module merely because several resource blocks happen to appear together.

07Automation must preserve the review boundary

OpenTofu fits continuous integration because its commands can format, validate, initialize, plan and apply through a repeatable workflow. A sound pipeline separates untrusted proposal code from credentials that can change infrastructure. Pull requests can run formatting and validation with limited access. A plan stage can use carefully scoped credentials and preserve its output for review. Apply can require approval and should use the reviewed revision and plan, not silently recompute different changes from a moving branch.

Concurrency control, environment protection and audit records matter as much as command syntax. Two accepted pull requests can each have a valid plan against the same starting point and conflict when applied in sequence. A long-lived plan can become stale. An interrupted apply can leave some remote operations complete. Pipelines should serialize changes where needed, refresh after prior applies and surface partial failure without pretending the whole transaction rolled back. Infrastructure APIs rarely provide one universal atomic transaction across all resources.

08MPL 2.0 and open governance need exact language

The OpenTofu repository is licensed under Mozilla Public License 2.0. MPL is a file-level copyleft license. Its terms distinguish covered source files and modifications from separate files, and its notice and source-availability obligations matter when covered software is distributed. It is neither the permissive MIT license nor the broader network copyleft of AGPL. Organizations embedding or distributing modified OpenTofu should read the actual license and obtain legal advice for their specific distribution model.

The core license does not automatically govern every downloaded provider, module or third-party dependency. Those artifacts need their own review. Governance also should not be reduced to a slogan. The repository exposes issue, contribution, security and release processes that let adopters evaluate how decisions are made. For most teams, the practical benefit is the ability to inspect the implementation, track public changes and pin an openly licensed core. That still requires normal dependency management and a tested upgrade policy.

09The best adoption starts with one bounded system

OpenTofu earns its place when infrastructure changes recur, several people need a shared review trail and the target APIs are represented by maintained providers. Start with a bounded environment whose owners understand the underlying platform. Capture the current resource shape, choose the state backend, import existing objects carefully if necessary, then make one small change. This reveals provider behavior and organizational review gaps without putting the entire estate behind a new tool on day one.

It is less helpful when a platform's native declarative service already provides a simpler lifecycle, or when a team expects the tool to compensate for unclear ownership. Infrastructure as code makes decisions repeatable and visible; it does not decide the architecture, create missing backups or guarantee that deletion is reversible. The repository provides a capable engine. The quality of the result depends on module boundaries, state stewardship, provider discipline and the humans who approve the plan.

A SENSIBLE FIRST HOUR

Start small enough to learn the repo

  1. Install a released OpenTofu binary using an official method, then read the configuration language introduction before copying a large example from elsewhere.
  2. Create a disposable directory with one low-risk resource or a local-only example. Pin the required OpenTofu and provider versions in configuration.
  3. Run initialization, inspect the generated dependency lock file, produce a saved plan and read every proposed action before applying it.
  4. Destroy the disposable resource, inspect what remains in state, then decide where team state, locking, credentials and review will live before adopting the tool for shared infrastructure.

SOURCE LEDGER

What this review is built on

We use the project repository and first-party documentation. Access, licenses and project direction can change, so recheck the linked source before making a production decision.

  1. opentofu/opentofu repositoryrepository
  2. OpenTofu documentationdocumentation
  3. OpenTofu state documentationdocumentation
  4. OpenTofu releasesrelease
  5. Mozilla Public License 2.0license