Skip to content

Releases: arillso/ansible.container

2.0.0

Choose a tag to compare

@github-actions github-actions released this 16 Aug 22:02
cf4703b

[2.0.0] - 2026-08-16

Removed

  • Five unused helm variables: helm_target_groups, helm_target_host,
    helm_kubectl_context, helm_validation_timeout and helm_log_level are
    gone from roles/helm/defaults/main.yml and
    roles/helm/meta/argument_specs.yml. No task file in the role ever read
    them, so setting them changed nothing and produced no warning.
    helm_target_groups and helm_target_host were especially misleading: they
    suggested the role filters its own target hosts, which it does not — host
    selection belongs in the play (hosts:). Validation behaviour is unaffected:
    helm_validation_retries and helm_validation_delay are read by
    roles/helm/tasks/charts.yml, helm_validation_enabled by
    roles/helm/tasks/prerequisites.yml, and together they cover the validation
    flow.

Added

  • apt_version_pin filter plugin: resolves a version prefix to the full
    version string apt reports, replacing four hand-rolled Jinja regex copies in
    the docker and docker_compose_v2 roles. Documented in
    plugins/filter/DOCUMENTATION.yml and covered by
    tests/unit/plugins/filter/test_apt_filters.py.

  • Configurable fleet bundle readiness wait: fleet_bundle_wait (true)
    and fleet_bundle_wait_timeout (300) in roles/fleet/defaults/main.yml,
    both overridable per bundle via wait / wait_timeout on the item and
    declared in meta/argument_specs.yml. The "Manage Fleet Bundles" task
    previously applied each bundle with a hardcoded wait for Ready, so a serial
    loop over many bundles stacked up the 300s timeout per item. Stable bundles
    can now be applied fire-and-forget and let Fleet reconcile them
    asynchronously; the registered result shape is unchanged.

  • k3s container log rotation defaults: k3s_container_log_max_size
    (10Mi) and k3s_container_log_max_files (5) now have defaults in
    defaults/main.yml and entries in meta/argument_specs.yml. Both were
    previously only read by an is defined guard in the agent config template,
    so out of the box kubelet never received container-log-max-size /
    container-log-max-files and container logs grew unbounded. The guards stay
    in place, so setting k3s_container_log_max_size to "" or
    k3s_container_log_max_files to 0 still omits the respective flag.

  • k3s hardening variables: eight new variables defined in both
    defaults/main.yml and meta/argument_specs.yml
    k3s_secrets_encryption, k3s_protect_kernel_defaults,
    k3s_audit_log_enabled, k3s_audit_log_maxage, k3s_anonymous_auth,
    k3s_node_restriction, k3s_kubelet_read_only_port_disabled,
    k3s_audit_log_level and k3s_pod_security_admission_profile. All are gated
    by k3s_security_hardening, which previously only covered SELinux/AppArmor.

  • k3s audit policy: renders audit-policy.yaml and passes
    audit-policy-file to the kube-apiserver when audit logging is enabled.
    Without a policy file the apiserver matches no events and the audit log stays
    empty. Drops high-volume node/proxy and health-endpoint traffic, caps secrets
    and configmaps at Metadata, and logs everything else at
    k3s_audit_log_level.

  • k3s Pod Security Admission: optional cluster-wide default profile via
    k3s_pod_security_admission_profile (empty by default, so no behaviour
    change). Renders psa-config.yaml with kube-system exempt and wires it as
    admission-control-config-file.

  • k3s molecule hardening assertions: verify.yml checks the rendered
    config for the hardening flags, k3s secrets-encrypt status for Enabled,
    the credential directory for 0700, and that a user-supplied
    kube-apiserver-arg survives the hardening merge.

  • Molecule coverage for the five previously-untested roles, each with a
    default scenario under roles/<role>/molecule/default/ and a matching
    molecule-<role> job wired into pull-request.yml (qemu/KVM driver,
    Ubuntu 22.04 cloud image, pinned to ci-ansible-molecule.yml@2026-06-18).

  • docker_login molecule — full converge: a prepare.yml installs Docker via
    the docker role and starts a throwaway local registry:2 container,
    converge logs into localhost:5000, and verify asserts the registry appears
    under auths in the Docker client config.

  • docker_compose_v2 molecule — full converge: prepare.yml installs Docker,
    converge deploys a minimal nginx compose project, and verify asserts the
    compose plugin, the rendered project file, the systemd unit and a running
    container.

  • helm, fleet, tailscale molecule — full converge against an
    ephemeral k3s cluster. Each scenario gained a prepare.yml that installs
    arillso.container.k3s in the same QEMU VM and adds whatever upstream
    controller the role needs, so converge, idempotence and verify are now
    part of the test_sequence. No external cluster and no repository secret is
    involved, which keeps the jobs working on fork pull requests. These scenarios
    assert that the roles emit schema-valid resources the API accepts; they do not
    assert that the upstream controllers act on them.

  • helm molecule exercises the whole deployment chain: the role applies a
    HelmChart CR, the k3s Helm controller turns it into an install Job, and verify
    asserts the CR, the completed Job and the running Pod.

  • fleet molecule installs standalone Fleet (fleet-crd, then fleet) and
    asserts that the GitRepo and Bundle CRs the role emits are accepted by the
    fleet.cattle.io API with the expected spec and labels. Workspaces
    (Rancher-only management.cattle.io/v3), registration tokens (the controller
    rotates the secret) and clusters (need a second cluster's kubeconfig) stay out
    of the fixture.

  • tailscale molecule installs the operator chart with dummy OAuth
    credentials and without waiting for the Pod, which registers the
    tailscale.com CRDs without a real tailnet, then asserts the ProxyGroup the
    role creates.

Fixed

  • docker version pin never matched on the Debian family: apt matches an =
    pin against the full version string and does not expand globs in it, so the
    shipped docker_version default (docker-ce=28.5.2) was unusable on Debian
    and Ubuntu — apt reports the version with an epoch and a distro release
    suffix. install_docker_debian.yml and install_docker_ubuntu.yml now
    resolve the full version string on the host before pinning. Every existing
    docker scenario blanked docker_version, so the shipped default had never
    been exercised; a new pinned molecule scenario runs the role without that
    override and asserts the installed server version equals the pin.

  • docker_compose_v2 pin was built in one form for three package managers:
    apt needed the full version string it never got, and dnf does not know the
    pkg=version syntax at all, so every pinned run failed on a role that
    advertises Debian, Ubuntu and EL 9. The pin form now lives in
    per-distribution vars/ files, and the apt string is resolved on the host
    through the new apt_version_pin filter.

  • helm applied charts to only one host per play: charts.yml,
    prerequisites.yml and repositories.yml carried run_once, but each host
    the role targets is its own k3s cluster, so the HelmChart CRs reached a single
    host and left the other clusters empty. Removing run_once also unmasks the
    kubeconfig autodetection, which promised the first existing candidate but let
    the loop overwrite it down to the last; it now selects the first match in one
    pass.

  • helm_kubeconfig_path was undocumented and unvalidated: the role read it
    in 13 task lines, including as kubeconfig for every kubernetes.core call,
    but declared it in neither defaults/main.yml nor meta/argument_specs.yml.
    Both now declare it. The default stays empty, since prerequisites.yml only
    autodetects the path while the value is unset or empty.

  • lefthook could not lint without Galaxy access: the ansible-lint hook
    resolved the collections declared in the molecule requirements against
    galaxy.ansible.com, so a machine without Galaxy egress could not commit any
    file under the hook's glob and had to reach for --no-verify, which drops the
    gitleaks hook too. The hook now lints offline.

  • Renovate could not refresh the pinned nginx digest: the image: lines in
    roles/docker_compose_v2/molecule/default/converge.yml and verify.yml
    carried a # renovate: datasource=docker depName=nginx comment, which the
    comment manager from the shared renovate-base preset read as
    currentValue: nginx:alpine. The resulting request for the
    library/nginx:nginx:alpine manifest returned 400 DIGEST_INVALID and every
    Renovate run reported "Could not determine new digest for update" as a
    repository problem, leaving the digest frozen. The comments are gone and
    .github/renovate.json gained a customManager that parses the image:
    line itself, so depName is nginx, currentValue is alpine and the
    digest updates again. The match requires an @sha256: suffix, which keeps
    tag-only test images such as registry:2 in docker_login untracked, while
    the tag itself is optional so a digest-only pin (image: nginx@sha256:…) is
    still tracked rather than silently frozen. Excluding / from the tag keeps a
    port-qualified registry (registry.example.com:5000/nginx) inside depName
    instead of splitting it at the port.

  • k3s AppArmor profile survived being disabled: setting
    k3s_apparmor_profile to false only stopped
    roles/k3s/tasks/security.yml from writing /etc/apparmor.d/k3s; a copy
    left from an earlier run stayed on disk and was reloaded by
    apparmor.service on every boot, so turning the variable off never took
    effect on hosts that once had it on. The role now mirrors the cri-containerd
    disable path — it unloads the profile with apparmor_parser -R, removes the
    file and clears a hand-pla...

Read more

1.4.0

Choose a tag to compare

@github-actions github-actions released this 12 Jun 21:35
1.4.0
45d516c

[1.4.0] - 2026-06-12

Added

  • New k3s_etcd_s3_access_key / k3s_etcd_s3_secret_key variables in the k3s
    role: render etcd-s3-access-key / etcd-s3-secret-key into the server
    config so scheduled etcd snapshots can authenticate against S3-compatible
    storage (e.g. Cloudflare R2). The config file is deployed with mode 0600,
    so credentials stay root-only on disk. Both variables are optional and
    omitted when unset — existing consumers are unaffected.
  • New k3s_health_check_delay / k3s_health_check_timeout /
    k3s_health_check_sleep variables (defaults 30 / 600 / 10,
    backwards-compatible) parametrise the server API readiness probe in the
    k3s role. The wait_for task previously hard-coded delay: 30, an
    unconditional pre-sleep on every run; consumers running against an
    already-converged server can now set k3s_health_check_delay: 0 to skip
    the idle wait while timeout/sleep still cover the cold-bootstrap race.

Changed

  • Documented the full etcd snapshot variable family in the k3s role's
    argument_specs.yml (k3s_etcd_expose_metrics,
    k3s_etcd_snapshot_schedule_cron, k3s_etcd_snapshot_retention,
    k3s_etcd_snapshot_dir, k3s_etcd_s3, k3s_etcd_s3_endpoint,
    k3s_etcd_s3_region, k3s_etcd_s3_bucket, k3s_etcd_s3_folder plus the two
    new credential variables). These were previously template-only and
    undocumented. All are required: false and carry no spec default — the
    template gates each with is defined, so a default would change behaviour —
    and the two credential keys are marked no_log: true.

Fixed

  • docker_compose_v2 role: removed bogus "{{ omit }}" defaults for optional
    variables. The literal placeholder string broke argument-spec validation for
    non-str-typed vars (docker_compose_v2_scale as dict,
    _files/_profiles/_services as list[str]) under Ansible 2.18+.
    Optional vars are now intentionally undefined and the module-call kwargs
    apply | default(omit) to emit a real omit sentinel. End behaviour is
    unchanged for consumers that did not override these vars.

1.3.13

Choose a tag to compare

@github-actions github-actions released this 02 May 23:05
1.3.13
d1f472a

[1.3.13] - 2026-05-03

Added

  • New k3s_cri_apparmor_profile_enabled variable (default true,
    backwards-compatible) to opt out of deploying the cri-containerd.apparmor.d
    profile in the k3s role; when set to false the role unloads the profile
    from the kernel, removes the file, and notifies Restart k3s. Workaround
    for kernel 6.17 AppArmor profile-stacking bugs
    (k3s-io/k3s#13625,
    containerd/containerd#12886)
    which cause pod termination to hang and flood dmesg with SIGURG denials

1.3.12

Choose a tag to compare

@github-actions github-actions released this 01 Apr 00:43
0fc4ddb

[1.3.12] - 2026-04-01

Changed

  • Reverted unrestricted signal, AppArmor rule back to targeted peer-specific rules in k3s security profile; restricts signal operations to known peers (host and containerd manager) for a tighter security posture while maintaining full functionality
  • Added signal (send) peer=cri-containerd.apparmor.d rule to allow container processes to signal each other (e.g. PID 1 sending SIGTERM to children during graceful shutdown)

1.3.11

Choose a tag to compare

@github-actions github-actions released this 31 Mar 22:02
719bcb7

[1.3.11] - 2026-03-31

Fixed

  • Replaced restrictive AppArmor signal rules (signal (receive) peer=unconfined and signal (receive) peer=cri-containerd.apparmor.d) with unrestricted signal, in k3s security profile; runc requires full signal capabilities (send/receive) to deliver SIGTERM/SIGKILL to container init processes during pod termination

1.3.10

Choose a tag to compare

@github-actions github-actions released this 28 Mar 16:54
6c7e5d1

[1.3.10] - 2026-03-28

Fixed

  • Deploy /etc/apparmor.d/cri-containerd.apparmor.d with change_profile -> **, in k3s role;
    on Ubuntu 24.04 (kernel 6.8, AppArmor 4.x) containerd generates this profile dynamically
    without the rule, causing kubectl exec to fail with
    apparmor failed to apply profile: write fsmount:fscontext:proc/thread-self/attr/apparmor/exec: operation not permitted. Pre-deploying the fixed profile ensures runc can apply AppArmor
    profiles to exec'd container processes.

1.3.9

Choose a tag to compare

@github-actions github-actions released this 28 Mar 16:17
f18c3a0

[1.3.9] - 2026-03-28

Fixed

  • Replaced invalid fsmount, AppArmor rule (parse error: unexpected TOK_END_OF_RULE, expecting TOK_MODE) with change_profile -> **, in k3s security profile; this allows containerd to write the target profile name to /proc/thread-self/attr/apparmor/exec before exec, which is how AppArmor profiles are applied to container processes

1.3.8

Choose a tag to compare

@github-actions github-actions released this 28 Mar 14:11
427a490

[1.3.8] - 2026-03-28

Fixed

  • Added fsmount, AppArmor rule to k3s security profile; required for AppArmor 4.x (kernel >= 6.x) where containerd writes the AppArmor exec profile via the fsmount LSM hook when applying profiles to container processes (apparmor failed to apply profile: write fsmount:fscontext:proc/thread-self/attr/apparmor/exec: operation not permitted)
  • Moved Docker GPG key from deprecated /etc/apt/trusted.gpg.d/ to /etc/apt/keyrings/ and added task to create the keyrings directory; fixes apt warnings on Ubuntu 22.04+ that treat keys outside /etc/apt/keyrings/ as untrusted

1.3.7

Choose a tag to compare

@github-actions github-actions released this 23 Mar 23:12
a72ef1c

[1.3.7] - 2026-03-21

Fixed

  • Added AppArmor rule /proc/thread-self/attr/** rw to k3s security profile; required for containerd to apply AppArmor profiles to container exec processes (apparmor failed to apply profile: write /proc/thread-self/attr/apparmor/exec: operation not permitted)

1.3.6

Choose a tag to compare

@github-actions github-actions released this 21 Mar 01:36
e2520d3

[1.3.6] - 2026-03-21

Fixed

  • Fixed k3s binary upgrade being skipped due to HTTP 304 Not Modified from cached ETag; replaced force: true workaround with proper SHA256 checksum verification fetched from the k3s GitHub release — Ansible now compares the local binary against the expected checksum locally, bypassing HTTP cache entirely