Files
ansible/roles/pi_standard_setup/tasks/main.yml
Martin Bauer 3d1675528b Fix tasks that always report changed regardless of actual state
Several roles reported "changed" on every playbook run even when
nothing on the target had drifted, making real config drift
indistinguishable from noise:

- 7 systemd tasks across 6 roles used state:restarted, which always
  issues a restart and always reports changed. Switched to
  state:started plus notify-driven handlers that only restart when
  the underlying unit file, script, or config actually changes.
- pi_standard_setup's boot mode, timezone, and locale tasks shelled
  out to raspi-config with changed_when:true hardcoded. Boot mode now
  checks systemctl get-default first; timezone/locale now use the
  natively idempotent community.general.timezone/locale_gen modules.
- The pi account password task computed password_hash('sha512')
  without a seed, generating a new random salt (and thus an
  apparently different hash) on every run. Added a stable seed so the
  hash only changes when the underlying secret does.

Also renamed a mislabeled task in pi_squeezelite_custom and fixed a
typo in pi_standard_setup while those files were already touched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-08 21:28:36 +02:00

154 lines
4.8 KiB
YAML

---
- name: Refresh apt cache
ansible.builtin.apt:
update_cache: "yes"
cache_valid_time: "7200"
- name: Detect Raspi Model
ansible.builtin.slurp:
src: /sys/firmware/devicetree/base/model
register: pi_standard_setup_raspberry_model
- name: Show Raspi Model
ansible.builtin.debug:
msg: "{{ pi_standard_setup_raspberry_model.content | b64decode }}"
- name: Add authorized SSH key to root account
ansible.posix.authorized_key:
user: root
key: "{{ lookup('file', 'sshkey.pub') }}"
state: present
- name: Activate root login with key
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#?PermitRootLogin"
line: "PermitRootLogin prohibit-password"
notify: Restart sshd
- name: Deactive SSH accepting locale vars (leads to warnings)
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#?AcceptEnv LANG LC_*"
line: "#AcceptEnv LANG LC_*"
notify: Restart sshd
- name: Remove first-run "SSH may not work until a valid user has been set up" banner
ansible.builtin.file:
path: /etc/ssh/sshd_config.d/rename_user.conf
state: absent
notify: Restart sshd
- name: Get hostname
ansible.builtin.command: "raspi-config nonint get_hostname"
register: pi_standard_setup_pi_hostname
changed_when: false
- name: Change hostname {{ pi_standard_setup_new_hostname }}
ansible.builtin.command: "raspi-config nonint do_hostname {{ pi_standard_setup_new_hostname }}"
when: pi_standard_setup_new_hostname | length > 0 and pi_standard_setup_pi_hostname.stdout != pi_standard_setup_new_hostname
register: pi_standard_setup_set_hostname
changed_when: true
notify: Reboot
- name: Get hostname
ansible.builtin.command: "raspi-config nonint get_hostname"
register: pi_standard_setup_pi_hostname
changed_when: false
- name: Get current boot target
ansible.builtin.command: "systemctl get-default"
register: pi_standard_setup_boot_target
changed_when: false
- name: Set boot mode to CLI
ansible.builtin.command: "raspi-config nonint do_boot_behaviour B1"
when: pi_standard_setup_boot_target.stdout != "multi-user.target"
changed_when: true
# I2 Change Timezone
- name: Change timezone
community.general.timezone:
name: "{{ pi_standard_setup_timezone }}"
- name: Generate locale
community.general.locale_gen:
name: en_US.UTF-8
state: present
- name: Set default locale
ansible.builtin.lineinfile:
path: /etc/default/locale
regexp: "^LANG="
line: "LANG=en_US.UTF-8"
create: true
mode: "0644"
- name: Change password of default pi account
ansible.builtin.user:
name: pi
update_password: always
password: "{{ lookup('keepass', 'ansible://default_rpi_password') | password_hash('sha512', 65534 | random(seed=inventory_hostname) | string) }}"
- name: Install Packages (vim, git, basic python stuff)
ansible.builtin.apt:
name:
- vim
- git
- python3
- python3-pip
- python3-wheel
- telnet
cache_valid_time: 7200
state: present
- name: Copy vim config
ansible.builtin.copy:
src: vimrc
dest: /root/.vimrc
mode: "0644"
- name: Copy git config
ansible.builtin.copy:
src: gitconfig
dest: /root/.gitconfig
mode: "0644"
# Wifi
- name: Change WiFi country
ansible.builtin.command: "raspi-config nonint do_wifi_country {{ pi_standard_setup_wifi_country }}"
when: configure_wifi
changed_when: true
- name: Set WiFi credentials
ansible.builtin.command: "raspi-config nonint do_wifi_ssid_passphrase {{ pi_standard_setup_wifi_ssid }} {{ lookup('keepass', 'bauer_wifi') }}"
when: configure_wifi
changed_when: true
- name: Install watchdog
ansible.builtin.apt:
name: watchdog
cache_valid_time: "7200"
state: present
when: not pi_standard_setup_wifi_ssid is defined
- name: Configure watchdog
ansible.builtin.blockinfile:
path: /etc/watchdog.conf
block: |
interface = wlan0
retry-timeout = 90
ping = {{ router_ip }}
interval = 15
when: configure_wifi
- name: Start watchdog
ansible.builtin.systemd: # state=restarted not working, also not manually
name: watchdog
state: started
enabled: "yes"
daemon_reload: "yes"
when: configure_wifi
# Message of the day
- name: Set Message of the day
ansible.builtin.copy:
src: motd/{{ pi_standard_setup_pi_hostname.stdout }}
dest: /etc/motd
mode: "0644"
# LED off script
- name: Copy led off script
ansible.builtin.copy:
src: raspi-leds-off.sh
dest: /usr/sbin/raspi-leds-off.sh
mode: "u+rwx"
notify: Restart raspi-leds-off
- name: Copy led off service
ansible.builtin.copy:
src: raspi-leds-off.service
dest: /lib/systemd/system/
mode: "0644"
notify: Restart raspi-leds-off
- name: Activate led off service
ansible.builtin.systemd:
name: raspi-leds-off
state: started
enabled: "yes"
daemon_reload: "yes"