How to Run Ansible Playbooks with ansible-playbook and ansible-navigator

Run Ansible playbooks with ansible-playbook and ansible-navigator—inventory, --limit, --syntax-check, --check, --diff, verbosity, tags, become, extra vars, and stdout mode.

Published

Updated

Read time 13 min read

Reviewed byDeepak Prasad

Run Ansible playbooks with ansible-playbook and ansible-navigator on Rocky Linux 10

After you write an Ansible playbook, the next question is usually: how do I run it safely? A normal run is simple, but real usage often needs more control—checking syntax first, limiting the target hosts, previewing changes, showing diffs, running only tagged tasks, or using ansible-navigator with an execution environment.

This guide shows the commands you will actually use while testing and running playbooks, starting with a simple run and then adding safer options such as --syntax-check, --list-hosts, --check, --diff, --limit, and --tags.

Read playbook structure and YAML syntax first. This page does not teach playbook anatomy, tag design, or ansible-navigator.yml settings—those live in dedicated guides linked below.

Tested on: Rocky Linux 10.2 (Red Quartz); kernel 6.12.0-211.16.1.el10_2.0.1.x86_64; ansible-core 2.16.16; ansible-navigator 26.6.0.

NOTE
This chapter is part of the GoLinuxCloud Ansible tutorial (RHCE EX294). Follow along from ~/ansible-project, inventory group lab, and playbooks in playbooks/. Use your own host names and paths if yours differ.
Tool Best for
ansible-playbook Simple local playbook execution
ansible-playbook --check --diff Previewing changes safely
ansible-playbook --limit Restricting a run to selected hosts
ansible-playbook --tags Running selected tagged tasks
ansible-navigator run TUI or stdout execution and EE-based workflows
ansible-navigator run --mode stdout Script-friendly navigator output

For a new playbook, do not jump straight to a full run on every host. First confirm that Ansible can parse the file, then confirm which hosts match, then preview the change, then run on one host or a small group. Once that works, run the full playbook.


What Happens When You Run an Ansible Playbook?

When you run a playbook, Ansible:

  1. Loads ansible.cfg from the project directory
  2. Resolves inventory (from -i or config)
  3. Parses the playbook YAML and builds plays and tasks
  4. Connects to each matched host over SSH
  5. Runs tasks in order and collects results
  6. Prints per-task status and a PLAY RECAP summary

Failures on a host stop further tasks on that host unless you use rescue blocks (see block and rescue).


ansible-playbook vs ansible-navigator

ansible-playbook ansible-navigator run
Runs on Control node (local ansible-core) Wraps playbook runs; may use execution environment (container)
UI Plain terminal output Interactive TUI or --mode stdout
Best when Scripts, CI, quick runs Browsing collections, EE images, artifact replay

Both execute the same playbook tasks—the difference is wrapper features and optional container isolation.


Basic ansible-playbook Syntax

bash
ansible-playbook playbooks/run-demo.yml

Common options you will use in this guide:

Option Short Purpose
--inventory -i Inventory path or plugin
--limit Narrow hosts at runtime
--syntax-check Validate YAML and playbook shape
--check -C Check mode (dry run)
--diff Show file diffs
--tags Run tagged tasks only
--skip-tags Skip tagged tasks
--start-at-task Start execution at a named task
--extra-vars -e Pass runtime variables
--become -b Privilege escalation
--ask-become-pass -K Prompt for become password
-v / -vv / -vvv Increase verbosity

Create a small demo playbook for the examples below:

bash
cat > ~/ansible-project/playbooks/run-demo.yml << 'EOF'
---
- name: Run demo
  hosts: lab
  gather_facts: false
  tasks:
    - name: Ping hosts
      ansible.builtin.ping:
      tags: [always]

    - name: Ensure demo dir
      ansible.builtin.file:
        path: /tmp/run-demo
        state: directory
        mode: "0755"
      tags: [config]

    - name: Debug skip me
      ansible.builtin.debug:
        msg: optional task
      tags: [optional]
EOF

Run a Playbook with Inventory

Use -i when you want to be explicit about which inventory Ansible should use. This is helpful when you have multiple inventories, when you are outside the project directory, or when you are testing a temporary inventory file.

Point at an inventory file explicitly:

bash
ansible-playbook -i inventory/hosts playbooks/run-demo.yml --syntax-check

Sample output:

output
playbook: playbooks/run-demo.yml

-i accepts a file, directory, or plugin source. If you skip -i and Ansible cannot find a default inventory, you may get an empty host list or connect to the wrong machines—being explicit avoids that surprise on the first run.


Run a Playbook Using Inventory from ansible.cfg

In a real project, you usually do not want to type -i inventory/hosts every time. Keeping the inventory path in ansible.cfg makes playbook commands shorter and reduces mistakes when the same project is used repeatedly.

