Introduction
Running a playbook is only part of Ansible work. You also need to inspect task output, understand the recap, and verify the final managed-node state.
In this lab, you will run a playbook with ansible-navigator, create managed files, run the playbook again, and inspect the evidence that the desired state is present.
Prepare the Project Configuration
In this step, you will create a project that navigator can run without extra command-line options. The configuration is similar to the previous lab, but this time the playbook will manage multiple files.
Create and enter the project.
cd /home/labex/project
mkdir -p rhce-ansible/{inventory/group_vars,playbooks,files}
cd rhce-ansible
Create the inventory and configuration files.
cat > inventory/hosts <<'EOF'
[managed]
node1 ansible_connection=local
EOF
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
retry_files_enabled = False
interpreter_python = auto_silent
EOF
The inventory creates a managed group with one local host alias. The ansible.cfg file makes that inventory the default, so navigator can run the playbook from the project directory without extra inventory flags.
cat > ansible-navigator.yml <<'EOF'
---
ansible-navigator:
mode: stdout
execution-environment:
enabled: false
playbook-artifact:
enable: false
EOF
The navigator settings keep this lab terminal-oriented. mode: stdout prints task output directly, local execution avoids container setup, and disabling artifacts keeps the visible project files limited to the ones you create.
Create Source Content for the Playbook
In this step, you will create source content that the playbook will deploy. Keeping source files under the project makes it clear what Ansible owns.
Before running commands in this step, return to the project directory so relative paths refer to the Ansible project.
cd /home/labex/project/rhce-ansible
Create a source file.
cat > files/motd.txt <<'EOF'
RHCE Ansible navigator practice host
EOF
This is source content: it is the file you want Ansible to deploy, not the final managed copy. Keeping source files separate from generated output makes it easier to see what the playbook owns.
Create a target directory path variable in an inventory group variable file. Keeping this file under inventory/group_vars makes it load consistently when playbooks are stored in a subdirectory.
mkdir -p inventory/group_vars
cat > inventory/group_vars/all.yml <<'EOF'
managed_dir: /home/labex/project/rhce-ansible/managed-state
EOF
managed_dir is a project-specific variable. Defining it in inventory/group_vars/all.yml lets the playbook refer to a name instead of repeating the same absolute path in every task.
Write the Managed-State Playbook
In this step, you will write a playbook that creates a directory and copies a file into it. The file module manages directories and permissions; the copy module deploys file content. Because this playbook lives in the playbooks directory, the source path ../files/motd.txt points back to the project-level files directory.
Before running commands in this step, return to the project directory so relative paths refer to the Ansible project.
cd /home/labex/project/rhce-ansible
Create playbooks/manage-state.yml.
cat > playbooks/manage-state.yml <<'EOF'
---
- name: Manage local state with navigator
hosts: managed
gather_facts: false
tasks:
- name: Create managed state directory
ansible.builtin.file:
path: "{{ managed_dir }}"
state: directory
mode: '0755'
- name: Deploy managed message
ansible.builtin.copy:
src: ../files/motd.txt
dest: "{{ managed_dir }}/motd.txt"
mode: '0644'
EOF
Read the playbook in order. The first task ensures the destination directory exists, and the second task copies the source file into that directory. The {{ managed_dir }} expressions are replaced with the value loaded from inventory/group_vars/all.yml.
Run a syntax check before changing the system.
ansible-playbook playbooks/manage-state.yml --syntax-check
This check is still useful even though you will run the playbook with navigator. Navigator hands the playbook to Ansible, so a playbook that fails normal syntax parsing will also fail through navigator.
Run the Playbook with Navigator
In this step, you will execute the playbook. The recap line is important: ok counts tasks that reached the desired state, changed counts tasks that modified something, and failed=0 means the run completed successfully.
Before running commands in this step, return to the project directory so relative paths refer to the Ansible project.
cd /home/labex/project/rhce-ansible
Run the playbook.
ansible-navigator run playbooks/manage-state.yml
Inspect the managed output file directly.
The recap tells you whether the run completed, but the managed file proves the requested state exists. You should see the same text you placed in files/motd.txt.
cat managed-state/motd.txt
Run Again and Inspect Idempotence
In this step, you will run the same playbook again. A well-written playbook should be safe to repeat. If the file already has the requested content and permissions, Ansible should not need to change it again.
Before running commands in this step, return to the project directory so relative paths refer to the Ansible project.
cd /home/labex/project/rhce-ansible
Run the playbook a second time and save the output.
ansible-navigator run playbooks/manage-state.yml | tee navigator-second-run.txt
Search for the recap. The exact spacing can vary, but the recap should still show no failures.
The second run is about repeatability. A clean run with failed=0 proves the playbook can be applied again without breaking the managed state; if changed=0 appears as well, it also shows the tasks were already satisfied.
grep -E 'failed=0' navigator-second-run.txt
Summary
You ran a playbook with ansible-navigator, inspected the managed file it created, and repeated the playbook to check that it can run again cleanly. This is the basic run-inspect-verify loop used throughout Ansible automation work.



