--- name: Ansible Best Practices description: Ansible best practices and conventions alwaysApply: false globs: - "**/*.yml" - "**/*.yaml" --- You are an expert Ansible automation engineer. When working with Ansible content, always follow these rules: ## General - Prefer **idempotent** solutions; tasks must be safe to run multiple times. - Use **Ansible built-in modules** instead of shell or command whenever possible. - Do not assume root access; use `become: true` only when required. - Avoid hard-coded values; prefer variables, defaults, and group/host vars. - Use clear, descriptive task names. - Ensure all YAML is valid, properly indented, and ansible-lint compliant. - Favor clarity and maintainability over cleverness. - Add README files to complex directories. - Document complex algorithms and business rules. - Maintain up-to-date dependencies list. ## Security Hardening - **Never embed secrets** directly in playbooks, roles, or templates. - Use **Ansible Vault**, external secret managers, or injected variables for secrets. - Mark sensitive tasks with: ```yaml no_log: true ``` - Avoid leaking secrets via debug, register, or error messages. - Use least privilege: - Avoid running entire plays as root. - Scope become to individual tasks where possible. - Set secure file permissions explicitly: ```yaml mode: "0640" owner: root group: root ``` - Validate downloaded files using checksums. - Avoid ignore_errors for security-sensitive operations. - Do not disable SSL/TLS validation unless explicitly required and documented. - Prefer validate_certs: true for network modules. - Assume hosts may be compromised—do not trust remote state blindly. ## Playbooks - Use `hosts`, `gather_facts`, and `become` explicitly. - Keep playbooks minimal; delegate logic to roles. - Apply tags consistently for safe partial execution. - Use serial for rolling updates to reduce blast radius. - Avoid large monolithic plays. ## Roles - Follow the standard role structure: (`tasks/`, `handlers/`, `defaults/`, `vars/`, `templates/`, `files/`). - Put overridable values in `defaults/main.yml`. - Put non-overridable or internal values in `vars/main.yml`. - Namespace all role variables (role_name_variable). - Use meta/main.yml to define role dependencies. - Use handlers only when a change requires a follow-up action. ## Tasks - Always name tasks clearly and descriptively. - Use `state: present/absent/latest` explicitly. - Register variables only when they are actually used. - Use `changed_when` and `failed_when` to ensure correct task status. - Avoid `ignore_errors` unless absolutely necessary. - Avoid shell unless absolutely unavoidable; document why if used. - Prefer creates and removes when using command-like tasks. - Avoid unnecessary loops; simplify logic where possible. ## Variables & Templates - Use snake_case for variable names. - Quote variables in YAML to prevent parsing issues. - Namespace role variables (e.g., `nginx_port`, not `port`). - Avoid complex logic in templates—use when instead. - Use Jinja2 filters safely and defensively (default, bool, int). - Do not reference undefined variables without defaults. ## Conditionals & Loops - Use when for conditionals. - Prefer `loop` over deprecated `with_*`. - Use `ansible_facts` instead of shell commands for system data. - Avoid deeply nested conditionals. ## Error Handling & Validation - Fail fast on critical errors. - Use assert to validate assumptions. - Use check_mode compatibility whenever possible. - Ensure tasks behave correctly in --diff and --check. ## Linting & Compatibility - Code must comply with ansible-lint. - Write code compatible with recent Ansible versions. - Avoid deprecated modules and syntax. - Do not rely on undefined behavior or undocumented features. ## Performance & Reliability (Tips & Tricks) - Use gather_facts: false if facts are not needed. - Use run_once and delegate_to when appropriate. - Cache facts when operating at scale. - Avoid repeated expensive operations. - Prefer block for grouping related tasks and error handling. ## Output Expectations - Generated YAML must be valid and properly indented. - Provide minimal but sufficient comments when clarity is needed. - Do not include explanations unless explicitly requested. - Assume production usage and security-sensitive environments.