Most projects set a default inventory in ansible.cfg so you can omit -i:

bash
ansible-config dump | grep DEFAULT_HOST_LIST

Sample output:

output
DEFAULT_HOST_LIST(/home/ansible/ansible-project/ansible.cfg) = ['/home/ansible/ansible-project/inventory/hosts']

From the project root, this is enough:

bash
ansible-playbook playbooks/run-demo.yml

Ansible picks up inventory/hosts automatically.


List Target Hosts Before Running

Before a risky run, check which hosts the playbook will target:

bash
ansible-playbook playbooks/run-demo.yml --list-hosts

Sample output:

output
playbook: playbooks/run-demo.yml

  play #1 (lab): Run demo	TAGS: []
    pattern: ['lab']
    hosts (1):
      rocky2

This is worth doing before any risky run. It is much easier to catch a wrong host list here than after a playbook has already changed the wrong machine.


Target Hosts with --limit

--limit narrows which inventory hosts run—even if the play lists a broader group:

bash
ansible-playbook playbooks/run-demo.yml --limit rocky2

Sample output:

output
PLAY [Run demo] ****************************************************************

TASK [Ping hosts] **************************************************************
ok: [rocky2]

Useful for testing one machine before rolling out to a group. Combine with host patterns from inventory patterns; double-check the limit before production runs.


Check Playbook Syntax Before Running

--syntax-check is the first command to run after editing a playbook. It catches YAML parsing problems and many playbook-structure errors before Ansible connects to managed hosts.

Validate a new or edited playbook without executing tasks:

bash
ansible-playbook playbooks/run-demo.yml --syntax-check

Sample output:

output
playbook: playbooks/run-demo.yml

If the command prints only the playbook path and exits cleanly, Ansible was able to read the YAML and understand the playbook structure. It does not prove that the playbook logic is correct, that the target package exists, or that every task will succeed. See YAML validation for parse-error examples. When syntax passes but task logic fails, use debug Ansible playbooks to inspect variables and registered output.


Preview Changes with Check Mode

Use check mode when you want to see what Ansible would do without making real changes yet. It is especially helpful before package installs, service restarts, or file updates on shared systems.

Check mode (--check or -C) asks supported modules to report what would change without applying it:

bash
ansible-playbook playbooks/run-demo.yml --check

Sample output:

output
PLAY RECAP *********************************************************************
rocky2                     : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

If /tmp/run-demo does not exist yet, the file task may report changed in check mode because Ansible predicts that it would create the directory. That predicted change is expected; it does not mean the directory was actually created.

Not every module supports check mode the same way—some fully support it, some partially, and some skip or behave differently. Check mode is a simulation that depends on module support. Always verify important changes on a lab host before trusting --check as a production gate.


Show File Changes with Diff Mode

Use --diff when you need to see the actual file content Ansible would write—not just whether a task reports changed. It is most useful with copy, template, and similar modules.

--diff shows content changes for modules such as copy and template. Create a small copy playbook:

bash
cat > ~/ansible-project/playbooks/diff-demo.yml << 'EOF'
---
- name: Diff demo
  hosts: lab
  gather_facts: false
  tasks:
    - name: Deploy motd snippet
      ansible.builtin.copy:
        dest: /tmp/run-demo/motd.txt
        content: "Managed by Ansible\n"
        mode: "0644"
EOF

Preview the change:

bash
ansible-playbook playbooks/diff-demo.yml --check --diff

Sample output:

output
TASK [Deploy motd snippet] *****************************************************
--- before
+++ after: /tmp/run-demo/motd.txt
@@ -0,0 +1 @@
+Managed by Ansible

changed: [rocky2]

The --- / +++ block is the preview of what would be written on disk.

Be careful with --diff on files that may contain secrets, because changed content can appear in terminal output or CI logs.

For file-heavy playbooks, keep using both flags together: --check predicts whether a task would change, and --diff shows the file content that would be written. The diff demo above already uses both. After the preview looks correct, run the same playbook again without --check to apply the change.


Increase Output with Verbosity

When a playbook fails and the default output is too short, add -v (up to -vvvv) for more connection and module detail:

bash
ansible-playbook playbooks/run-demo.yml -v

Sample output:

output
Using /home/ansible/ansible-project/ansible.cfg as config file

PLAY [Run demo] ****************************************************************

TASK [Ping hosts] **************************************************************
ok: [rocky2] => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "changed": false, "ping": "pong"}

Start with -v for module JSON; use -vvv or -vvvv when debugging SSH or plugin issues.


Run Selected Tasks with Tags

Tags let you include or exclude parts of a playbook at runtime. Overview only—see Ansible tags for design patterns.

Avoid putting broad tags at play level unless you want every task in that play to inherit them. Ansible inherits tags from plays, blocks, roles, and imports—play-level tags can make --tags run more tasks than you expect.

