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
25 changes: 12 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ FROM debian:${DEBIAN_VERSION} as terraform
ARG TARGETARCH
ARG TERRAFORM_VERSION
RUN apt-get update
# RUN apt-get install --no-install-recommends -y libcurl4=7.74.0-1.3+deb11u7
RUN apt-get install --no-install-recommends -y ca-certificates=20230311
RUN apt-get install --no-install-recommends -y curl=7.88.1-10+deb12u4
RUN apt-get install --no-install-recommends -y gnupg=2.2.40-1.1
RUN apt-get install --no-install-recommends -y ca-certificates=20230311+deb12u1
RUN apt-get install --no-install-recommends -y curl=7.88.1-10+deb12u14
RUN apt-get install --no-install-recommends -y gnupg=2.2.40-1.1+deb12u2
RUN apt-get install --no-install-recommends -y unzip=6.0-28
WORKDIR /workspace
RUN curl --silent --show-error --fail --remote-name https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_${TARGETARCH}.zip
Expand All @@ -27,12 +26,12 @@ RUN unzip -j terraform_${TERRAFORM_VERSION}_linux_${TARGETARCH}.zip
FROM debian:${DEBIAN_VERSION} as aws-cli
ARG AWS_CLI_VERSION
RUN apt-get update
RUN apt-get install -y --no-install-recommends ca-certificates=20230311
RUN apt-get install -y --no-install-recommends curl=7.88.1-10+deb12u4
RUN apt-get install -y --no-install-recommends gnupg=2.2.40-1.1
RUN apt-get install -y --no-install-recommends ca-certificates=20230311+deb12u1
RUN apt-get install -y --no-install-recommends curl=7.88.1-10+deb12u14
RUN apt-get install -y --no-install-recommends gnupg=2.2.40-1.1+deb12u2
RUN apt-get install -y --no-install-recommends unzip=6.0-28
RUN apt-get install -y --no-install-recommends git=1:2.39.2-1.1
RUN apt-get install -y --no-install-recommends jq=1.6-2.1
RUN apt-get install -y --no-install-recommends git=1:2.39.5-0+deb12u3
RUN apt-get install -y --no-install-recommends jq=1.6-2.1+deb12u1
WORKDIR /workspace
RUN curl --show-error --fail --output "awscliv2.zip" --remote-name "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-${AWS_CLI_VERSION}.zip"
COPY security/awscliv2.asc ./
Expand All @@ -47,10 +46,10 @@ FROM debian:${DEBIAN_VERSION} as build
LABEL maintainer="bgauduch@github"
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates=20230311\
git=1:2.39.2-1.1 \
jq=1.6-2.1 \
openssh-client=1:9.2p1-2+deb12u1 \
ca-certificates=20230311+deb12u1 \
git=1:2.39.5-0+deb12u3 \
jq=1.6-2.1+deb12u1 \
openssh-client=1:9.2p1-2+deb12u10 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /workspace
Expand Down
65 changes: 65 additions & 0 deletions docs/adr/0010-apt-package-pinning-strategy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# 0010 — APT package pinning strategy

- Status: Accepted
- Date: 2026-06-15
- Deciders: @bgauduch

## Context and problem statement

The Dockerfile pins every OS package to an exact version
(`ca-certificates=20230311+deb12u1`, `curl=7.88.1-10+deb12u14`, …). Debian
removes superseded point-release versions from the `bookworm` mirror, so a stale
pin eventually disappears and the build fails with `apt-get … exit code 100`.
This broke `build-test` (the pin `ca-certificates=20230311` had been superseded
by `…+deb12u1`). The question is whether to keep pinning, drop pins, or freeze
the mirror.

## Decision drivers

- Reproducibility and supply-chain integrity of the image.
- Predictable, reviewable dependency changes.
- Acceptable maintenance for a low-traffic project.

## Considered options

- **Keep exact version pins** and refresh them when Debian supersedes a version
(or on base-image bumps).
- **Unpin** the OS utility packages (rely on the stable suite). *Rejected — loses
reproducibility and makes dependency changes invisible.*
- **`snapshot.debian.org`** as a frozen apt source so exact pins never disappear.

## Decision outcome

Chosen option: **keep exact version pins** for all OS packages
(`ca-certificates`, `curl`, `gnupg`, `unzip`, `git`, `jq`, `openssh-client`),
with `--no-install-recommends`. Pins are **refreshed** when a build breaks on a
superseded version or when the base image is bumped — the procedure is documented
in [`docs/dependencies-upgrades.md`](../dependencies-upgrades.md).

Unpinning was explicitly rejected: the bundled tools (Terraform, AWS CLI) are
already pinned + GPG/checksum-verified, and keeping the OS packages pinned too
keeps the whole image reproducible and every change explicit in the diff.

**`snapshot.debian.org`** is recorded as the path to make pins *never* break
(fully reproducible builds); it is deferred to a future ADR/PR rather than
adopted now, to keep this change minimal.

