Skip to main content
intermediate Free with email

Ansible Commands Cheat Sheet: Basics to Advanced Automation (Free PDF)

Reviewed 2026-10-20

Direct answer
The Ansible commands you use most are ansible for ad hoc tasks, ansible-playbook, ansible-inventory, ansible-doc, ansible-vault and ansible-galaxy. This free 48-page PDF covers them with modules, variables, patching and RHEL Leapp upgrades, built for Linux admins and DevOps engineers who run playbooks against real servers.

The Ansible commands you’ll use most are ansible for ad hoc tasks, ansible-playbook to run playbooks, ansible-inventory to check your hosts, ansible-doc to read module documentation, ansible-vault for secrets and ansible-galaxy for collections. Before any change, run --syntax-check, then --check --diff, then limit the run with --limit. This free 48-page PDF covers those commands plus modules, variables, patching and RHEL Leapp upgrades. This page shows the ones to learn first.

Ansible commands list: the seven command-line tools

Seven tools cover most daily work, and each does one job. Run ansible --version first so you know which release you’re on.

CommandWhat it doesExample
ansibleRuns one module on a set of hosts (ad hoc)ansible all -i inventory.ini -m ansible.builtin.ping
ansible-playbookRuns a playbookansible-playbook site.yml --check --diff
ansible-inventoryShows how Ansible reads your inventoryansible-inventory -i inventory.ini --graph
ansible-docShows module and plugin documentationansible-doc ansible.builtin.copy
ansible-vaultEncrypts and edits secret filesansible-vault create group_vars/prod/vault.yml
ansible-galaxyInstalls collections and rolesansible-galaxy collection install -r requirements.yml
ansible-configShows which settings are activeansible-config dump --only-changed

Ansible’s own CLI cheat sheet lists more flags for each tool. The PDF puts the same commands in the order you’d use them on a real server.

Ansible ad hoc commands: run one task on many hosts

An ad hoc command runs one module on one or more hosts without a playbook. The pattern is ansible <hosts> -i <inventory> -m <module> -a "<arguments>". According to Ansible’s ad hoc documentation, ad hoc commands are quick but not reusable, so move anything you repeat into a playbook.

ansible all -i inventory.ini -m ansible.builtin.ping
ansible web -i inventory.ini -m ansible.builtin.setup
ansible localhost -m ansible.builtin.apt -a "name=apache2 state=present" -b -K

The first line tests that Ansible can log in and run Python on every host. The second collects facts from the web group. The third installs a package: -b escalates privilege and -K asks for the sudo password.

Ad hoc commands answer “is it up?” and “what’s on it?”. Playbooks answer “make it look like this”. Not sure whether to learn Ansible or Terraform first? Read Terraform vs Ansible: which one to learn first.

Ansible inventory commands: check your hosts before you run anything

Inventory tells Ansible who to talk to. Check how Ansible reads it before every run with ansible-inventory --graph.

# inventory.ini
[web]
web01 ansible_host=10.10.10.11
web02 ansible_host=10.10.10.12

[db]
db01 ansible_host=10.10.20.11

[prod:children]
web
db

[all:vars]
ansible_user=automation
ansible-inventory -i inventory.ini --graph
ansible-inventory -i inventory.ini --list

--graph shows your groups as a tree. --list prints the full inventory as JSON, including host variables. A static file is fine for a lab. Once your hosts change every week, switch to an inventory plugin instead of editing text. Our NetBox dynamic inventory for Ansible guide shows one that stays accurate.

Ansible playbook commands: run, check and limit safely

Run every playbook in the same order: syntax check, dry run with a diff, one host, then the full run. These flags come straight from the PDF’s safe-execution section.

CommandWhat it does
ansible-playbook site.yml --syntax-checkCatches YAML and structure errors before anything runs
ansible-playbook site.yml --list-hostsShows which hosts the play would touch
ansible-playbook site.yml --list-tasksLists the tasks in order
ansible-playbook site.yml --check --diffDry run, and shows the file changes it would make
ansible-playbook site.yml --limit web01Runs on one host or group only
ansible-playbook site.yml --tags patchRuns only tasks with that tag
ansible-playbook site.yml --skip-tags rebootSkips tasks with that tag
ansible-playbook site.yml --start-at-task "Validate service"Resumes at a named task
ansible-playbook site.yml -vvAdds detail when a task fails

