{
 "id": "ansible",
 "kind": "skill",
 "name": "Ansible",
 "description": "Write, lint, dry-run and run Ansible playbooks, roles and inventories safely.",
 "version": "1.0.0",
 "author": "Hexa Hub",
 "files": {
  "SKILL.md": "---\nname: ansible\ndescription: Write, lint, dry-run and run Ansible playbooks, roles and inventories safely.\ntitle: Ansible\nicon: tabler:brand-ansible\ncategory: Infrastructure as code\ntriggers: ansible, playbook, role, inventory, group_vars, handler, ansible-lint, galaxy, jinja\nmarkers: ansible, ansible-lint\nrecipes: ansible.syntax-check, ansible.lint, ansible.inventory-list, ansible.check, ansible.run, help.ansible-doc\nrelated: terraform, puppet\n---\n\n# Ansible\n\nAnsible does not run on Windows itself. On a Windows PC run the recipes where Ansible lives: `on: \"wsl:<name>\"` or `on: \"ssh:<name>\"` (hosts are set up in Settings, Hosts). If the recipe says the program is missing, use `toolchain`.\n\n**Check or review request**: read the playbook or role, run `ansible.syntax-check` and `ansible.lint`, then answer. Do not run the dry run or the playbook for a review. If Ansible is not installed here, say so and review the code by reading it.\n\n## Workflow for a change\n1. **Look first.** Find the playbook, the role and the inventory it targets (`find_code`, `list_dir`). Follow the layout in use: `inventories/<env>/`, `group_vars/`, `roles/<name>/{tasks,handlers,defaults,vars,templates,files,meta}`.\n2. Edit the role or playbook.\n3. `ansible.syntax-check`, then `ansible.lint`. Fix everything lint reports unless the user's existing code clearly ignores that rule.\n4. `ansible.check` (dry run, `--check --diff`) with `limit` set to one host first. **Show the user what would change.** Tasks that cannot run in check mode are skipped, so say what the dry run could not tell.\n5. Only if the user asks to run it: `ansible.run` with the same playbook, inventory and limit. It always asks, works only right after the check on unchanged files, and is blocked for prod inventories. Roll out to one host, look at the result, then widen `limit`.\n\nExample: `run_recipe {\"recipe\":\"ansible.check\",\"args\":{\"playbook\":\"site.yml\",\"inventory\":\"inventories/test\",\"limit\":\"web01\"},\"on\":\"wsl:ubuntu\"}`\n\n## Write idempotent tasks\n- Use the module for the job, with its fully qualified name (`ansible.builtin.copy`, `ansible.builtin.template`, `ansible.posix.firewalld`). Look up arguments for the installed version with `help.ansible-doc` (module name); never invent arguments.\n- `command`/`shell` only when no module exists, and then with `creates:` or `changed_when:` so a second run reports no change. A second dry run after a run must show zero changes.\n- Every task has a `name`. Restart services with handlers (`notify:`), not tasks. Use `become` on the task or play that needs it, not for everything.\n- Variables: role defaults in `defaults/main.yml` (overridable), constants in `vars/`, environment values in `group_vars/<env>`. Prefix variable names with the role name.\n- Booleans and modes as the right type: `mode: \"0644\"` (string), `enabled: true`. A value starting with `{{` must be quoted: `path: \"{{ base_dir }}/app\"`.\n- `when:` takes a bare expression (no braces). `loop:` instead of `with_items`.\n\n## Secrets\nNever write passwords into playbooks, vars files or templates. Use `ansible-vault` encrypted files and reference the variable by name; ask the user to create the vault content. Add `no_log: true` to tasks that handle secrets. Hexa's secret handles are for files you write for the user's machine, not for files that go into version control.\n\n## Windows targets\nUse the `ansible.windows` and `community.windows` collections over WinRM or SSH; module names differ (`ansible.windows.win_service`). Check with `help.ansible-doc`.\n\n## Report\nSay: what changed in the code, lint result, what the dry run said (hosts, tasks that would change) and whether anything was actually run.\n"
 }
}
