Claude
Skills
Sign in
Back

ansible

Included with Lifetime
$97 forever

ansible-core — the agentless, push-based, SSH automation engine that runs idempotent tasks from declarative YAML playbooks. Use when writing or running Ansible playbooks, issuing ad-hoc commands (`ansible -m`), managing INI/YAML inventory, authoring roles, installing collections with `ansible-galaxy`, encrypting secrets with Ansible Vault, tuning `ansible.cfg`, looking up module docs with `ansible-doc`, or provisioning/configuring hosts idempotently over SSH. Covers the ten `ansible*` CLIs, FQCN (`ansible.builtin.*`), become/privilege escalation, inventory patterns, variable precedence, check/diff mode, and strategies. Triggers on mentions of ansible, ansible-playbook, ansible-galaxy, ansible-vault, ansible-inventory, ansible.cfg, playbooks, roles, collections, or Ansible Vault. This is ansible-core (the engine + `ansible.builtin`), NOT generic configuration-management theory and NOT the bundled community `ansible` package's collection modules.

Ads & Marketing

What this skill does


# ansible-core - Agentless Automation Engine

## Overview

ansible-core is the automation **engine**: you describe desired state in declarative YAML
**playbooks**, and it connects to managed hosts (by default over **SSH**, **push**-based) and
runs **modules** that converge each host to that state. It is **agentless** — nothing is
installed on the targets beyond Python and SSH; the controller pushes and executes module code,
then cleans up. Well-written modules are **idempotent**: re-running a playbook reports `changed`
only when something actually changed.

**Key characteristics:**
- **Agentless / push / SSH** — controller connects out to hosts; no daemon on the targets
- **Declarative YAML** — plays map a host pattern to an ordered list of tasks (modules + args)
- **Idempotent** — converge to desired state; safe to re-run; `--check` predicts, `--diff` shows
- **Inventory-driven** — hosts and groups come from INI/YAML inventory (or dynamic plugins)
- **FQCN-addressed** — builtin content is `ansible.builtin.<name>`; everything else ships as a
  Galaxy **collection** you install separately

> **ansible-core vs the community `ansible` package:** *ansible-core* is the engine plus the
> **`ansible.builtin`** content set (the modules/plugins bundled in this repo). The community
> **`ansible`** package (v9/10/11…) is a curated bundle of ansible-core **plus hundreds of
> collections** (`community.general`, `ansible.posix`, `community.docker`, …). When a user
> "installs ansible" they may have either. Anything beyond `ansible.builtin` requires
> `ansible-galaxy collection install <ns.coll>`. **Always FQCN non-builtin content.**

> **Disambiguation:** This skill documents **ansible-core and its `ansible*` CLIs** — playbooks,
> inventory, roles, collections, vault, config, become, and the engine's behavior. It is **not**
> a course in generic config-management theory, and it does **not** enumerate the thousands of
> collection modules — for those, use `ansible-doc -l` and `ansible-doc <fqcn>`.

## When to Use This Skill

Use this skill when:
- **Writing/running playbooks**: `ansible-playbook site.yml -i inventory.ini`
- **Ad-hoc commands**: `ansible web -m ansible.builtin.ping`, `ansible all -a 'uptime'`
- **Managing inventory**: INI or YAML hosts/groups, `group_vars/`, `host_vars/`, `--limit`
- **Authoring roles**: `tasks/`, `handlers/`, `defaults/`, `vars/`, `templates/`, `meta/`
- **Collections**: `ansible-galaxy collection install`, `requirements.yml`, FQCN resolution
- **Secrets**: Ansible Vault (`ansible-vault encrypt`/`encrypt_string`, `--vault-id`)
- **Configuration**: `ansible.cfg` discovery/precedence, `ansible-config dump`
- **Privilege escalation**: `become`, `--become-method` (sudo/su/runas), `-K`
- **Module discovery**: `ansible-doc -l`, `ansible-doc <fqcn>`, `ansible-doc -s`
- **Idempotent provisioning**: dry-run with `--check`, inspect with `--diff`

## Prerequisites

**CRITICAL**: Before proceeding, verify ansible-core is installed and check the version:

```bash
ansible --version        # prints "ansible [core 2.21.x]", config file, python/jinja versions
```

**Version note:** This skill is documented against **ansible-core 2.21** (the latest released
core; the reference clone is a `2.22.0.dev0` development checkout, so 2.22 features are treated
as unreleased). Long-standing flags work on any recent core; features added in a specific
release are annotated inline as `(ansible-core X.Y+)` **only where the source declares a
`version_added`**. Bedrock flags (the bulk of the CLI) are left unannotated. Confirm on the
running system with `ansible --version` and `<binary> --help`.