A minimal playbook looks like this. Give every task a name, use fully qualified collection names such as ansible.builtin.package, and keep one job per task.

---
- name: Baseline Linux configuration
  hosts: linux
  become: true
  gather_facts: true
  vars:
    package_name: chrony
  tasks:
    - name: Install chrony
      ansible.builtin.package:
        name: "{{ package_name }}"
        state: present

    - name: Enable and start the service
      ansible.builtin.service:
        name: chronyd
        state: started
        enabled: true

Tags let you run a slice of a big playbook:

- name: Patch operating system
  ansible.builtin.dnf:
    name: "*"
    state: latest
  tags: [patch]

- name: Reboot if required
  ansible.builtin.reboot:
    reboot_timeout: 900
  tags: [reboot]

Check mode is an aid, not a guarantee. Not every module can predict its changes, so read the diff and don’t treat a clean dry run as proof. Ansible’s check mode documentation explains where it falls short.

Ansible playbook commands in three steps: ansible-playbook --syntax-check, --check --diff and --limit
Ansible playbook commands: syntax-check, dry run with diff, then limit the run to one host.

What does idempotent mean in Ansible?

An idempotent task gives the same result whether you run it once or ten times. If the system already matches what you asked for, Ansible reports ok and changes nothing. Modules like package, file and service work this way. command and shell don’t, because Ansible can’t tell what a command did, so you add a guard.

- name: Run a one-time migration
  ansible.builtin.command: /usr/local/bin/migrate-db
  args:
    creates: /var/lib/myapp/.migration-v2-complete

- name: Check application health
  ansible.builtin.command: /usr/local/bin/healthcheck
  register: health
  changed_when: false
  failed_when:
    - health.rc != 0
    - "'WARNING' not in health.stdout"

creates skips the task when the file already exists. changed_when: false stops a read-only command from reporting a change. failed_when lets you decide what counts as a failure. A task that reports changed on every run is the first sign of a missing guard. Interviewers ask about this all the time, and our 120 Ansible interview questions answer it precisely.

Ansible command vs shell: which module should you use?

Use command unless you need shell features such as pipes or redirection. It runs the program directly, so there’s no shell parsing and fewer surprises. shell runs through a shell, so pipes work, but you must add set -o pipefail and a changed_when yourself. raw skips the normal module transport and is mainly for bootstrapping.

- name: Run a command without a shell
  ansible.builtin.command:
    argv:
      - /usr/bin/ss
      - -lntup
  register: sockets
  changed_when: false

- name: Use shell only when shell features are required
  ansible.builtin.shell: |
    set -o pipefail
    rpm -qa | sort | head -20
  args:
    executable: /bin/bash
  register: rpm_sample
  changed_when: false

Both modules have full reference pages in Ansible’s docs: ansible.builtin.command and ansible.builtin.shell.

Ansible command vs shell module: command uses argv and creates, shell needs pipefail and changed_when
Ansible command vs shell: use command unless you need pipes, and guard shell with pipefail and changed_when.

Go deeper

Reading a playbook isn’t the same as running one.

This PDF shows you the commands. The DevOps Certification Workbook has you run them, with Ansible fundamentals, playbooks and roles, and Ansible Vault sitting next to Git, CI/CD, Docker, Kubernetes and Terraform. Start a lab, break it, fix it, and the flags stop being trivia.

See the DevOps Certification Workbook →

ansible-doc command: find any module or plugin from the terminal

ansible-doc shows the documentation for the Ansible you have installed, so the answer always matches your version. Start with ansible-doc -l.

ansible-doc -l
ansible-doc ansible.builtin.copy
ansible-doc ansible.builtin.package
ansible-doc -t filter -l
ansible-doc -t test -l
ansible-doc -t lookup -l
ansible-doc -t connection -l
ansible-doc -t become -l
ansible-galaxy collection list
ansible-config dump --only-changed

-t picks the plugin type: filter, test, lookup, connection, become, callback, strategy, inventory or vars. ansible-galaxy collection list shows which collections are installed, and ansible-config dump --only-changed shows the settings you’ve changed. The full option list is in the ansible-doc reference.

Ansible Vault commands: create, edit and view encrypted files

