From all-skills
Guides structuring Ansible roles, managing role dependencies, writing Jinja2 templates, and using Ansible Galaxy for role installation and reuse.
How this skill is triggered — by the user, by Claude, or both
Slash command
/all-skills:ansible-rolesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Activate when creating reusable role structures, using `import_role:` or `include_role:`, writing Jinja2 templates, or working with Ansible Galaxy collections and roles.
Activate when creating reusable role structures, using import_role: or include_role:, writing Jinja2 templates, or working with Ansible Galaxy collections and roles.
A role is a self-contained directory of tasks, handlers, variables, templates, and files organized for reuse. Instead of copying tasks between playbooks, extract them into a role and apply the role wherever needed.
Roles enforce a consistent directory layout that Ansible recognizes automatically.
roles/
└── my_role/
├── tasks/
│ └── main.yml # entry point — required
├── handlers/
│ └── main.yml # handlers (notified by tasks)
├── defaults/
│ └── main.yml # default variables (lowest precedence)
├── vars/
│ └── main.yml # role variables (higher precedence than defaults)
├── files/
│ └── app.conf # static files (copy: module)
├── templates/
│ └── nginx.conf.j2 # Jinja2 templates (template: module)
├── meta/
│ └── main.yml # role metadata and dependencies
└── tests/
├── inventory
└── test.yml # simple smoke test playbook
Scaffold a new role:
ansible-galaxy role init my_role
| Location | Precedence | Purpose |
|---|---|---|
defaults/main.yml | Lowest — easily overridden | User-facing knobs with sensible fallbacks |
vars/main.yml | Higher — harder to override | Internal role constants |
# defaults/main.yml
nginx_port: 80
nginx_worker_processes: auto
nginx_log_level: warn
# vars/main.yml
nginx_config_dir: /etc/nginx
nginx_pid_file: /var/run/nginx.pid
Set defaults for everything a consumer might want to change. Put implementation details in vars.
# Classic roles: block (static, resolved at parse time)
- hosts: webservers
roles:
- common
- role: nginx
vars:
nginx_port: 8080
# import_role (static — analyzed before execution)
- hosts: webservers
tasks:
- name: Apply base role
ansible.builtin.import_role:
name: common
# include_role (dynamic — resolved at runtime, supports when:/loop:)
- hosts: webservers
tasks:
- name: Apply role conditionally
ansible.builtin.include_role:
name: nginx
when: install_nginx | bool
loop: "{{ nginx_sites }}"
loop_control:
loop_var: nginx_site
Use import_role when you need tags to propagate; use include_role when you need conditionals or loops on the role itself.
Declare roles that must run before this role in meta/main.yml:
# roles/app/meta/main.yml
galaxy_info:
author: rginnow
description: Deploy the application
license: MIT
min_ansible_version: "2.14"
dependencies:
- role: common
- role: nginx
vars:
nginx_port: 8080
Dependencies run first, in order. Ansible deduplicates them — a dependency listed by multiple roles only runs once per play.
Use the template: module to render Jinja2 templates from templates/ onto managed nodes.
- name: Write nginx config
ansible.builtin.template:
src: nginx.conf.j2 # relative to templates/ — Ansible finds it
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: "0644"
notify: Reload nginx
Template syntax:
{# nginx.conf.j2 #}
worker_processes {{ nginx_worker_processes }};
pid {{ nginx_pid_file }};
events {
worker_connections {{ nginx_worker_connections | default(1024) }};
}
http {
server {
listen {{ nginx_port }};
server_name {{ ansible_fqdn }};
{% for location in nginx_locations %}
location {{ location.path }} {
proxy_pass {{ location.upstream }};
}
{% endfor %}
}
}
Key Jinja2 syntax:
{{ variable }} — output a value{% if condition %}...{% endif %} — conditional block{% for item in list %}...{% endfor %} — loop{# comment #} — template comment (not in output){{ value | filter }} — apply a filterCommon filters:
{{ my_list | join(', ') }} {# join list items #}
{{ name | upper }} {# uppercase #}
{{ path | basename }} {# filename from path #}
{{ value | default('fallback') }} {# fallback if undefined #}
{{ items | selectattr('active') }} {# filter objects by attribute #}
{{ count | int }} {# type conversion #}
Galaxy is the public hub for community roles and collections.
# Install a role
ansible-galaxy role install geerlingguy.nginx
# Install a collection (namespaced: namespace.collection)
ansible-galaxy collection install community.general
ansible-galaxy collection install amazon.aws
# Specify version
ansible-galaxy collection install community.general:==6.0.0
Pin dependencies in a requirements.yml file and install all at once:
# requirements.yml
roles:
- name: geerlingguy.nginx
version: "3.2.0"
- src: https://github.com/example/my-role
name: my_custom_role
collections:
- name: community.general
version: ">=6.0.0"
- name: amazon.aws
version: "6.5.0"
ansible-galaxy role install -r requirements.yml
ansible-galaxy collection install -r requirements.yml
# ansible.cfg
[defaults]
roles_path = roles:~/.ansible/roles:/usr/share/ansible/roles
Ansible searches each path in order when resolving role names.
npx claudepluginhub vinnie357/claude-skills --plugin qaStructures Ansible roles for modular automation and configuration management, with examples for nginx webserver installation, configuration, and security tasks.
Designs production-grade Ansible role structures including directories, tasks/handlers organization, variable precedence (defaults/vars), based on 7 geerlingguy roles. Use when creating/refactoring roles.
Provides Ansible playbook and role structures plus best practices for idempotent tasks, handlers, FQCN, and inventory management. Use when writing playbooks, roles, or automating infrastructure.