### Consequences

- Good: reproducible, explicit dependencies; supply-chain integrity preserved.
- Cost: pins must be refreshed periodically (when Debian supersedes a version) —
a manual step today, a candidate for a Renovate custom manager later (#20).
- Lint: hadolint `DL3008` stays **enforced** (pinning required).

## More information

Pin values are read with:

```bash
docker run --rm debian:bookworm-slim bash -c \
'apt-get update -qq && for p in ca-certificates curl gnupg unzip git jq openssh-client; do \
printf "%s=%s\n" "$p" "$(apt-cache policy "$p" | awk "/Candidate:/{print \$2}")"; done'
```

The bundled-binary verification chain is unchanged
([`docs/binaries-verifications.md`](../binaries-verifications.md)).
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,4 @@ Phase 6) will scaffold this automatically.
| [0007](0007-adopt-entire-checkpoints.md) | Adopt Entire / Checkpoints for agent-session capture | Proposed |
| [0008](0008-conventional-branch-naming.md) | Conventional branch naming | Accepted |
| [0009](0009-agent-agnostic-framework.md) | Agent-agnostic framework with a tool-specific adapter layer | Accepted |
| [0010](0010-apt-package-pinning-strategy.md) | APT package pinning strategy | Accepted |
9 changes: 8 additions & 1 deletion docs/dependencies-upgrades.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Supported tools versions:
* [Report to the doc](https://github.com/zenika-open-source/terraform-aws-cli/tree/master/docs/binaries-verifications.md) to add required security files (stored under `security/`, e.g. `security/hashicorp.asc`) when adding a new supported versions
* check available **AWS CLI** version on the [project release page](https://github.com/aws/aws-cli/tags)
* check available **Terraform CLI** version (keep all minor versions from 0.11) on the [project release page](https://github.com/hashicorp/terraform/releases)
* check available **Terraform CLI** version (keep one patch per minor, from 1.0 — see ADR-0004) on the [project release page](https://github.com/hashicorp/terraform/releases)
* Dockerfile:
* check **base image** version [on DockerHub](https://hub.docker.com/_/debian?tab=tags&page=1&name=bookworm)
* check OS package versions on Debian package repository
Expand All @@ -16,6 +16,13 @@
* Available **curl** versions on the [Debian Packages repository](https://packages.debian.org/search?suite=bookworm&arch=any&searchon=names&keywords=curl)
* Available **gnupg** versions on the [Debian Packages repository](https://packages.debian.org/search?suite=bookworm&arch=any&searchon=names&keywords=gnupg)
* Available **unzip** versions on the [Debian Packages repository](https://packages.debian.org/search?suite=bookworm&arch=any&searchon=names&keywords=unzip)
* OS packages are **pinned to exact versions** in the Dockerfile (see ADR-0010). When a build fails with `apt-get ... exit code 100`, a pin was superseded by Debian — refresh **all** pins to the current candidates, then update the Dockerfile **and** the matching version assertions in [`tests/container-structure-tests.yml.template`](tests/container-structure-tests.yml.template) (e.g. the git/jq/openssh versions):

```bash
docker run --rm debian:bookworm-slim bash -c \
'apt-get update -qq && for p in ca-certificates curl gnupg unzip git jq openssh-client; do \
printf "%s=%s\n" "$p" "$(apt-cache policy "$p" | awk "/Candidate:/{print \$2}")"; done'
```
* Dockerfile tests : update version according to changes in Dockerfile in [tests/container-structure-tests.yml.template](tests/container-structure-tests.yml.template)
* Github actions:
* check [runner version](https://github.com/actions/virtual-environments#available-environments)
Expand Down
1 change: 1 addition & 0 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ Code) (Phase 2).
| Dependency bot | **Renovate only** (Dependabot retired) | ADR-0002 |
| ADR format | MADR (Nygard considered, rejected for simplicity) | ADR-0005 |
| Terraform deprecation | Drop versions `< 1.0` from `supported_versions.json` | ADR-0004 |
| APT package pinning | OS utility packages unpinned (stable suite); bundled binaries stay pinned + GPG/checksum verified | ADR-0010 |
| Rollback policy | No mutation of immutable full tags; consumers re-pin an older tag | `docs/rollback.md` |
| ADR enforcement | PR-template checkbox + `adr-check.yml` CI gate + CODEOWNERS (no soft-rule-only) | this doc |
| Branch naming | `type/topic` (Conventional types), `type/phase-N-topic` for phases; no tool names | ADR-0008 |
Expand Down
2 changes: 1 addition & 1 deletion tests/container-structure-tests.yml.template
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ commandTests:
- name: "Check Git version"
command: "git"
args: ["--version"]
expectedOutput: ["git version 2.39.2"]
expectedOutput: ["git version 2.39.5"]

- name: "Check JQ version"
command: "jq"
Expand Down
Loading