Ansible Vault encrypts variable files so secrets can sit next to your playbooks without being readable. The PDF covers create, edit and view, plus the flag that asks for the password at run time.

ansible-vault create group_vars/prod/vault.yml
ansible-vault edit group_vars/prod/vault.yml
ansible-vault view group_vars/prod/vault.yml
ansible-playbook site.yml --ask-vault-pass

According to Ansible’s ansible-vault reference, the same tool also has encrypt, decrypt, encrypt_string and rekey. You can pass the password with --ask-vault-pass, --vault-password-file or --vault-id.

- name: Configure application secret
  ansible.builtin.template:
    src: app-secret.conf.j2
    dest: /etc/myapp/secret.conf
    mode: "0600"
  no_log: true

Three rules. Never put plaintext production secrets in Git. Add no_log: true to any task that might print one. And remember that Vault encrypts Ansible data, but it doesn’t protect a secret you pass on a command line.

Ansible modules cheat sheet: where each module lives

A module name that works on one control node fails on another when its collection isn’t installed. You’ll see a “couldn’t resolve module/action” error. Check where a module lives before you copy it.

CollectionModules you’ll useInstall needed?
ansible.builtinfile, copy, template, lineinfile, blockinfile, dnf, apt, package, service, systemd, user, group, command, shell, reboot, setup, stat, find, unarchive, uri, get_url, wait_for, cron, hostnameNo, ships with ansible-core
ansible.posixauthorized_key, acl, mount, sysctl, firewalldYes
community.generalfilesystem, lvol, lvg, parted, timezone, archiveYes

List the collections you depend on in requirements.yml, so CI and your colleagues build the same environment:

# requirements.yml
collections:
  - name: ansible.posix
  - name: community.general
  - name: redhat.leapp
ansible-galaxy collection install -r requirements.yml

ansible-galaxy is the command that installs collections and roles. Ansible Galaxy is the public hub where they’re shared. Verify any module with ansible-doc first.

The file module sets owner, group and mode, so keep our chmod, chown and umask cheat sheet next to you. New to the Linux side? The Linux commands cheat sheet covers the shell commands behind these modules.

- name: Create application directory
  ansible.builtin.file:
    path: /opt/myapp
    state: directory
    owner: appuser
    group: appuser
    mode: "0750"

Want these modules in a lab, not a table? The DevOps Workbook lists Ansible fundamentals, playbooks and roles, and Ansible Vault in its Infrastructure as Code and Cloud DevOps chapter.

Ansible modules cheat sheet: ansible.builtin modules ship with ansible-core, ansible.posix and community.general need installing
Ansible modules cheat sheet: builtin modules ship with ansible-core, while ansible.posix and community.general need to be installed.

Ansible facts, variables, when and loop

Facts are information Ansible gathers about each host: OS family, kernel, memory and interfaces. Read them through the ansible_facts dictionary.

- name: Show selected facts
  hosts: linux
  gather_facts: true
  tasks:
    - name: Print selected facts
      ansible.builtin.debug:
        msg:
          hostname: "{{ ansible_facts['hostname'] }}"
          os: "{{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}"
          kernel: "{{ ansible_facts['kernel'] }}"
          memory_mb: "{{ ansible_facts['memtotal_mb'] }}"

Older playbooks use injected names such as ansible_hostname. According to Ansible’s ansible-core 2.20 porting guide, those are deprecated and the default switches in 2.24, so write ansible_facts['hostname'] in new code.

Conditionals and loops use Jinja expressions. Don’t wrap a when expression in {{ }}.

- name: Restart only on RHEL 9
  ansible.builtin.service:
    name: myapp
    state: restarted
  when:
    - ansible_facts['os_family'] == "RedHat"
    - ansible_facts['distribution_major_version'] | int == 9

- name: Install multiple packages
  ansible.builtin.package:
    name: "{{ item }}"
    state: present
  loop:
    - curl
    - rsync
    - tar

Group risky steps in block, rescue and always so a failure runs your recovery task and a final status check either way.

Ansible handlers and Jinja2 templates: restart only when something changed

A handler runs when a task notifies it, and by default at the end of the play. Use one for every restart that depends on a config change.

