chore: ansible-lint review (almost done)

This commit is contained in:
Clément Désiles 2026-01-04 11:21:15 +01:00
parent 3e469fa25e
commit c79c445a23
No known key found for this signature in database
67 changed files with 197 additions and 107 deletions

View File

@ -1,3 +1,4 @@
---
skip_list:
- var-naming[no-role-prefix]
- no-handler # Sequential task flows require immediate execution, not end-of-play handlers

View File

@ -1,7 +1,7 @@
---
- hosts: marge
- name: Sample of a playbook
hosts: marge
become: true
roles:
- role: ntpd
- role: fail2ban
- role: unbound

View File

@ -1,6 +1,7 @@
---
collections:
- name: ansible.netcommon
- name: ansible.posix
- name: community.general
- name: community.postgresql
- name: containers.podman

View File

@ -1,15 +1,21 @@
---
- name: Configure locales
block:
- name: Activate locale
ansible.builtin.command:
cmd: localectl set-locale LANG={{ arch_locale }}
- name: Edit /etc/locale.gen
ansible.builtin.lineinfile:
dest: /etc/locale.gen
state: present
regexp: "{{ arch_locale }}"
line: "{{ arch_locale }} UTF-8"
register: locale_gen_changed
- name: Regenerate locales
ansible.builtin.command:
cmd: locale-gen
when: locale_gen_changed is changed
changed_when: true
- name: Activate locale
ansible.builtin.command:
cmd: localectl set-locale LANG={{ arch_locale }}
changed_when: false

View File

@ -77,12 +77,19 @@
mode: "0644"
- name: Extract paru
ansible.builtin.command:
cmd: "tar -xf /tmp/paru-{{ os_arch }}.tar.zst paru -C /tmp"
ansible.builtin.unarchive:
src: "/tmp/paru-{{ os_arch }}.tar.zst"
dest: /tmp
remote_src: true
extra_opts:
- paru
- name: Install paru binary
ansible.builtin.command:
cmd: "mv /tmp/paru /usr/bin/paru"
ansible.builtin.copy:
src: /tmp/paru
dest: /usr/bin/paru
remote_src: true
mode: "0755"
- name: Ensure permissions
ansible.builtin.file:

View File

@ -0,0 +1,4 @@
---
- name: Systemd daemon reload
ansible.builtin.systemd:
daemon_reload: true

View File

@ -23,11 +23,7 @@
group: root
mode: "0644"
register: timer_config
- name: Systemd daemon reload
ansible.builtin.systemd:
daemon_reload: true
when: timer_config.changed
notify: Systemd daemon reload
- name: Enable periodic trim
ansible.builtin.systemd:

View File

@ -0,0 +1,4 @@
---
- name: Inform user to relogin
ansible.builtin.debug:
msg: "Please logout and login again to make sure the user is added to the docker group"

View File

@ -35,9 +35,4 @@
name: "{{ ansible_user }}"
groups: docker
append: true
register: docker_group
- name: Inform the user that user needs to logout and login again
ansible.builtin.debug:
msg: "Please logout and login again to make sure the user is added to the docker group"
when: docker_group.changed
notify: Inform user to relogin

View File

@ -4,13 +4,18 @@
daemon_reload: true
- name: Reload systemd user
ansible.builtin.command: "systemctl --user daemon-reload"
become: true
ansible.builtin.systemd:
daemon_reload: true
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Restart gitea
ansible.builtin.command: "systemctl --user restart gitea.service"
become: true
ansible.builtin.systemd:
name: gitea.service
state: restarted
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Reload nginx

View File

