Ansible

Pages 3-5 of the Bitsmasher Lab Operations Manual (62 pages)

Ansible Automation

Current Landscape (August 2026)

As of August 2026, the Ansible ecosystem is split between two distribution paths:

<strong>EOL versions as of August 2026</strong>: Ansible 10--12 and ansible-core 2.15--2.18 are EOL. Do not use these in new work. Only Ansible 13.x / ansible-core 2.20 is current; 14.0.0/2.21 is in development.

Molecule Testing -- Deprecated (August 2026)

<strong>Molecule has been removed from the active workflow as of August 2026.</strong> It no longer serves as a testing target or standard. All role validation now uses:

Existing Molecule test harnesses (in ansible/collections/ansible\_collections/lab/franklin/roles/ role /molecule/}) remain as historical artifacts but are no longer invoked or maintained. New roles must use native ansible-test exclusively.

The lab/franklin Ansible collection lives at:

\begin{lstlisting}[style=mystyle]

/mnt/clusterfs2/workspace/lab-franklin/ansible/collections/ansible_collections/lab/franklin/

    \end{lstlisting}

It is the central automation artifact for the entire lab.bitsmasher.net infrastructure, managing provisioning, configuration, and testing across all hosts.

Collection Manifest (galaxy.yml)

The collection follows standard Ansible Galaxy conventions with namespace lab} and name franklin}:

Role Inventory

The collection contains roles organized under the roles/ directory. As of August 2026, the following roles are maintained with native ansible-test harnesses:

\begin{lstlisting}[style=mystyle]

roles/

├── apt_mirror/ # APT mirror configuration

├── beagleboard/ # BeagleBoard device provisioning

├── common/ # Shared base configuration (bootstrap.sh, common utils)

├── container_registry/ # Docker/container registry setup

├── ctfd/ # CTFd platform deployment

├── desktop/ # Desktop environment provisioning

├── docker/ # Docker engine installation

├── documentation/ # Documentation generation roles

├── dhcp/ # DHCP server configuration (dhcpd.conf)

├── dns/ # BIND/named DNS server

├── golang/ # Go language toolchain

├── jetson-nano/ # NVIDIA Jetson Nano provisioning

├── k3s_agent/ # k3s worker node

├── k3s_server/ # k3s control plane server

├── k8s/ # Kubernetes generic setup

├── latex/ # LaTeX environment

├── logging/ # Centralized logging

├── music/ # Music service configuration

├── nfs/ # NFS server/client

├── nix/ # Nix package manager

├── openbsd/ # OpenBSD host bootstrap (blowfish target)

│ ├── tasks/main.yml # Includes files.yml, timezone setup

│ └── files/ # bootstrap.sh, login.conf, hosts entries

├── paloalto/ # Palo Alto firewall config

├── prereq/ # Prerequisite packages

├── pypi_internal/ # Internal PyPI repository setup

│ ├── tasks/main.yml # Symlink pypi_dir -> html_dir/pypi

│ └── vars/main.yml # html_dir=/var/www/html, pypi_dir=/mnt/storage1/LAB/pypi

├── python/ # Python environment

├── raspberrypi/ # Raspberry Pi provisioning

├── samba/ # Samba file sharing

├── security/ # Hardening and security baselines

├── shell/ # Shell configuration

├── ssh/ # SSH server hardening

├── tls/ # TLS certificate management

├── chonk/ # chonk-specific configuration

├── cluster/ # Cluster-wide settings

    \end{lstlisting}

Workspace Structure

The full project layout:

\begin{lstlisting}[style=mystyle]

/workspace/lab-franklin/

├── Makefile.am # Top-level autotools target (Python, Docker, dev)

├── configure.ac # Autotools config (autoconf)

├── bootstrap.sh # Cross-platform bootstrapper

├── network_update.sh # One-shot maintenance script (hardened 2026-08-02)

├── ansible/ # ANSIBLE_HOME root

│ ├── playbook.yml # Main playbook

│ ├── hosts # Inventory file

│ └── collections/ # Collections path

│ ├── ansible_collections/ # Galaxy namespace

│ └── lab/franklin/ # The lab/franklin collection

│ ├── galaxy.yml

│ ├── roles/ # All role modules (37 total)

│ └── docs/latex/ # LaTeX docs build (autotools)

├── container/ # Docker/Podman configs

├── terraform/ # Terraform infrastructure definitions

├── bin/ # Shared utility scripts (common.sh)

└── docs/manual/ # Lab manual documentation (this document)

    \end{lstlisting}

Build System (Autotools)

The project uses GNU Autotools for the root-level build:

The network\_update.sh} script was hardened on 2026-08-02 with: set -euo pipefail, auto-resolved paths, pinned K3s version validation, ANSIBLE_HOME environment checks, removed dangerous clush/apt-get blast radius, and dead code removal. It runs the main playbook at ansible/playbook.yml} as its primary action.

Native ansible-test on stargate.research.bitsmasher.net

The stargate host (10.10.16.66, Debian 12 bookworm) serves as the exclusive testing platform for the lab/franklin Ansible collection. All test execution runs with zero external billing -- direct shell access to the gateway sandbox eliminates API token overhead.

Testing Standard: ansible-test (August 2026)

Native ansible-test} has replaced Molecule as the canonical testing framework:

The legacy Molecule directory structure at each role's molecule/} subdirectory has been deprecated. It remains in-place as historical reference but is excluded from CI pipelines and the Makefile.am test target.

Test Execution Flow (ansible-test)

For a given role, the native test cycle is:

  1. <strong>syntax-check</strong>: \texttt{ansible-playbook --syntax-check playbook.yml} validates YAML structure
  2. <strong>sanity</strong>: \texttt{ansible-test sanity} runs built-in linting against the collection -- no container, no overhead
  3. <strong>integration</strong>: \texttt{ansible-test integration <role>} runs target-specific tests using docker driver containers

Running Tests from Stargate

From stargate's workspace:

\begin{lstlisting}[style=mystyle]

cd ~/workspace/lab-franklin/ansible/collections/ansible_collections/lab/franklin

ansible-test sanity

ansible-test integration dns --python 3.12

ansible-playbook --syntax-check playbook.yml

    \end{lstlisting}

Dynamic Scoping and Pathing Convention

Roles use dynamic file inclusion via templated variables to avoid hardcoded paths:

This convention eliminates static path dependencies across role invocations and supports multi-target deployment without playbook-level path overrides.

Package Standards -- Deprecated Utilities

The following deprecated utilities have been removed from baseline role manifests:

Dynamic Probing Standard

Static inventory reachability assumptions have been replaced with non-interactive batch probes:

\begin{lstlisting}[style=mystyle]

ssh -o BatchMode=yes -o ConnectTimeout=3 -i ~/.ssh/id_ed25519_openclaw franklin@<host> "hostname && whoami"

    \end{lstlisting}

This approach eliminates stale host entries, prevents password prompts in automation pipelines, and provides deterministic connectivity feedback with a 3-second timeout. Never assume reachability from static notes -- always probe on demand.