tasks:
  - name: Deploy configuration
    ansible.builtin.template:
      src: myapp.conf.j2
      dest: /etc/myapp.conf
    notify: Restart myapp

handlers:
  - name: Restart myapp
    ansible.builtin.systemd:
      name: myapp
      state: restarted

The template renders variables and logic before the file is copied:

# templates/myapp.conf.j2
server_name = {{ inventory_hostname }}
listen_port = {{ app_port }}
{% for backend in backends %}
backend = {{ backend }}
{% endfor %}

Keep complex logic out of templates when you can compute it in vars or set_fact, and use to_json or to_yaml when you embed structured data.

Ansible patching playbook for RHEL, Rocky, Alma and Ubuntu

One playbook can patch both families if you branch on os_family and limit the batch with serial.

- name: Linux patch baseline
  hosts: linux
  become: true
  serial: 10
  tasks:
    - name: Update RHEL-family hosts
      ansible.builtin.dnf:
        name: "*"
        state: latest
        update_cache: true
      when: ansible_facts['os_family'] == "RedHat"

    - name: Update Debian-family hosts
      ansible.builtin.apt:
        name: "*"
        state: latest
        update_cache: true
      when: ansible_facts['os_family'] == "Debian"

Then decide on a reboot. On RHEL-family systems, needs-restarting -r returns a non-zero code when one is needed, so register the result and test it. The command has to be installed on the host.

- name: Check whether a reboot is required (RHEL family)
  ansible.builtin.command: needs-restarting -r
  register: reboot_check
  changed_when: false
  failed_when: false
  when: ansible_facts['os_family'] == "RedHat"

- name: Reboot if required
  ansible.builtin.reboot:
    reboot_timeout: 1200
  when:
    - ansible_facts['os_family'] == "RedHat"
    - reboot_check.rc | default(0) != 0

After the reboot, prove the service came back instead of assuming it did:

- name: Collect service state
  ansible.builtin.service_facts:

- name: Assert application service is running
  ansible.builtin.assert:
    that:
      - ansible_facts.services['myapp.service'].state == 'running'
    fail_msg: "myapp is not running after reboot"

A full patch workflow has prechecks, a repository health check, a disk space check, a drain or maintenance step, the update, the reboot decision, service validation and post-checks.

RHEL Leapp upgrade with Ansible: analyse first, upgrade last

An in-place RHEL major upgrade is a different job from patching. Run leapp preupgrade, read the report, fix every inhibitor, then upgrade in a change window with an approval step.

leapp preupgrade --target-version 9.8
less /var/log/leapp/leapp-report.txt

Replace the target with a path Red Hat supports for your source release. Red Hat ships the redhat.leapp collection with analysis, remediate and upgrade roles. According to Red Hat’s upgrade documentation, the control node for these roles must run RHEL 9 or RHEL 10.

- name: RHEL pre-upgrade analysis using the Red Hat Leapp role
  hosts: rhel8
  become: true
  tasks:
    - name: Generate pre-upgrade analysis
      ansible.builtin.import_role:
        name: redhat.leapp.analysis
      vars:
        leapp_upgrade_type: cdn

Don’t continue automatically from the analysis to the upgrade. Review the report, resolve the inhibitors, and confirm the exact source and target path first. Don’t run configuration or deployment tasks during the upgrade phase either.

Ansible roles, collections and project layout

A role is a reusable folder of tasks, handlers, templates, files and defaults. A collection packages roles, modules and plugins. Keep production and non-production inventories apart, pin your collection versions, and put the guardrails in the playbook: assertions, serial, tags and explicit limits.

ansible-project/
  ansible.cfg
  requirements.yml
  inventories/
    production/
    nonprod/
  playbooks/
    site.yml
    patch.yml
  roles/
    baseline/
  collections/

Two settings matter early:

# ansible.cfg
[defaults]
inventory = inventory.ini
forks = 20
timeout = 30

[ssh_connection]
pipelining = true

forks sets how many hosts run at once. Don’t raise it blindly: your network, package repositories and application capacity become the bottleneck.

Ansible troubleshooting: symptom, likely cause, first check