@ -14,6 +14,7 @@
name: "{{ gitea_postgres_user }}"
password: "{{ gitea_postgres_password }}"
state: present
become: false
become_user: "{{ postgres_admin_user }}"
- name: Create PostgreSQL database for Gitea
@ -21,6 +22,7 @@
name: "{{ gitea_postgres_db_name }}"
owner: "{{ gitea_postgres_user }}"
state: present
become: false
become_user: "{{ postgres_admin_user }}"
- name: Grant all privileges on database to Gitea user
@ -30,6 +32,7 @@
type: database
privs: ALL
state: present
become: false
become_user: "{{ postgres_admin_user }}"
- name: Ensure Gitea user has no superuser privileges
@ -37,6 +40,7 @@
name: "{{ gitea_postgres_user }}"
role_attr_flags: NOSUPERUSER,NOCREATEDB,NOCREATEROLE
state: present
become: false
become_user: "{{ postgres_admin_user | default('postgres') }}"
- name: Create PostgreSQL schema for Gitea
@ -45,6 +49,7 @@
database: "{{ gitea_postgres_db_name }}"
owner: "{{ gitea_postgres_user }}"
state: present
become: false
become_user: "{{ postgres_admin_user | default('postgres') }}"
- name: Grant schema permissions to Gitea user
@ -55,6 +60,7 @@
objs: "{{ gitea_postgres_schema }}"
privs: CREATE,USAGE
state: present
become: false
become_user: "{{ postgres_admin_user | default('postgres') }}"
- name: Create Gitea project directory
@ -113,7 +119,12 @@
when: ansible_user != 'root'
- name: Enable and start Gitea service (user scope)
ansible.builtin.command: "systemctl --user enable --now gitea.service"
ansible.builtin.systemd:
name: gitea.service
enabled: true
state: started
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Deploy nginx vhost configuration for Gitea

View File

@ -4,13 +4,18 @@
daemon_reload: true
- name: Reload systemd user
ansible.builtin.command: "systemctl --user daemon-reload"
become: true
ansible.builtin.systemd:
daemon_reload: true
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Restart Immich
ansible.builtin.command: "systemctl --user restart immich.service"
become: true
ansible.builtin.systemd:
name: immich.service
state: restarted
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Reload nginx

View File

@ -16,6 +16,7 @@
name: "{{ immich_postgres_db_name }}"
owner: "{{ immich_postgres_user }}"
state: present
become: false
become_user: "{{ postgres_admin_user | default('postgres') }}"
- name: Create PostgreSQL user for Immich
@ -23,6 +24,7 @@
name: "{{ immich_postgres_user }}"
password: "{{ immich_postgres_password }}"
state: present
become: false
become_user: "{{ postgres_admin_user | default('postgres') }}"
- name: Grant all privileges on database to Immich user
@ -32,6 +34,7 @@
type: database
privs: ALL
state: present
become: false
become_user: "{{ postgres_admin_user | default('postgres') }}"
- name: Ensure Immich user has no superuser privileges
@ -39,6 +42,7 @@
name: "{{ immich_postgres_user }}"
role_attr_flags: NOSUPERUSER,NOCREATEDB,NOCREATEROLE
state: present
become: false
become_user: "{{ postgres_admin_user | default('postgres') }}"
- name: Enable required PostgreSQL extensions in Immich database
@ -46,6 +50,7 @@
name: "{{ item }}"
login_db: "{{ immich_postgres_db_name }}"
state: present
become: false
become_user: "{{ postgres_admin_user | default('postgres') }}"
loop:
- cube
@ -60,6 +65,7 @@
objs: public
privs: CREATE,USAGE
state: present
become: false
become_user: "{{ postgres_admin_user | default('postgres') }}"
- name: Create Immich project directory
@ -120,7 +126,12 @@
when: ansible_user != 'root'
- name: Enable and start Immich service (user scope)
ansible.builtin.command: "systemctl --user enable --now immich.service"
ansible.builtin.systemd:
name: immich.service
enabled: true
state: started
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Deploy nginx vhost configuration for Immich

View File

@ -1,4 +1,5 @@
---
- name: install oryx
cmd: paru -S oryx
- name: Install oryx
ansible.builtin.command: paru -S --noconfirm oryx
when: ansible_facts['os_family'] == 'Archlinux'
changed_when: false

View File

@ -7,7 +7,7 @@
- name: Process ethernet interface persistence
when: interface.type is not defined or interface.type == 'ethernet'
block:
- name: "Check {{ interface.name }} ({{ interface.mac_address }}) rule"
- name: "Check interface rule for {{ interface.name }} ({{ interface.mac_address }})"
ansible.builtin.set_fact:
interface_original_name: "{{ ansible_facts.interfaces | select('in', ansible_facts) | map('extract', ansible_facts) | selectattr('pciid', 'defined') | selectattr('macaddress', 'equalto', interface.mac_address) | map(attribute='device') | first }}"

View File

@ -6,8 +6,8 @@ This role configures the networking on the target machine.
Roles:
- net-persist
- net-config
- net_persist
- net_config
## Inventory Variables

View File