**If ansible-core is not installed:** do **NOT** silently auto-install. Recommend a user-scoped
install and let the user choose engine-only vs the full bundle:

```bash
# Just the engine + ansible.builtin (recommended for CI / lean controllers)
pipx install ansible-core          # or: pip install --user ansible-core

# The full community bundle (ansible-core + curated collections)
pipx install ansible               # or: pip install --user ansible

# System packages also exist (apt/dnf "ansible" or "ansible-core"); versions lag pip
```

`pipx` keeps ansible in an isolated venv with the `ansible*` shims on `PATH` — preferred over a
global `pip install`.

## The `ansible*` Binaries

Ten executables ship in `bin/`; each is a thin launcher over `lib/ansible/cli/<name>.py`.

| Binary | Purpose |
|--------|---------|
| `ansible` | **Ad-hoc** — run a single module against a host pattern (`-m`/`-a`) |
| `ansible-playbook` | Run **playbooks** (the primary workhorse) |
| `ansible-inventory` | Inspect/validate inventory: `--list`, `--graph`, `--host` |
| `ansible-galaxy` | Install/manage **collections** and **roles** (`requirements.yml`) |
| `ansible-vault` | Encrypt/decrypt secrets: `create`, `encrypt`, `encrypt_string`, `view`, `rekey` |
| `ansible-doc` | Plugin/module documentation: `-l` (list), `-s` (snippet), `-t TYPE` |
| `ansible-config` | View/dump/generate config: `list`, `dump`, `view`, `init`, `validate` |
| `ansible-console` | Interactive REPL that runs modules against a host pattern |
| `ansible-pull` | **Pull** mode — host clones a repo and runs a playbook on itself (cron/scale) |
| `ansible-test` | Dev/CI test runner for collections (shipped separately; out of scope here) |

Every binary shares flag groups (verbosity `-v`…`-vvvvvv`, inventory, connection, become,
vault, …). For the exhaustive per-binary flag set, see **[references/cli.md](references/cli.md)**.

## Mental Model

```
inventory ──> playbook ──> plays ──> tasks ──> modules (FQCN) ──> managed hosts (SSH)
   hosts        YAML        hosts:    name:     ansible.builtin.*    idempotent change
   & groups               + tasks    module:                        (check/diff preview)
```

1. **Inventory** names your hosts and arranges them into **groups** (`all` and `ungrouped` are
   implicit). INI and YAML are the two hand-written formats.
2. A **playbook** is a list of **plays**; each play binds a **host pattern** (`hosts:`) to an
   ordered list of **tasks** (plus `pre_tasks`, `roles`, `post_tasks`, `handlers`).
3. Each **task** invokes one **module** by **FQCN** (`ansible.builtin.copy`) with arguments.
4. **Idempotency**: modules converge to desired state and report `changed` only on real change.
   **`--check`** predicts changes without applying; **`--diff`** shows what would change.
5. **FQCN**: builtin content is `ansible.builtin.<name>`; bare names resolve via `ansible.legacy`
   (local `library/` overrides, then builtin). Non-builtin content needs its collection installed.

## Core Workflows

### 1. Ad-hoc command (one module, no playbook)

```bash
# Default module is `command`; -a passes its args
ansible all -i inventory.ini -m ansible.builtin.ping
ansible web -i inventory.ini -m ansible.builtin.shell -a 'systemctl status nginx'
ansible all -i inventory.ini -a 'uptime'                 # implicit -m command

# With privilege escalation (prompt for the sudo password with -K)
ansible db -i inventory.ini -b -K -m ansible.builtin.apt -a 'name=htop state=present'
```

`-i` accepts a path **or** a comma-separated host list (note the trailing comma):
`ansible all -i 'host1.example.com,' -m ping`.

### 2. Inventory basics (INI and YAML)

```ini
# inventory.ini
[web]
web1.example.com
web2.example.com ansible_host=10.0.0.12

[db]
db1.example.com

[prod:children]      # a group of groups
web
db

[web:vars]
ansible_user=deploy
```

```yaml
# inventory.yml  (auto-detected by the `auto` plugin via the top-level groups)
all:
  children:
    web:
      hosts:
        web1.example.com:
        web2.example.com:
          ansible_host: 10.0.0.12
      vars:
        ansible_user: deploy
    db:
      hosts:
        db1.example.com:
```

Variables also live in **`group_vars/<group>.yml`** and **`host_vars/<host>.yml`** beside the
inventory or the playbook. Inspect what Ansible parsed:

```bash
ansible-inventory -i invento

Related in Ads & Marketing