Chapter 9: Troubleshooting Ansible
Exercise: Troubleshooting Ansible managed hosts
You will troubleshoot two playbooks that fail on a managed host: one that fails only in check mode, and one that cannot reach its host at all, even though an ad hoc command can.
The project ~/troubleshoot-host has an ansible.cfg, an inventory, the playbooks mailrelay.yml and samba.yml, and their templates. mailrelay.yml sets up servera as a Postfix mail relay; samba.yml is the playbook you fixed in the previous exercise.
Troubleshooting Ansible managed hosts
- Troubleshoot managed hosts with check mode, ad hoc commands and verbose output.
Prerequisites: Complete control-node setup and the preceding lessons in this chapter. Run commands as student on workstation unless a step names another machine.
From the project directory, run the relevant home-lab check. For an exercise with several checkpoints, grade each state before changing or removing it:
lab grade troubleshoot-hostThe grader reads project files and host state. A passing report covers the listed checks; also perform the task’s independent connection, repeat-run, and reboot checks where requested.
Starter files contain deliberate YAML, inventory, or task errors. Repair them before the final checkpoint.
Temporarily remove SMTP firewall access. Compare a successful service check with a failed connection from workstation.
Record the published result first. The grader checks the original requirements, so a changed name or value may intentionally fail those checks.
Determine which failures come from the execution mode and which come from host access.
- Explain why the supplied mail playbook can fail in check mode on a clean host; its real run must prepare the service.
- Servera must accept SMTP connections on port 25 through its firewall.
- The Samba playbook must reach the intended server and complete successfully.
- Use independent SSH/Ansible connection evidence before changing access settings. Record the failing target, cause, and correction for each issue.
Try the mail relay in check mode
[student@workstation ~]$ cd ~/troubleshoot-host
[student@workstation troubleshoot-host]$ ansible-navigator run -m stdout mailrelay.yml --check
PLAY [Create mail relay servers] ***********************************************
TASK [Gathering Facts] *********************************************************
ok: [servera.lab.example.com]
TASK [Install postfix package] *************************************************
changed: [servera.lab.example.com]
TASK [Install mail config files] ***********************************************
changed: [servera.lab.example.com]
TASK [Check main.cf file] ******************************************************
ok: [servera.lab.example.com]
TASK [Verify main.cf file exists] **********************************************
skipping: [servera.lab.example.com]
TASK [Start and enable mail services] ******************************************
fatal: [servera.lab.example.com]: FAILED! => {"changed": false, "msg": "Could not find the requested service postfix: host"}
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=4 changed=2 unreachable=0 failed=1 skipped=1 ...Check main.cf file uses the stat module, and Verify main.cf file exists reports only when the file is there. Both tell the same story: in check mode the postfix package was not really installed, so neither its configuration file nor its service exists. The failure is an artefact of check mode, not a problem in the playbook.
Run it for real
[student@workstation troubleshoot-host]$ ansible-navigator run -m stdout mailrelay.yml
...output omitted...
TASK [Check main.cf file] ******************************************************
ok: [servera.lab.example.com]
TASK [Verify main.cf file exists] **********************************************
ok: [servera.lab.example.com] => {
"msg": "The main.cf file exists"
}
TASK [Start and enable mail services] ******************************************
changed: [servera.lab.example.com]
...output omitted...
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=8 changed=4 unreachable=0 failed=0 skipped=1 ...The error is gone.
Let mail in through the firewall
Postfix runs, but other hosts cannot reach it. Add a task at the end of the play, before the handlers, that enables the smtp service in the firewall:
- name: Postfix firewalld config
ansible.posix.firewalld:
state: enabled
permanent: true
immediate: true
service: smtp[student@workstation troubleshoot-host]$ ansible-navigator run -m stdout mailrelay.yml
...output omitted...
TASK [Postfix firewalld config] ************************************************
changed: [servera.lab.example.com]
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=8 changed=1 unreachable=0 failed=0 skipped=1 ...Test the mail port
[student@workstation troubleshoot-host]$ telnet servera.lab.example.com 25
Trying 172.25.250.10...
Connected to servera.lab.example.com.
Escape character is '^]'.
220 servera.lab.example.com ESMTP Postfix
quit
221 2.0.0 Bye
Connection closed by foreign host.telnet is not installed on the home-lab workstation. Bash can open the connection itself:
[student@workstation troubleshoot-host]$ exec 3<>/dev/tcp/servera.lab.example.com/25; \
> head -1 <&3; printf 'QUIT\r\n' >&3; head -1 <&3; exec 3<&-
220 servera.lab.example.com ESMTP Postfix
221 2.0.0 ByeThe relay answers on TCP port 25.
Run the Samba playbook
[student@workstation troubleshoot-host]$ ansible-navigator run -m stdout samba.yml
PLAY [Install a samba server] **************************************************
TASK [Gathering Facts] *********************************************************
fatal: [servera.lab.exammple.com]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host servera.lab.exammple.com port 22: Network is unreachable", "unreachable": true}
PLAY RECAP *********************************************************************
servera.lab.exammple.com : ok=0 changed=0 unreachable=1 failed=0 ...The very first task cannot connect. In a classroom the message may instead end in Connection timed out; either way, SSH never reached a server.
Is it the connection?
Check, outside Ansible, that you can log in to servera as devops, then with an ad hoc command:
[student@workstation troubleshoot-host]$ ssh devops@servera.lab.example.com hostname
servera.lab.example.com
[student@workstation troubleshoot-host]$ ansible servera.lab.example.com -m ansible.builtin.ping
servera.lab.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}Both work. So the keys, the user and SSH are fine: the problem is in what the playbook asks Ansible to connect to.
Ask for detail
[student@workstation troubleshoot-host]$ ansible-navigator run -m stdout samba.yml -vvvv
ansible-playbook [core 2.14.18]
config file = /home/student/troubleshoot-host/ansible.cfg
...output omitted...
PLAYBOOK: samba.yml ************************************************************
...output omitted...
verbosity: 4
...output omitted...
inventory: ('/home/student/troubleshoot-host/inventory',)
...output omitted...
<servera.lab.exammple.com> ESTABLISH SSH CONNECTION FOR USER: devops
...output omitted...
fatal: [servera.lab.exammple.com]: UNREACHABLE! => {
...output omitted...The first lines show which configuration file and inventory are in use. ESTABLISH SSH CONNECTION shows the name Ansible is really connecting to: servera.lab.exammple.com, with two ms.
Fix the inventory
The host in the samba_servers group is misspelled. Correct it:
[mailrelay]
servera.lab.example.com
[samba_servers]
servera.lab.example.com[student@workstation troubleshoot-host]$ ansible-navigator run -m stdout samba.yml
...output omitted...
PLAY RECAP *********************************************************************
servera.lab.example.com : ok=8 changed=4 unreachable=0 failed=0 ...Every task succeeds. If you did not reset the servers after the previous exercise, Samba is already set up and the run reports changed=0 instead.
Finish
Check your work with lab grade troubleshoot-host, then put the exercise away with lab finish troubleshoot-host.