Skip to content

Troubleshooting

The single troubleshooting page for the Ansible section. For the everyday debugging commands (--list-hosts, -m setup, systemctl --failed and so on), see the Quick Reference.

"Permission denied" on SSH

# Verify the key works manually
ssh -i ~/.ssh/ansible -v username@server1.example.com

# Check the key is in authorized_keys on the remote host
ssh username@server1.example.com "cat ~/.ssh/authorized_keys"

The -v flag shows the SSH handshake. Look for which keys are being offered and whether the server accepts them. If the key is not being offered, check that private_key_file in ansible.cfg points to the right path.

"Missing sudo password"

The username user needs passwordless sudo. On the managed node:

echo "username ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/username
sudo chmod 440 /etc/sudoers.d/username

Check it works over the Ansible key (this should print root):

ssh -i ~/.ssh/ansible username@server1.example.com "sudo whoami"

"Could not resolve host"

Check DNS. From Control Node:

dig server1.example.com

If it doesn't resolve, add the host in OPNsense dnsmasq. Until DNS is fixed, you can temporarily use the IP directly by adding it to your inventory:

[infra]
server1.example.com ansible_host=192.0.2.10

Template errors

If a template fails, check the variable exists:

# Show all variables for a host
ansible server1.example.com -m debug -a "var=hostvars[inventory_hostname]"

This dumps every variable available for that host. Search for the one your template references.

"changed" on every run

If a task shows "changed" every time you run it, it's not idempotent. Common causes:

  • Using ansible.builtin.command or ansible.builtin.shell (these always show changed, because Ansible has no way to know if the command actually modified anything). Add creates:, when:, or changed_when: false conditions.
  • Templates that include timestamps or dynamic content.
# Before (always changed)
- name: Get release name
  ansible.builtin.command: lsb_release -cs
  register: debian_release

# After (never shows changed, because it is read-only)
- name: Get release name
  ansible.builtin.command: lsb_release -cs
  register: debian_release
  changed_when: false

View verbose output

Add -v flags for more detail:

ansible-playbook playbooks/base.yml -v     # task results
ansible-playbook playbooks/base.yml -vv    # task input parameters
ansible-playbook playbooks/base.yml -vvv   # SSH connection debug