ci: ansible and ansible-lint are still unpinned in the runner image bake #400

Öppen
öppnade 2026-08-06 08:59:22 +00:00 av supernaut · 0 kommentarer
Ägare

ansible and ansible-lint are installed into the runner image with no version:

# scripts/bake-runner-image.sh
pip install --break-system-packages ansible ansible-lint "ruff==${RUFF_VERSION}"

Every other tool baked into that image is pinned — RUNNER_VERSION, TOFU_VERSION, NODE_VERSION,
GITLEAKS_VERSION, and now RUFF_VERSION (#399). These two are what is left.

Why it matters, and why it is not urgent

Same failure shape as the ruff pin: CI runs whatever was newest on bake day, a version the repo
cannot name and no developer can reproduce. ansible-lint in particular adds rules between minor
releases
, so a re-bake can fail CI on unchanged code — and the reverse, a stale image quietly
accepting what a current lint would reject, is the worse direction.

It is less acute than ruff was for one reason: a re-bake is a deliberate, infrequent act, and the
image currently in use has been exercised by many green runs. The exposure is a future re-bake,
not today's CI.

Why it is not just "add a pin"

Unlike ruff, ansible is not only a linter. It is the thing that configures the entire estate, so
its version is coupled to:

  • collection compatibility (ansible/requirements.yml pins containers.podman, ansible.posix,
    community.general, community.crypto — a core bump can move the minimum each needs)
  • module behaviour the roles depend on, including check-mode semantics, which this repo has already
    had to reason about carefully (see the apply-reconcile tooling and the --check notes in the
    runbook)
  • the operator's LOCAL ansible, which is what actually applies to production — CI only lints

So pinning it without deciding which version, and re-running a full --check against both hosts
to confirm nothing moved, would trade an unknown for a differently-shaped unknown.

Suggested approach

  1. Record what the current image actually has (ansible --version, ansible-lint --version on a
    live runner) — that is today's de facto pin and the safest first value.
  2. Pin both to it, plumbed through the heredoc's sudo env like the others, with the same
    post-install assertion ruff now has.
  3. Decide separately whether the operator's local ansible should match, and say so in the runbook.
    They are different machines doing different jobs; forcing equality may not be wanted.
  4. Consider whether ansible-lint should get a wrapper like scripts/ruff.sh /
    scripts/shellcheck.sh so local and CI cannot disagree at all. It is the same class of tool.

Acceptance

  • Both pinned, asserted after install, and the assertion proven to fail on a wrong value.
  • A full site.yml --check against both hosts is unchanged at changed=0 on the pinned version.
`ansible` and `ansible-lint` are installed into the runner image with no version: ```bash # scripts/bake-runner-image.sh pip install --break-system-packages ansible ansible-lint "ruff==${RUFF_VERSION}" ``` Every other tool baked into that image is pinned — `RUNNER_VERSION`, `TOFU_VERSION`, `NODE_VERSION`, `GITLEAKS_VERSION`, and now `RUFF_VERSION` (#399). These two are what is left. ## Why it matters, and why it is not urgent Same failure shape as the ruff pin: CI runs whatever was newest on bake day, a version the repo cannot name and no developer can reproduce. `ansible-lint` in particular **adds rules between minor releases**, so a re-bake can fail CI on unchanged code — and the reverse, a stale image quietly accepting what a current lint would reject, is the worse direction. It is less acute than ruff was for one reason: a re-bake is a deliberate, infrequent act, and the image currently in use has been exercised by many green runs. The exposure is a *future* re-bake, not today's CI. ## Why it is not just "add a pin" Unlike ruff, `ansible` is not only a linter. It is the thing that configures the entire estate, so its version is coupled to: - collection compatibility (`ansible/requirements.yml` pins `containers.podman`, `ansible.posix`, `community.general`, `community.crypto` — a core bump can move the minimum each needs) - module behaviour the roles depend on, including check-mode semantics, which this repo has already had to reason about carefully (see the `apply-reconcile` tooling and the `--check` notes in the runbook) - the operator's LOCAL ansible, which is what actually applies to production — CI only lints So pinning it without deciding **which** version, and re-running a full `--check` against both hosts to confirm nothing moved, would trade an unknown for a differently-shaped unknown. ## Suggested approach 1. Record what the current image actually has (`ansible --version`, `ansible-lint --version` on a live runner) — that is today's de facto pin and the safest first value. 2. Pin both to it, plumbed through the heredoc's sudo env like the others, with the same post-install assertion `ruff` now has. 3. Decide separately whether the operator's local ansible should match, and say so in the runbook. They are different machines doing different jobs; forcing equality may not be wanted. 4. Consider whether `ansible-lint` should get a wrapper like `scripts/ruff.sh` / `scripts/shellcheck.sh` so local and CI cannot disagree at all. It is the same class of tool. ## Acceptance - Both pinned, asserted after install, and the assertion proven to fail on a wrong value. - A full `site.yml --check` against both hosts is unchanged at `changed=0` on the pinned version.
Logga in för att delta i denna konversation.
Ingen milstolpe
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-infra#400
Ingen beskrivning angiven.