I'm trying to use the ansible hostname module to change hostname of multiple Raspberry Pi Compute Module 4. Because they are all based from the same Raspberry Pi OS image, their hostname is raspberrypi
for all of them, what I would like to change.
My inventory is roughly like this:
rpi-cm4-1:
node_number: 1
name: rpi-cm4-1
ansible_host: 192.168.1.101
rpi-cm4-2:
node_number: 2
name: rpi-cm4-2
ansible_host: 192.168.1.102
...
and my playbook is like this:
- name: Change hostname of managed nodes
hosts: rpi_cm4-2
tasks:
- name: Change hostname of managed nodes
ansible.builtin.hostname:
name: "{{ hostvars[inventory_hostname].name }}"
When I run the playbook, the error I'm facing is this:
TASK [Gathering Facts] *****************************************************************************************************
ok: [rpi-cm4-2]
TASK [Change hostname of managed nodes] *****************************************************************************************************
fatal: [rpi-cm4-2]: FAILED! => changed=false
msg: |-
Command failed rc=1, out=, err=Could not set pretty hostname: Connection timed out
I guess that maybe Ansible is not using the ip address of the inventory (but it used it for gathering facts). What could I do to make him use the IP of the inventory ?
I could not manage to make Ansible use the IP address.
The -vvv
actually shows this:
TASK [Change hostname of managed nodes] ****************************************************************************************************************************
task path: /home/ncasaux/home-lab/ansible/tpi2_rpi_cm4.tpi2_rpios.yml:75
<192.168.1.102> ESTABLISH SSH CONNECTION FOR USER: pi
<192.168.1.102> SSH: EXEC sshpass -d12 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="pi"' -o ConnectTimeout=10 -o 'ControlPath="/home/ncasaux/.ansible/cp/ed650a3305"' 192.168.1.102 '/bin/sh -c '"'"'echo ~pi && sleep 0'"'"''
<192.168.1.102> (0, b'/home/pi\n', b'')
<192.168.1.102> ESTABLISH SSH CONNECTION FOR USER: pi
<192.168.1.102> SSH: EXEC sshpass -d12 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="pi"' -o ConnectTimeout=10 -o 'ControlPath="/home/ncasaux/.ansible/cp/ed650a3305"' 192.168.1.102 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /home/pi/.ansible/tmp `"&& mkdir "` echo /home/pi/.ansible/tmp/ansible-tmp-1703118028.4996538-25006-160853801334657 `" && echo ansible-tmp-1703118028.4996538-25006-160853801334657="` echo /home/pi/.ansible/tmp/ansible-tmp-1703118028.4996538-25006-160853801334657 `" ) && sleep 0'"'"''
<192.168.1.102> (0, b'ansible-tmp-1703118028.4996538-25006-160853801334657=/home/pi/.ansible/tmp/ansible-tmp-1703118028.4996538-25006-160853801334657\n', b'')
Using module file /usr/lib/python3/dist-packages/ansible/modules/hostname.py
<192.168.1.102> PUT /home/ncasaux/.ansible/tmp/ansible-local-24823y1az1b7h/tmp3nxd67rj TO /home/pi/.ansible/tmp/ansible-tmp-1703118028.4996538-25006-160853801334657/AnsiballZ_hostname.py
<192.168.1.102> SSH: EXEC sshpass -d12 sftp -o BatchMode=no -b - -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="pi"' -o ConnectTimeout=10 -o 'ControlPath="/home/ncasaux/.ansible/cp/ed650a3305"' '[192.168.1.102]'
<192.168.1.102> (0, b'sftp> put /home/ncasaux/.ansible/tmp/ansible-local-24823y1az1b7h/tmp3nxd67rj /home/pi/.ansible/tmp/ansible-tmp-1703118028.4996538-25006-160853801334657/AnsiballZ_hostname.py\n', b'')
<192.168.1.102> ESTABLISH SSH CONNECTION FOR USER: pi
<192.168.1.102> SSH: EXEC sshpass -d12 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="pi"' -o ConnectTimeout=10 -o 'ControlPath="/home/ncasaux/.ansible/cp/ed650a3305"' 192.168.1.102 '/bin/sh -c '"'"'chmod u+x /home/pi/.ansible/tmp/ansible-tmp-1703118028.4996538-25006-160853801334657/ /home/pi/.ansible/tmp/ansible-tmp-1703118028.4996538-25006-160853801334657/AnsiballZ_hostname.py && sleep 0'"'"''
<192.168.1.102> (0, b'', b'')
<192.168.1.102> ESTABLISH SSH CONNECTION FOR USER: pi
<192.168.1.102> SSH: EXEC sshpass -d12 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="pi"' -o ConnectTimeout=10 -o 'ControlPath="/home/ncasaux/.ansible/cp/ed650a3305"' -tt 192.168.1.102 '/bin/sh -c '"'"'/usr/bin/python3 /home/pi/.ansible/tmp/ansible-tmp-1703118028.4996538-25006-160853801334657/AnsiballZ_hostname.py && sleep 0'"'"''
<192.168.1.102> (1, b'\x1b[1;31m==== AUTHENTICATING FOR org.freedesktop.hostname1.set-static-hostname ====\r\n\x1b[0mAuthentication is required to set the statically configured local hostname, as well as the pretty hostname.\r\nAuthenticating as: ,,, (pi)\r\nPassword: polkit-agent-helper-1: pam_authenticate failed: Authentication failure\r\n\r\n{"failed": true, "msg": "Command failed rc=1, out=, err=Could not set pretty hostname: Connection timed out\\n", "invocation": {"module_args": {"name": "192.168.1.102", "use": null}}}\r\n', b'Shared connection to 192.168.1.102 closed.\r\n')
<192.168.1.102> Failed to connect to the host via ssh: Shared connection to 192.168.1.102 closed.
<192.168.1.102> ESTABLISH SSH CONNECTION FOR USER: pi
<192.168.1.102> SSH: EXEC sshpass -d12 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="pi"' -o ConnectTimeout=10 -o 'ControlPath="/home/ncasaux/.ansible/cp/ed650a3305"' 192.168.1.102 '/bin/sh -c '"'"'rm -f -r /home/pi/.ansible/tmp/ansible-tmp-1703118028.4996538-25006-160853801334657/ > /dev/null 2>&1 && sleep 0'"'"''
<192.168.1.102> (0, b'', b'')
fatal: [rpi-cm4-2]: FAILED! => changed=false
invocation:
module_args:
name: 192.168.1.102
use: null
msg: |-
Command failed rc=1, out=, err=Could not set pretty hostname: Connection timed out
So the IP seems to be used...
It's pretty clearly using the ip address, so that's not the problem. It looks like ansible is connecting successfully, but it receiving an error when it attempts to set the system hostname.
From the error message, it looks like a permissions problem:
==== AUTHENTICATING FOR org.freedesktop.hostname1.set-static-hostname ====
Authentication is required to set the statically configured local hostname, as well as the pretty hostname.
Authenticating as: ,,, (pi)
Password: polkit-agent-helper-1: pam_authenticate failed: Authentication failure
You probably need to ensure that you're running the task as root
on the remote host:
- name: Change hostname of managed nodes
hosts: rpi_cm4-2
become: true
tasks:
- name: Change hostname of managed nodes
ansible.builtin.hostname:
name: "{{ hostvars[inventory_hostname].name }}"
Note the addition of become: true
, which will cause all tasks in this play to run as root
.