Use --tags

Run tasks that match a tag. Tasks tagged always still run unless you explicitly skip that tag:

bash
ansible-playbook playbooks/run-demo.yml --tags config

Sample output:

output
PLAY RECAP *********************************************************************
rocky2                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Here ping (tag always) and Ensure demo dir (tag config) ran—the optional debug task did not.

Use --tags when you want only install, config, or deploy slices—see Ansible tags for how to design tag names.

Use --skip-tags

Skip tasks with a given tag:

bash
ansible-playbook playbooks/run-demo.yml --skip-tags optional

Sample output:

output
PLAY RECAP *********************************************************************
rocky2                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

The optional debug task did not run—PLAY RECAP shows two tasks instead of three.

List available tags

bash
ansible-playbook playbooks/run-demo.yml --list-tags

Sample output:

output
playbook: playbooks/run-demo.yml

  play #1 (lab): Run demo	TAGS: []
      TASK TAGS: [always, config, optional]

List Tasks Before Running

Use --list-tasks when you want to see which task names Ansible will run without executing them:

bash
ansible-playbook playbooks/run-demo.yml --list-tasks

Sample output:

output
playbook: playbooks/run-demo.yml

  play #1 (lab): Run demo	TAGS: []
    tasks:
      Ping hosts	TAGS: [always]
      Ensure demo dir	TAGS: [config]
      Debug skip me	TAGS: [optional]

This is useful before combining --tags, --skip-tags, or --limit in larger playbooks.

Use --start-at-task "Task name" only for troubleshooting or resuming a failed run carefully. It skips earlier tasks, so required setup may be missing.


Use Privilege Escalation While Running Playbooks

Many tasks need root on the managed host—installing packages, managing services, or writing files under /etc. You can set become: true in the playbook, in ansible.cfg, or pass it at runtime.

Use -b when the playbook needs root privileges but become: true is not already set in the playbook or ansible.cfg. This is common for package installation, service management, files under /etc, or other root-owned paths.

Use -K only when the remote sudo configuration requires a password. If your automation account has passwordless sudo, -b is usually enough.

Run with privilege escalation:

bash
ansible-playbook playbooks/run-demo.yml -b

If sudo requires a password, combine -b with -K:

bash
ansible-playbook playbooks/run-demo.yml -b -K

If become: true is already set in the playbook or ansible.cfg, you may only need -K to provide the password.

Your ansible.cfg may already set become = True—check before adding -b so you do not wonder why privilege escalation is already active.


Pass Extra Variables at Runtime

Use -e / --extra-vars when you need a one-time override at run time—for example, changing a greeting message, toggling a feature flag, or passing a version number without editing the playbook.

Extra variables have high precedence, so they can override values from inventory, group vars, host vars, and play vars. Use them carefully for one-time runtime changes, not as a replacement for normal variable files.

Override or supply variables with -e:

bash
cat > ~/ansible-project/playbooks/extra-var-demo.yml << 'EOF'
---
- hosts: lab
  gather_facts: false
  tasks:
    - ansible.builtin.debug:
        msg: "{{ greeting }}"
EOF
bash
ansible-playbook playbooks/extra-var-demo.yml -e greeting=from_cli

Sample output:

output
ok: [rocky2] => {
    "msg": "from_cli"
}

Avoid passing secrets on the command line—they appear in shell history and process lists. Use Ansible Vault or a vars file with restrictive permissions for sensitive values.


Run Playbooks with ansible-navigator

ansible-navigator run wraps ansible-playbook with UI and optional execution environments. Configure defaults in ansible-navigator.yml. Many learners edit playbooks in Visual Studio Code with Ansible and run them from the integrated terminal or navigator.

Run in interactive mode

On a local console with a TTY:

bash
ansible-navigator run playbooks/run-demo.yml

Opens the navigator TUI for task-by-task browsing. Over SSH without a terminal, use stdout mode instead.

Run in stdout mode

Plain playbook output for scripts and remote sessions:

bash
ansible-navigator run playbooks/run-demo.yml --mode stdout

Sample output:

output
PLAY [Run demo] ****************************************************************

TASK [Ping hosts] **************************************************************
ok: [rocky2]

PLAY RECAP *********************************************************************
rocky2                     : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Navigator may add ANSI color codes in your terminal—that is normal for stdout mode.

Run with execution environment enabled

Execution environments are useful when you want the same Ansible version, collections, and Python dependencies everywhere. Instead of relying on whatever is installed on the control node, navigator runs the playbook inside a container image that already contains the required automation content.

With EE enabled (the default in many setups), navigator uses the image defined in ansible-navigator.yml. Choose this when teammates or CI need a predictable toolchain, not when you are doing a quick local test on a small lab VM.

Run with execution environment disabled

