OpenTofu & Pulumi
The fork, and IaC in real languages.
Terraform is the default, but two alternatives matter enough to know. OpenTofu is an open-source fork of Terraform, created in 2023 after HashiCorp changed Terraform’s license from fully open-source to the more restrictive BSL. OpenTofu is managed by the Linux Foundation, is a near drop-in replacement (same HCL, same providers, same workflow), and exists to keep a truly open, community-governed version available. For most purposes the concepts and code are identical — the difference is licensing and governance, which for some organizations is decisive.
# OpenTofu is a drop-in: same HCL, same commands, just "tofu" instead of "terraform"$ tofu init$ tofu plan$ tofu apply# your existing .tf files, providers, and state work unchanged
Why the fork happened, and why it matters
HashiCorp relicensed Terraform under the Business Source License, which restricts commercial use in ways the fully-open MPL did not. The community forked the last open version as OpenTofu to preserve an unrestricted, foundation-governed tool. Practically: if your organization is sensitive to the BSL terms (many vendors and some enterprises are), OpenTofu is the open alternative with essentially the same experience; if not, Terraform remains fine. Either way, the HCL skills and mental models you are learning transfer completely — they are the same tool at the level that matters here.
Pulumi: IaC in real languages
Pulumi takes a different approach: instead of a dedicated language like HCL, you write infrastructure in a general-purpose programming language — TypeScript, Python, Go, C#. That means real loops, functions, classes, and your language’s testing and tooling, which can be powerful for complex or highly-dynamic infrastructure and appealing to teams who would rather write code than learn HCL. The tradeoff: the full power of a programming language is also full complexity, and it is easier to write clever, hard-to-review infrastructure. It still uses state and a plan/apply model — the concepts you know carry over.
import * as aws from "@pulumi/aws";// real language: a loop creates three buckets — no HCL count/for_each dancefor (const env of ["dev", "staging", "prod"]) {new aws.s3.Bucket(`data-${env}`, { tags: { Environment: env } });}