Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/workflows/opentofu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ on:
description: "Args passed to `tofu init -backend-config=...` (newline-separated)"
type: string
default: ""
init-backend:
description: |
Initialise the backend during `tofu init`. Set false to pass
`-backend=false`, which initialises providers and modules only.

Needed for fmt/validate-only jobs on a configuration whose
`backend` block requires credentials the job has no business
holding — an S3/R2 backend, for example, where a bare `tofu init`
fails with "No valid credential sources found" before `validate`
ever runs. Mutually exclusive with run-plan, which needs state.
type: boolean
default: true
var-file:
description: "Optional .tfvars file to pass to plan"
type: string
Expand Down Expand Up @@ -99,9 +111,20 @@ jobs:
if: inputs.run-fmt
run: tofu fmt -check -recursive

# Fail here rather than three steps later with a confusing state
# error: `plan` needs the backend that `init-backend: false` skipped.
- name: Check input combination
if: ${{ !inputs.init-backend && inputs.run-plan }}
run: |
echo "::error::init-backend: false skips backend init, so tofu plan cannot run. Set run-plan: false, or give this job backend credentials." >&2
exit 1

- name: tofu init
run: |
ARGS="-input=false"
if [ "${{ inputs.init-backend }}" != "true" ]; then
ARGS="$ARGS -backend=false"
fi
if [ -n "${{ inputs.backend-config }}" ]; then
while IFS= read -r line; do
[ -z "$line" ] && continue
Expand Down
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ project uses [SemVer](https://semver.org/) for the `vMAJOR.MINOR.PATCH` tags.

## [Unreleased]

### Added

- `opentofu.yml` — `init-backend` input (boolean, default `true`). Set it to
`false` to run `tofu init -backend=false`, initialising providers and
modules without touching the backend.

Needed by any consumer whose configuration has a `backend` block requiring
credentials that a lint-only job has no business holding. A bare
`tofu init` against an S3/R2 backend fails with *"No valid credential
sources found"* before `validate` ever runs, so a fmt/validate job that was
green with local state goes red the moment a backend block lands. That is
exactly what `hordialabs/platform` hit moving its state to Cloudflare R2.

```yaml
uses: nkg/github-actions/.github/workflows/opentofu.yml@v3
with:
run-plan: false
init-backend: false # fmt + validate only; no state credentials in CI
```

Mutually exclusive with `run-plan`, which needs state — setting both now
fails fast with an explicit error rather than a confusing one from `plan`.
Default `true` keeps every existing caller byte-identical.

## [3.1.0] - 2026-08-30

### Changed
Expand Down
15 changes: 15 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,21 @@ jobs:
tofu-version: "1.8.0"
```

Lint-only, on a stack whose `backend` block needs credentials CI does not
hold (an S3/R2 backend, say). Without `init-backend: false`, `tofu init`
fails with *"No valid credential sources found"* before `validate` runs:

```yaml
jobs:
validate:
uses: nkg/github-actions/.github/workflows/opentofu.yml@v3
with:
working-directory: tofu/proxmox
use-mise: true
run-plan: false
init-backend: false
```

## Docker → GHCR

```yaml
Expand Down
Loading