OpenTofu module standard
Every foundations module, and the bootstrap module, passes this checklist.
1. Structure
Section titled “1. Structure”- One flat root module per cloud at
opentofu/<cloud>/, nomodules/. Verify:ls opentofu/*/. -
main.tf,variables.tf,outputs.tf,versions.tf, plus topic files. Verify: review. - A minimal example (foundations modules; the bootstrap is shown by the roots). Verify:
test -d opentofu/<cloud>/examples/minimal. - Tests. Verify:
test -d opentofu/<cloud>/tests. - OpenTofu 1.13 or later, for anonymous OCI module init. Verify:
required_version = ">= 1.13".
2. Interface
Section titled “2. Interface”- Every variable typed; a bare
anysays why in a comment. Verify: review. - Constraints in
validationblocks. Verify: atofu testcase asserts the rejection. - Defaults are the recommended positions. Verify: the example sets only per-consumer values.
-
nullable = falseon every defaulted variable, unless the default is null. Verify: review. - No default where none is good; a silent default means nobody decided. Verify: review against the decisions.
- Options we would not recommend are absent. Verify: review against the decisions.
- Names consistent across clouds. Verify: diff
opentofu/*/variables.tf. - Outputs for the bootstrap: endpoint, CA,
helm_kubernetes(an exec), the workload identity binding, the in-cluster provider’s identity. Verify:tofu outputon the example.
3. Quality and security
Section titled “3. Quality and security”-
tofu fmtandtofu validateclean. Verify:pr-static.yaml. - TFLint with the cloud’s plugin. Verify:
test -f opentofu/<cloud>/.tflint.hcl, gated in CI. - Generated docs current. Verify:
terraform-docs markdown . --output-check. - No HIGH or CRITICAL Trivy finding; each ignore states its reason. Verify:
pr-static.yaml. - No committed secret, no credential variable: ambient credentials or workload identity.
Verify:
trivy fs --scanners secret .and review.
4. Tests
Section titled “4. Tests”- Unit:
tofu test, no Go: validations, defaults, conditional logic. Verify:tofu testpasses. - Every
validationhas a test that trips it. Verify: review. - Integration: a plan against an emulator (
integration.yaml: floci, floci-gcp, floci-az; Scaleway offline; Azurecontinue-on-error). Verify: green, or the summary says why. - Convergence: an apply on floci’s k3s (
e2e.yaml), ending intofu destroy; AWS only today. Verify: thee2echeck is green. - A leg that cannot apply says why in the run summary. Verify: review.
5. Versioning and distribution
Section titled “5. Versioning and distribution”- SemVer: removing a variable, renaming an output or forcing replacement is breaking
(the minor before 1.0.0). Verify: the commit type (
!orBREAKING CHANGE:). -
local.socle_versionannotated# x-release-please-version. Verify:.github/scripts/check-version.sh. - Published as a cosign-signed OCI package. Verify:
tofu initfrom a clean cache. - Consumers pin by
?tag=${var.socle_version}and runcosign verifybeforeinit(Artifacts). Verify: the consumer docs carry it. - Renovate moves provider and action versions. Verify:
renovate.json.
6. Compatibility with automation
Section titled “6. Compatibility with automation”- No
backendblock; the state is the consumer’s. Verify: review; the example documents one. - One
tofu applyconverges, no input, no manual step; exceptions in the README. Verify: CI applies with-input=false -auto-approve. - Runs from an isolated CI runner with only the roles it needs. Verify: the example lists them.
- Idempotent. Verify:
tofu plan -detailed-exitcodeafter the apply is empty.