Propagate OpenTofu outputs to downstream jobs as dotenv variables
What
Lets you propagate OpenTofu outputs to downstream CI jobs as environment variables, via a artifacts:reports:dotenv report.
Opt-in, defaults off. Implemented as gitlab-tofu-ctl outputs-to-dotenv behind a new gitlab-tofu output-dotenv command.
Why
Chaining apply outputs into a downstream job currently means hand-rolling jq against a JSON artifact. A dotenv report makes the outputs directly available as variables in later jobs.
Design decisions
Sensitive outputs are excluded by default. tofu output -json includes values marked sensitive, and dotenv values are readable in the UI/API and inherited downstream. There is an explicit opt-out only. Values are also piped rather than held in a shell variable, because GITLAB_TOFU_DEBUG enables xtrace and would otherwise print every value into the job log — there is a test asserting a sensitive value reaches neither the report nor stdout/stderr.
Name transformation: [^A-Za-z0-9_] → _, case preserved. Verified against GitLab's actual constraint (Ci::HasVariable, /\A[a-zA-Z0-9_]+\z/, max 255) and OpenTofu's identifier rules. Case is deliberately not upper-cased so that lower snake_case outputs cannot shadow PATH or CI_* downstream.
Collisions are a hard error naming both outputs, rather than silently picking one. This happens after a successful apply, so no infrastructure change is lost and re-running after a rename is safe.
Values: strings raw; numbers/bools as JSON literals (no float64 precision loss); lists/maps as compact JSON. Multi-line strings and null are skipped with a warning, not fatally — GitLab rejects the entire report on one multi-line value, so failing hard would drop every other output.
Documented GitLab limits (verified in the GitLab source, not from memory): dotenv_size default 5120 bytes, dotenv_variables default 20 self-managed / 50-150 on GitLab.com by tier.
Testing
- 16 Go subtests, including the sensitive-value leak test.
tests/integration-tests/DotenvOutputs.gitlab-ci.yml+tests/iac-dotenv-outputs/fixture, asserting an output actually arrives in a downstream job.- 1 new bats case;
shellcheckclean;make docsidempotent.
Depends on !556 (merged)
The Go tests here will not run in CI until !556 (merged) (which adds the missing go:test:gitlab-tofu-ctl job) is merged. Please merge !556 (merged) first.
Pre-existing gap, deliberately not fixed here
validate-plan-apply.yml's child-pipeline trigger never forwarded apply_artifacts_access, apply_save_outputs_as_artifact or apply_output_artifact_name. The inputs added by this MR are forwarded; fixing the existing three is handled separately.