@ -6,7 +6,7 @@
- name: Setup persistent network interface(s)
ansible.builtin.include_role:
name: net-persist
name: net_persist
public: true
vars:
interface: "{{ item }}"
@ -14,7 +14,7 @@
- name: Configure network interface(s)
ansible.builtin.include_role:
name: net-config
name: net_config
public: true
vars:
interface: "{{ item }}"

View File

@ -4,13 +4,18 @@
daemon_reload: true
- name: Reload systemd user
ansible.builtin.command: "systemctl --user daemon-reload"
become: true
ansible.builtin.systemd:
daemon_reload: true
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Restart ntfy
ansible.builtin.command: "systemctl --user restart ntfy.service"
become: true
ansible.builtin.systemd:
name: ntfy.service
state: restarted
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Reload nginx

View File

@ -77,7 +77,12 @@
when: ansible_user != 'root'
- name: Enable and start ntfy service (user scope)
ansible.builtin.command: "systemctl --user enable --now ntfy.service"
ansible.builtin.systemd:
name: ntfy.service
enabled: true
state: started
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Wait for ntfy to be ready
@ -92,21 +97,26 @@
register: ntfy_user_list
changed_when: false
failed_when: false
become: false
become_user: "{{ ansible_user }}"
- name: Create admin user in ntfy
ansible.builtin.shell: |
set -o pipefail
printf '%s\n%s\n' '{{ ntfy_admin_password }}' '{{ ntfy_admin_password }}' | podman exec -i ntfy-server ntfy user add --role=admin {{ ntfy_admin_user }}
when: ntfy_admin_user not in ntfy_user_list.stdout
register: ntfy_user_create
changed_when: ntfy_user_create.rc == 0
become: false
become_user: "{{ ansible_user }}"
- name: Set admin user password
ansible.builtin.shell: |
set -o pipefail
printf '%s\n%s\n' '{{ ntfy_admin_password }}' '{{ ntfy_admin_password }}' | podman exec -i ntfy-server ntfy user change-pass {{ ntfy_admin_user }}
when: ntfy_admin_user in ntfy_user_list.stdout
changed_when: false
become: false
become_user: "{{ ansible_user }}"
- name: Deploy nginx vhost configuration for ntfy

View File

@ -35,4 +35,5 @@
ansible.builtin.command:
cmd: initdb -D {{ postgres_data_dir }}
creates: "{{ postgres_data_dir }}/PG_VERSION"
become: false
become_user: "{{ postgres_admin_user }}"

View File

@ -97,4 +97,5 @@
name: "{{ postgres_admin_user }}"
password: "{{ postgres_admin_password }}"
state: present
become: false
become_user: "{{ postgres_admin_user }}"

View File

@ -4,8 +4,8 @@ ssh_allowed_network: "192.168.1.0/24"
ssh_allowed_vpn_network: "192.168.27.0/27"
ssh_users: "jokester" # space separated if many
ssh_config_dir: "/etc/ssh"
sshd_config: "{{ ssh_config_dir}}/sshd_config"
sshd_banner: "{{ ssh_config_dir}}/banner"
sshd_config: "{{ ssh_config_dir }}/sshd_config"
sshd_banner: "{{ ssh_config_dir }}/banner"
sshd_binary: "/usr/sbin/sshd"
ssh_authorized_keys_fallback_enabled: false
ssh_authorized_keys_fallback_dir: "/etc/ssh/authorized_keys"

View File

@ -0,0 +1,5 @@
---
- name: Restart SSH service
ansible.builtin.service:
name: "{{ ssh_service_name }}"
state: restarted

View File