When you want navigator's stdout mode or TUI but not a container, disable the execution environment and use the local ansible-core install:

bash
ansible-navigator run playbooks/run-demo.yml --mode stdout --ee false

Matches execution-environment.enabled: false in navigator settings—handy on small lab VMs.


ansible-playbook vs ansible-navigator Output

Both show PLAY, TASK, and PLAY RECAP lines in stdout mode. Differences:

  • ansible-playbook output is the baseline—no TUI, no EE wrapper
  • ansible-navigator may colorize output and can store run artifacts for replay
  • Interactive navigator adds keyboard navigation—not available in plain ansible-playbook

For reading normal PLAY, TASK, and PLAY RECAP output, ansible-playbook and ansible-navigator run --mode stdout look similar. Results can still differ if navigator runs inside an execution environment with different collections, Python packages, or configuration.


Quick Command Reference

Goal Command
Run normally ansible-playbook playbooks/run-demo.yml
Check syntax ansible-playbook playbooks/run-demo.yml --syntax-check
List matched hosts ansible-playbook playbooks/run-demo.yml --list-hosts
Preview changes ansible-playbook playbooks/run-demo.yml --check
Preview file diffs ansible-playbook playbooks/diff-demo.yml --check --diff
Run one host ansible-playbook playbooks/run-demo.yml --limit rocky2
Run tagged tasks ansible-playbook playbooks/run-demo.yml --tags config
Run with navigator stdout ansible-navigator run playbooks/run-demo.yml --mode stdout

Demo playbooks (run-demo.yml, diff-demo.yml, extra-var-demo.yml) are created from the cat blocks earlier in this guide.


Common Playbook Execution Mistakes

Symptom Likely cause Fix
provided hosts list is empty Wrong inventory or host pattern Check -i, ansible.cfg, and play hosts:
Changes on wrong server Typo in --limit Run --list-hosts before limiting
Check mode output is surprising Module has partial/no check support, or task is forced with check_mode: false Read module docs; test on a lab host before production
--diff shows nothing Task is not file-based Use copy/template; some modules have no diff
Navigator fails on SSH Interactive mode without TTY Add --mode stdout
Missing collection in navigator EE image lacks content Install collection or use --ee false locally
Secret leaked -e password=... on CLI Use vault or a protected vars file
--tags config runs too many tasks Tags set at play or role level and inherited by tasks Move broad tags to specific tasks or review tag inheritance

Safe Playbook Run Workflow

Treat this as the default habit for a new or changed playbook—not only for production. A practical sequence before touching every host in the inventory:

  1. ansible-playbook play.yml --syntax-check
  2. Confirm inventory: ansible-playbook play.yml --list-hosts
  3. Preview: ansible-playbook play.yml --check --diff
  4. Limited run: ansible-playbook play.yml --limit staging1
  5. Full run: ansible-playbook play.yml

Add -v when the first failure needs more context.


  • cd into the project root so ansible.cfg and inventory resolve
  • Prefer --syntax-check after every significant playbook edit
  • Use --check --diff before package, file, or template changes on shared systems
  • Use --limit for the first run on a new play
  • Use ansible-navigator run --mode stdout when you want navigator features without the TUI
  • Keep the hands-on first playbook in playbook examples—this page is the CLI reference
  • After your first playbook, learn idempotency before scaling automation

Summary

Run playbooks with ansible-playbook playbooks/site.yml from the project directory, or use ansible-navigator run for stdout or interactive execution. Validate with --syntax-check, preview with --check and --diff, narrow hosts with --limit, and slice work with --tags. Pass runtime data with -e, escalate with -b / -K, and turn up -v when you need deeper logs.


References

  • ansible-playbook command — Ansible documentation
  • ansible-navigator run — navigator run subcommand
  • Tags in Ansible — official tag selection
  • Ansible playbook structure — plays, tasks, handlers
  • ansible-navigator.yml — navigator settings file
  • Ansible tags — tag design and patterns

Frequently Asked Questions

1. What is the difference between ansible-playbook and ansible-navigator?

ansible-playbook runs playbooks directly with ansible-core on the control node. ansible-navigator wraps the same runs with a TUI or stdout mode and optional execution environment containers.

2. Does ansible-playbook --check make real changes?

No. Check mode asks modules that support it to predict changes without applying them. It is a dry run, not a guarantee for every module.

3. When should I use --diff with ansible-playbook?

Use --diff with --check to preview file and template changes before a real run. It is especially useful for copy, template, and lineinfile tasks.

4. How do I run only some tasks in a playbook?

Tag tasks and plays, then use --tags or --skip-tags. Run ansible-playbook playbook.yml --list-tags to see what is available.

5. Why use ansible-navigator --mode stdout?

Stdout mode prints plain playbook output—ideal for SSH sessions, scripts, and tutorials. Interactive mode needs a real terminal for the TUI.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …