Use when working with Ansible Core 2.19 for automation, configuration management, playbooks, modules, or infrastructure as code
Comprehensive assistance with Ansible Core development and automation, generated from official Ansible Core 2.19 documentation.
This skill should be triggered when:
A simple playbook with tasks, the fundamental building block of Ansible automation:
- name: My first play
hosts: myhosts
tasks:
- name: Ping my hosts
ansible.builtin.ping:
- name: Print message
ansible.builtin.debug:
msg: Hello world
What it does: Defines a play that runs against hosts in the myhosts group, pings them to verify connectivity, and prints a debug message.
Organize your managed hosts into groups with variables:
[web]
host1
host2 ansible_port=222
[web:vars]
http_port=8080
myvar=23
[web:children]
apache
nginx
[apache]
tomcat1
tomcat2 myvar=34
tomcat3 mysecret="'03#pa33w0rd'"
[nginx]
jenkins1
[all:vars]
has_java = False
What it does: Defines host groups, assigns variables at group level, creates group hierarchies with :children, and sets host-specific overrides.
Encrypt sensitive data and use it in playbooks:
# Create encrypted file
ansible-vault create secrets.yml
# Use in playbook with password prompt
ansible-playbook site.yml --ask-vault-pass
# Use with password file
ansible-playbook site.yml --vault-password-file ~/.vault_pass.txt
# Use multiple vault IDs
ansible-playbook site.yml --vault-id dev@dev-password --vault-id prod@prompt
What it does: Encrypts sensitive variables, allows decryption at runtime with passwords from prompts, files, or scripts. Supports multiple vault IDs for different environments.
Get started with Ansible quickly:
# Install ansible
pip install ansible
# Create project structure
mkdir ansible_quickstart && cd ansible_quickstart
# Run a playbook
ansible-playbook playbook.yaml
What it does: Installs Ansible via pip, creates a project directory for organizing automation content, and executes a playbook.
Execute single tasks without writing a playbook:
# Run ad-hoc command on specific hosts
ansible -i inventory.ini myhosts -m ansible.builtin.ping
# Install package with privilege escalation
ansible localhost -m ansible.builtin.apt -a "name=apache2 state=present" -b -K
# Check disk space
ansible all -m ansible.builtin.shell -a "df -h"
What it does: Executes Ansible modules directly from CLI for quick tasks. -b enables become (sudo), -K prompts for privilege escalation password.
Dynamically load variables from external files:
- name: Include vars of stuff.yaml into the 'stuff' variable
ansible.builtin.include_vars:
file: stuff.yaml
name: stuff
- name: Load variables based on OS
ansible.builtin.include_vars: "{{ lookup('ansible.builtin.first_found', params) }}"
vars:
params:
files:
- '{{ansible_distribution}}.yaml'
- '{{ansible_os_family}}.yaml'
- default.yaml
paths:
- 'vars'
What it does: Loads YAML/JSON variables at runtime. Supports conditional loading based on facts, directory scanning, and namespace isolation.
Create a custom filter plugin:
from ansible.module_utils.common.text.converters import to_native
try:
cause_an_exception()
except Exception as e:
raise AnsibleError('Something happened, this was original exception: %s' % to_native(e))
What it does: Shows proper error handling in Ansible plugins using to_native() for Python 2/3 string compatibility and AnsibleError for user-friendly error messages.
Ensure proper Unicode handling in custom modules:
from ansible.module_utils.common.text.converters import to_text
result_string = to_text(result_string)
What it does: Converts strings to Unicode (Python 3's str type) ensuring Jinja2 compatibility and preventing encoding errors.
Transform Ansible variables into YAML format in templates:
# dump variable in a template to create a YAML document
{{ github_workflow | to_nice_yaml }}
# with custom indentation and sorting
{{ my_dict | to_nice_yaml(indent=4, sort_keys=False) }}
What it does: Uses the to_nice_yaml filter to serialize Ansible variables as YAML strings, useful for generating config files or debugging.
Use Jinja2 test plugins to validate data:
big: [1,2,3,4,5]
small: [3,4]
issmallinbig: '{{ small is subset(big) }}'
What it does: Tests if one list is a subset of another. Useful for conditional logic in playbooks based on list membership.
YAML files defining automation workflows. Contain plays (ordered lists of tasks) that run against inventory groups. Each task invokes a module with specific parameters.
Lists of managed hosts organized into groups. Can be static (INI/YAML files) or dynamic (scripts/plugins). Supports host and group variables, parent-child relationships.
Reusable units of code executed on managed nodes. Ansible ships with hundreds of modules (ansible.builtin collection). Use FQCN (Fully Qualified Collection Name) like ansible.builtin.copy for clarity.
Extend Ansible's core functionality. Types include filters, tests, callbacks, connections, inventory, lookup, and vars plugins. Execute on the control node (unlike modules).
Packaging format for Ansible content (modules, plugins, roles, playbooks). Use ansible-galaxy collection install to add community collections.
Encryption system for sensitive data. Encrypts entire files or individual variables. Supports multiple vault passwords with vault IDs for different environments (dev, prod, etc.).
Full path to a module/plugin: namespace.collection.plugin_name. Example: ansible.builtin.copy. Prevents naming conflicts and improves clarity.
System information gathered automatically from managed nodes. Access with ansible_facts variable. Disable with gather_facts: no in playbooks.
Special tasks triggered by notify directive. Run once at the end of a play, even if notified multiple times. Common for service restarts.
This skill includes comprehensive documentation in references/:
Use the reference files when you need:
First steps:
pip install ansibleansible-playbook -i inventory.ini playbook.ymlFocus areas:
Advanced topics:
- name: Install package
ansible.builtin.apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: Create multiple users
ansible.builtin.user:
name: "{{ item }}"
state: present
loop:
- alice
- bob
- charlie
tasks:
- name: Update config
ansible.builtin.copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
notify: restart nginx
handlers:
- name: restart nginx
ansible.builtin.service:
name: nginx
state: restarted
- name: Check if file exists
ansible.builtin.stat:
path: /etc/myapp/config
register: config_stat
- name: Create config if missing
ansible.builtin.copy:
src: default-config
dest: /etc/myapp/config
when: not config_stat.stat.exists
ansible.builtin.copy instead of copy for clarity--check mode - Test playbooks without making changes--diff - See what changes before applying themConnection issues:
# Test connectivity
ansible all -m ping -i inventory.ini
# Use verbose mode
ansible-playbook playbook.yml -vvv
# Check SSH configuration
ansible all -m shell -a "whoami" --ask-pass
Variable debugging:
- name: Debug variable value
ansible.builtin.debug:
var: my_variable
verbosity: 0
Syntax validation:
# Check playbook syntax
ansible-playbook playbook.yml --syntax-check
# Lint with ansible-lint (if installed)
ansible-lint playbook.yml
To refresh with updated documentation:
# Re-scrape with same configuration
uv run cli/doc_scraper.py --config configs/ansible-core.json --enhance-local
# Or use cached data for faster rebuild
uv run cli/doc_scraper.py --config configs/ansible-core.json --skip-scrape --enhance-local
The skill will be rebuilt with the latest information from the Ansible Core documentation.