@ -1,26 +1,27 @@
---
- include_vars: "{{ item }}"
- name: Load OS-specific variables
ansible.builtin.include_vars: "{{ item }}"
with_first_found:
- "vars/{{ ansible_facts['os_family'] }}.yml"
- "vars/debian.yml"
- name: Install OpenSSH
package:
ansible.builtin.package:
name: "{{ ssh_package_name }}"
state: present
- name: Install UFW
package:
ansible.builtin.package:
name: ufw
state: present
- name: Enable SSH
service:
ansible.builtin.service:
name: "{{ ssh_service_name }}"
enabled: true
- name: Allow local network incoming connection
ufw:
community.general.ufw:
rule: allow
port: "{{ ssh_port }}"
proto: tcp
@ -29,7 +30,7 @@
comment: "SSH from local network"
- name: Allow SSH VPN incoming connection
ufw:
community.general.ufw:
rule: allow
port: "{{ ssh_port }}"
proto: tcp
@ -37,36 +38,41 @@
direction: in
comment: "SSH from VPN network"
- name: Add SSH public key to authorized_keys
authorized_key:
user: "{{ item }}"
state: present
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
comment: "{{ lookup('env', 'USER') | default('ansible') }}@{{ lookup('pipe', 'hostname -s') }}"
loop: "{{ ssh_users.split() }}"
# TODO
# - name: Add SSH public key to authorized_keys
# authorized_key:
# user: "{{ item }}"
# state: present
# key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
# comment: "{{ lookup('env', 'USER') | default('ansible') }}@{{ lookup('pipe', 'hostname -s') }}"
# loop: "{{ ssh_users.split() }}"
- name: Authorized keys fallback
- name: Authorized keys fallback (when home cannot be mounted)
when: ssh_authorized_keys_fallback_enabled
block:
- name: Create the directory
file:
path: "{{ssh_authorized_keys_fallback_dir}}"
ansible.builtin.file:
path: "{{ ssh_authorized_keys_fallback_dir }}"
state: directory
owner: root
group: root
mode: "0755"
- name: Backup authorized_keys out of HOME dir (if unavailable at startup)
command: "cp /home/{{ item }}/.ssh/authorized_keys {{ssh_authorized_keys_fallback_dir}}/{{ item }}"
ansible.builtin.command: "cp /home/{{ item }}/.ssh/authorized_keys {{ ssh_authorized_keys_fallback_dir }}/{{ item }}"
loop: "{{ ssh_users.split() }}"
changed_when: false
- name: Fix ownership
file:
path: "{{ssh_authorized_keys_fallback_dir}}/{{ item }}"
ansible.builtin.file:
path: "{{ ssh_authorized_keys_fallback_dir }}/{{ item }}"
owner: "{{ item }}"
group: "{{ item }}"
mode: "0600"
loop: "{{ ssh_users.split() }}"
when: ssh_authorized_keys_fallback_enabled
- name: Create an SSH banner
template:
ansible.builtin.template:
src: templates/sshd_banner.j2
dest: "{{ sshd_banner }}"
owner: root
@ -74,27 +80,33 @@
mode: "0644"
- name: Remove motd on Debian
file:
ansible.builtin.file:
path: /etc/motd
state: absent
when: ansible_facts['os_family'] == 'Debian'
- name: Hardening sshd_config
template:
ansible.builtin.template:
src: templates/sshd_config.j2
dest: "{{ sshd_config }}"
owner: root
group: root
mode: "0600"
validate: "{{ sshd_binary }} -t -f %s"
register: ssh_hardening_task
- name: Restart SSH service
service:
name: "{{ ssh_service_name }}"
state: restarted
when: ssh_hardening_task.changed
notify: Restart SSH service
- name: Enable UFW
community.general.ufw:
state: enabled
- name: Enable UFW service at startup
ansible.builtin.systemd:
name: ufw
enabled: true
state: started
- name: Start and enable fail2ban
ansible.builtin.service:
name: fail2ban
state: started
enabled: true

View File

@ -37,6 +37,7 @@
force: true
loop: "{{ static_web_sites | dict2items }}"
when: static_web_sites | length > 0
become: false
become_user: "{{ nginx_user }}"
notify: Reload nginx
@ -49,6 +50,7 @@
- static_web_sites | length > 0
- item.value.build_command is defined
- item.value.build_command | length > 0
become: false
become_user: "{{ nginx_user }}"
changed_when: true

View File

@ -16,3 +16,9 @@
name: bottom
state: present
changed_when: false
- name: Install wget
package:
name: wget
state: present
changed_when: false

View File

@ -97,6 +97,7 @@
- name: Convert hosts file to unbound format
ansible.builtin.shell: |
set -o pipefail
grep '^0\.0\.0\.0' /tmp/hosts.txt | awk '{print "local-zone: \""$2"\" always_nxdomain"}' > "{{ unbound_ad_servers_config_path }}" &&
chown unbound:unbound "{{ unbound_ad_servers_config_path }}"
args:

View File

