diff --git a/defaults/main.yaml b/defaults/main.yaml index 51bf3ee..9714f89 100644 --- a/defaults/main.yaml +++ b/defaults/main.yaml @@ -28,6 +28,7 @@ system: authorized_keys: yes authorized_keys_delete: no motd: yes + unattended_upgrades: no prefix: sudoers: >- {%- if ansible_system == 'Linux' -%} @@ -59,6 +60,21 @@ system: apt: proxy: packages: {} + version_locks: {} + unattended_upgrades: + config: + feature_updates: no + auto_clean: yes + auto_reboot: + enabled: no + time: "03:00" + blacklist: [] + schedule: "20:00" # https://www.freedesktop.org/software/systemd/man/latest/systemd.time.html + mail: + enable: yes + only_on_error: yes + to: + postfix: prefix: config: >- diff --git a/handlers/main.yaml b/handlers/main.yaml index 921338e..add365a 100644 --- a/handlers/main.yaml +++ b/handlers/main.yaml @@ -9,3 +9,7 @@ ansible.builtin.service: name: sshd state: restarted + +- name: Reload systemd units + ansible.builtin.systemd: + daemon_reload: yes diff --git a/tasks/apt.yaml b/tasks/apt.yaml index 85a69b2..3ff48a6 100644 --- a/tasks/apt.yaml +++ b/tasks/apt.yaml @@ -1,3 +1,4 @@ +--- - name: Install GPG on Ubuntu/Debian ansible.builtin.package: name: gpg @@ -23,6 +24,14 @@ owner: root when: nodejs.version is defined +- name: Template the version lock file + when: system.apt.version_locks | length > 0 + ansible.builtin.template: + src: apt/preferences.d/00-ansible + dest: /etc/apt/preferences.d/00-ansible + owner: root + mode: "0644" + - name: Update apt cache and remove unneeded packages ansible.builtin.apt: update_cache: yes diff --git a/tasks/main.yaml b/tasks/main.yaml index 764068e..a87b6c9 100644 --- a/tasks/main.yaml +++ b/tasks/main.yaml @@ -22,6 +22,9 @@ - ansible.builtin.include_tasks: apt.yaml when: system.features.apt +- ansible.builtin.include_tasks: unattended_upgrades.yaml + when: system.features.unattended_upgrades + - ansible.builtin.include_tasks: ufw.yaml when: system.features.ufw diff --git a/tasks/unattended_upgrades.yaml b/tasks/unattended_upgrades.yaml new file mode 100644 index 0000000..29e0a02 --- /dev/null +++ b/tasks/unattended_upgrades.yaml @@ -0,0 +1,39 @@ +--- +- name: Install unattended upgrades packages + ansible.builtin.apt: + update_cache: yes + name: + - unattended-upgrades + - apt-listchanges + +- name: Ensure the configuration directories exist + ansible.builtin.file: + state: directory + path: "{{ item }}" + owner: root + mode: "0755" + loop: + - /etc/apt/apt.conf.d + - /etc/systemd/system/apt-daily-upgrade.timer.d + +- name: Template the unattended upgrades configuration + ansible.builtin.template: + src: apt/apt.conf.d/50unattended-upgrades + dest: /etc/apt/apt.conf.d/50unattended-upgrades + owner: root + mode: "0644" + +- name: Template the apt periodic configuration + ansible.builtin.template: + src: apt/apt.conf.d/10periodic + dest: /etc/apt/apt.conf.d/10periodic + owner: root + mode: "0644" + +- name: Install the unattended_upgrades systemd timer + notify: Reload systemd units + ansible.builtin.template: + src: systemd/system/apt-daily-upgrade.timer.d/override.conf + dest: /etc/systemd/system/apt-daily-upgrade.timer.d/override.conf + owner: root + mode: "0644" diff --git a/templates/apt/apt.conf.d/10periodic b/templates/apt/apt.conf.d/10periodic new file mode 100644 index 0000000..c477011 --- /dev/null +++ b/templates/apt/apt.conf.d/10periodic @@ -0,0 +1,9 @@ +APT::Periodic::Enable "1"; + +APT::Periodic::Update-Package-Lists "1"; + +APT::Periodic::Download-Upgradeable-Packages "1"; + +APT::Periodic::Unattended-Upgrade "1"; + +APT::Periodic::AutocleanInterval "21"; diff --git a/templates/apt/apt.conf.d/50unattended-upgrades b/templates/apt/apt.conf.d/50unattended-upgrades new file mode 100644 index 0000000..7af6e9c --- /dev/null +++ b/templates/apt/apt.conf.d/50unattended-upgrades @@ -0,0 +1,26 @@ +Unattended-Upgrade::Automatic-Reboot "{{ system.unattended_upgrades.config.auto_reboot.enabled | lower }}"; +Unattended-Upgrade::Automatic-Reboot-Time "{{ system.unattended_upgrades.config.auto_reboot.time }}"; + +{% if system.unattended_upgrades.config.mail.enable %} +Unattended-Upgrade::Mail "{{ system.unattended_upgrades.config.mail.to }}"; +{% if system.unattended_upgrades.config.mail.only_on_error %} +Unattended-Upgrade::MailOnlyOnError "true"; +{% endif %} +{% endif %} + +Unattended-Upgrade::Allowed-Origins { + "${distro_id} ${distro_codename}-security"; +{% if system.unattended_upgrades.config.feature_updates %} + "${distro_id} ${distro_codename}-updates"; +{% endif %} +}; + +Unattended-Upgrade::Package-Blacklist{ +{% for package in system.unattended_upgrades.config.blacklist %} + "{{ package }}"; +{% endfor %} +} + +Unattended-Upgrade::AutoFixInterruptedDpkg "true"; + +Unattended-Upgrade::Remove-Unused-Dependencies "{{ system.unattended_upgrades.config.auto_clean | lower }}"; diff --git a/templates/apt/preferences.d/00-ansible b/templates/apt/preferences.d/00-ansible new file mode 100644 index 0000000..9cd19e8 --- /dev/null +++ b/templates/apt/preferences.d/00-ansible @@ -0,0 +1,6 @@ +{% for package, version in system.apt.version_locks.items() %} +Package: {{ package }} +Pin: version {{ version }} +Pin-Priority: 1001 + +{% endfor %} diff --git a/templates/systemd/system/apt-daily-upgrade.timer.d/override.conf b/templates/systemd/system/apt-daily-upgrade.timer.d/override.conf new file mode 100644 index 0000000..2503b52 --- /dev/null +++ b/templates/systemd/system/apt-daily-upgrade.timer.d/override.conf @@ -0,0 +1,12 @@ +[Unit] +Description=Daily apt upgrade and clean activities +After=apt-daily.timer + +[Timer] +OnCalendar= +OnCalendar={{ system.unattended_upgrades.config.schedule }} +RandomizedDelaySec=60m +Persistent=true + +[Install] +WantedBy=timers.target