SymptomLikely areaFirst checks
UNREACHABLESSH, network or authssh -v, inventory, DNS, route, key, user
Permission deniedsudo, become or file modesbecome, sudoers, file ownership and mode
Module not foundCollection or versionansible-doc, ansible-galaxy collection list
Task changed every runIdempotenceModule choice, changed_when, command side effects
YAML errorSyntax or indentationansible-playbook site.yml --syntax-check
Fact missingFact gathering or platformsetup, gather_subset, exact fact name
Template errorJinja or undefined variable-vvv, assert the variable is defined
TimeoutNetwork or applicationtimeout, wait_for, async and poll

For an UNREACHABLE host, rule out the network before you blame Ansible. Our network troubleshooting commands cheat sheet covers ping, traceroute and the checks around them.

Where does this free Ansible PDF stop?

The PDF is a reference. You can read every playbook in it, but nothing breaks while you watch. The DevOps Certification Workbook pairs its Ansible chapters with ready-to-use Git repositories, Docker Compose files and Helm charts, so you can start a first lab in under ten minutes. Preview its sample pages on the workbook page before you decide.

What to read next:

Free Ansible commands PDF with 48 pages of examples compared with the DevOps workbook with Ansible labs
The free Ansible commands PDF gives you examples to read, and the DevOps workbook gives you labs to run.

Frequently asked questions

What are the basic commands in Ansible?
Seven cover most work: ansible for ad hoc tasks, ansible-playbook to run playbooks, ansible-inventory to check hosts, ansible-doc for module documentation, ansible-vault for secrets, ansible-galaxy for collections and ansible-config for settings. Each tool does one job. Run ansible --version first to see which release you're on.
How do I run an Ansible ad hoc command?
Use the ansible command with a host pattern, an inventory and a module, for example ansible all -i inventory.ini -m ansible.builtin.ping. Add -a for module arguments and -b to escalate privilege. According to Ansible's documentation, ad hoc commands are quick but not reusable, so repeat jobs belong in a playbook.
What is the difference between ansible and ansible-playbook?
ansible runs one module once against your hosts, which suits quick checks like ping or uptime. ansible-playbook runs a YAML file of ordered tasks, variables and handlers that you can repeat and keep in Git. Use ansible to ask a question, and ansible-playbook to make hosts match a state.
What are the Ansible Vault commands?
ansible-vault create, edit and view manage an encrypted file. According to Ansible's reference, the tool also has encrypt, decrypt, encrypt_string and rekey. Run a playbook with --ask-vault-pass, --vault-password-file or --vault-id. Never commit plaintext production secrets, and add no_log: true to tasks that could print one.
Is Ansible YAML or Python?
Both. You write playbooks, inventories and variables in YAML, and you don't need to write Python to do that. Ansible itself and its modules are written in Python, and you only write Python when you build a custom module or plugin. The control node needs Python installed either way.
What does idempotent mean in Ansible?
An idempotent task gives the same result whether you run it once or ten times. If the host already matches the state you asked for, Ansible reports ok and changes nothing. Modules like package, file and service behave this way. command and shell don't, so add creates, changed_when or failed_when.
What is the difference between command and shell in Ansible?
command runs a program directly with no shell parsing, so it's safer and the default choice. shell runs through a shell, so pipes, redirects and expansion work, but you need set -o pipefail and a changed_when. raw skips the normal module transport and is mainly used to bootstrap a host.
How do I list Ansible modules and plugins?
Run ansible-doc -l to list every module your installation can see, and ansible-doc followed by a module name, such as ansible.builtin.copy, to read its options. Add -t with filter, test, lookup, connection or become to list plugins of that type. The output always matches your installed version.

Reviewed by

CCDE/CCIE

How to cite this resource

SMEnode Labs (2026). Ansible Commands Cheat Sheet: Basics to Advanced Automation (Free PDF). SMEnode Labs. https://smenode-labs.com/free-pdf/devops/ansible-commands/

APA

SMEnode Labs. (2026). Ansible Commands Cheat Sheet: Basics to Advanced Automation (Free PDF). SMEnode Labs. https://smenode-labs.com/free-pdf/devops/ansible-commands/

BibTeX

@misc{smenodelabs2026,
  title = {Ansible Commands Cheat Sheet: Basics to Advanced Automation (Free PDF)},
  author = {{SMEnode Labs}},
  year = {2026},
  url = {https://smenode-labs.com/free-pdf/devops/ansible-commands/},
  note = {SMEnode Labs}
}