@ -4,13 +4,18 @@
daemon_reload: true
- name: Reload systemd user
ansible.builtin.command: "systemctl --user daemon-reload"
become: true
ansible.builtin.systemd:
daemon_reload: true
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Restart uptime-kuma
ansible.builtin.command: "systemctl --user restart uptime-kuma.service"
become: true
ansible.builtin.systemd:
name: uptime-kuma.service
state: restarted
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Reload nginx

View File

@ -55,7 +55,12 @@
when: ansible_user != 'root'
- name: Enable and start uptime-kuma service (user scope)
ansible.builtin.command: "systemctl --user enable --now uptime-kuma.service"
ansible.builtin.systemd:
name: uptime-kuma.service
enabled: true
state: started
scope: user
become: false
become_user: "{{ ansible_user }}"
- name: Deploy nginx vhost configuration for uptime-kuma

View File

@ -20,3 +20,10 @@
else
grub-mkconfig -o /boot/grub/grub.cfg
fi
- name: Warn user about reboot requirement
ansible.builtin.debug:
msg: |
WARNING: GRUB configuration has been updated with transparent_hugepage=madvise
A REBOOT IS REQUIRED for this change to take effect permanently.
The setting has been applied at runtime temporarily.

View File

@ -20,8 +20,9 @@
line: '\1 transparent_hugepage=madvise"'
backrefs: true
when: thp_check.rc != 0
notify: Update GRUB
register: grub_updated
notify:
- Update GRUB
- Warn user about reboot requirement
- name: Check current THP runtime setting
ansible.builtin.shell: cat /sys/kernel/mm/transparent_hugepage/enabled
@ -33,11 +34,3 @@
echo madvise > /sys/kernel/mm/transparent_hugepage/enabled
echo madvise > /sys/kernel/mm/transparent_hugepage/defrag
when: "'[madvise]' not in current_thp.stdout"
- name: Warn user about reboot requirement
ansible.builtin.debug:
msg: |
WARNING: GRUB configuration has been updated with transparent_hugepage=madvise
A REBOOT IS REQUIRED for this change to take effect permanently.
The setting has been applied at runtime temporarily.
when: grub_updated is changed

View File

@ -17,9 +17,7 @@
when: zfs_pools is defined
- name: Creating basic zpool(s)
ansible.builtin.command:
"zpool create {{ '-o '+ item.options.items() |map('join', '=') | join (' -o ') if item.options is defined else '' }} {{ item.name }} {{
item.devices|join (' ') }}"
ansible.builtin.command: "zpool create {{ '-o ' + item.options.items() | map('join', '=') | join(' -o ') if item.options is defined else '' }} {{ item.name }} {{ item.devices | join(' ') }}"
with_items: "{{ zfs_pools }}"
when:
- zfs_pools is defined
@ -29,9 +27,7 @@
- item.devices[0] not in zpool_devices.stdout
- name: Creating mirror/zraid zpool(s)
ansible.builtin.command:
"zpool create {{ '-o '+ item.options.items() |map('join', '=') | join (' -o ') if item.options is defined else '' }} {{ item.name }} {{
item.type }} {{ item.devices|join (' ') }}"
ansible.builtin.command: "zpool create {{ '-o ' + item.options.items() | map('join', '=') | join(' -o ') if item.options is defined else '' }} {{ item.name }} {{ item.type }} {{ item.devices | join(' ') }}"
with_items: "{{ zfs_pools }}"
when:
- zfs_pools is defined

View File

@ -24,18 +24,12 @@
update: true
version: master
loop:
- {
repo: https://github.com/zsh-users/zsh-syntax-highlighting.git,
dest: "{{ zsh_plugins_path }}/zsh-syntax-highlighting",
}
- {
repo: https://github.com/zsh-users/zsh-autosuggestions.git,
dest: "{{ zsh_plugins_path }}/zsh-autosuggestions",
}
- {
repo: https://github.com/romkatv/powerlevel10k.git,
dest: "{{ zsh_plugins_path }}/powerlevel10k",
}
- repo: https://github.com/zsh-users/zsh-syntax-highlighting.git
dest: "{{ zsh_plugins_path }}/zsh-syntax-highlighting"
- repo: https://github.com/zsh-users/zsh-autosuggestions.git
dest: "{{ zsh_plugins_path }}/zsh-autosuggestions"
- repo: https://github.com/romkatv/powerlevel10k.git
dest: "{{ zsh_plugins_path }}/powerlevel10k"
- name: Assert plugins are available for any user
ansible.builtin.file: