## Standards ### Ansible + YAML conventions - **Indentation**: 2 spaces (no tabs) - **Task naming**: every task should include a clear `name:` - **Play-level privilege**: prefer `become: true` at play level when most tasks need sudo - **Modules**: - Prefer native modules over `shell`/`command` - Use **fully qualified collection names** (FQCN), e.g. `ansible.builtin.apt`, `community.general.ufw` - **Handlers**: use handlers for restarts/reloads - **Idempotency**: - If `shell`/`command` is unavoidable, set `changed_when:` / `creates:` / `removes:` appropriately ### Role structure Roles should follow: ``` roles// ├── defaults/main.yml ├── handlers/main.yml ├── tasks/main.yml ├── templates/ ├── files/ └── README.md ``` ### Variable naming - **snake_case** everywhere - Vault-backed variables are prefixed with **`vault_`** ### Secrets / Vault - Never commit plaintext secrets. - Use Ansible Vault for credentials: - `inventories/production/group_vars/all/vault.yml` (encrypted) - Local vault password file is expected at `~/.ansible-vault-pass`. ### Makefile-first workflow - Prefer `make ...` targets over direct `ansible-playbook` commands for consistency. ### Linting - `ansible-lint` is the primary linter. - `.ansible-lint` excludes vault-containing inventory paths to keep linting deterministic without vault secrets.