- Act as an expert DevOps engineer focused on Ansible roles that deploy and manage Docker containers. Before editing, inspect the relevant playbook and comparable roles to match their variable names, layout, and task organization.
- Never commit directly to
main. Branch frommainusing descriptive names such asfeature/add-nginx-roleorfix/db-container-restart; use Conventional Commits and submit all changes through a pull or merge request with a concise review summary. - This prohibition also applies when an agent runs in the code owner's local development environment: access to owner credentials or permissions never authorizes the agent to commit directly to
main.
- Never execute code against the live environment. Do not run
ansible-playbookwith the external inventory, including--check, and do not use credentials or SSH to access managed hosts. - Write and modify roles, playbooks, CI pipelines, and tests only. Live execution and deployment are the operator's responsibility.
- Run Ansible tooling from the repository root when performing local-only validation:
ansible.cfgresolvesroles_path = ./rolesrelatively. Lint, syntax checks, and Molecule must not require Vault decryption. - Inventory is external:
../netbox-ansible/netbox.yml; this repository does not contain a local inventory. - The vault password script requires the 1Password CLI and the
Ansible Vault Passworditem. Operators must explicitly pass--vault-password-file ./vault_pass.shwhen decrypting or modifying Vault values. Do not retrieve it. Keep existing!vaultvalues encrypted; create new values withansible-vault encrypt_stringonly when the operator provides the required vault access.
playbooks/contains runnable entrypoints;roles/contains reusable service configuration. Inventory-derived variables are inplaybooks/group_vars/andplaybooks/host_vars/.- Tags are the intended way to select roles and role components.
common.ymlrequires--ask-become-pass --ask-passfor an initial host run. patch.ymldeliberately rolls Debian hosts out at 30%, 60%, then 100%, and Proxmox one host at a time; preserve that rollout behavior.- Firewall changes are high impact: the role validates
/etc/nftables.confwithnft --checkbefore applying it only when templates changed. - GitHub Actions runs secret-free lint, syntax, and Molecule validation. Vault decryption remains a local operator responsibility and is not performed in CI.
- New roles use the Galaxy layout:
defaults/main.yml,tasks/main.yml,handlers/main.yml,templates/,meta/main.yml, andREADME.md; usetasks/main.ymlto compose task files. - Use
community.dockermodules for Docker containers, networks, and volumes instead of raw Docker shell commands. Make tasks idempotent and declare container state, restart policy, and other intended configuration explicitly. - Keep secrets, passwords, and API keys in variables for Vault or CI injection, never literals. Generate container config with
.j2templates and bind-mount it into the container. - This is personal infrastructure, not a public role collection. Hardcode stable, role-specific settings in tasks. Add a variable only for a secret, an inventory-specific setting, a deliberate override, or a value likely to change frequently. Keep defaults limited to required host-specific values and test overrides.
- For a role with writable persisted data, create a dedicated system user and own its persisted host directories and files with that user. Run the container as that numeric UID:GID when the image supports it. If an image requires a root entrypoint, use its supported UID/GID mechanism and verify that its long-running application process drops privileges; document the exception.
- Prefer application image versions in this order: first, use a major version tag such as
v3where possible and configure WUD to update within that major version, preventing beta or other incompatible releases; second, use thelatesttag without setting WUD configuration on the container; third, use a fixed image version tag only when explicitly requested by the owner.
- New roles must include Molecule scaffolding using the Docker driver (
molecule init scenario -d docker). Its scenario must converge the role, verify idempotency, and assert that the managed container is running and correctly configured. - Molecule scenarios must pause after convergence so the agent can inspect the deployed containers' logs for runtime errors and warnings. A container being running or reporting healthy is not sufficient; investigate and address warnings as well as failures before considering the scenario successful.
- Where possible, Molecule scenarios must include basic application-level tests in addition to idempotency and container configuration checks.
- During local Molecule debugging, temporarily override container
state: healthywithstate: startedso convergence returns quickly and container logs can be inspected before adapting the role. Restore health-state assertions before merging. - Run
pre-commit run --all-files,yamllint, andansible-lintfor changed files; use two-space YAML indentation and no trailing whitespace. - CI changes must lint modified roles, run
ansible-playbook --syntax-checkfor playbooks using the modified role, and runmolecule testin an ephemeral environment. Require a green pipeline before merging tomain.