From e2c9acd872700ba1a77ce579e3cedc581bc9ea90 Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Wed, 22 Oct 2025 18:19:12 +0200 Subject: [PATCH 1/5] alpine: fix condition for loopback interface template --- roles/alpine/templates/interfaces.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/alpine/templates/interfaces.j2 b/roles/alpine/templates/interfaces.j2 index 0ccf500..98126f0 100644 --- a/roles/alpine/templates/interfaces.j2 +++ b/roles/alpine/templates/interfaces.j2 @@ -1,5 +1,5 @@ -{# Loopback interface must be present so define it here if none exists. #} -{% if interfaces | rejectattr("name", "==", "lo") %} +{# Loopback interface must be present so create it here if none is defined in inventory. #} +{% if not interfaces | selectattr("name", "==", "lo") %} auto lo iface lo From 1b206517b68b5c93fd1ded4b97e51c9d57ac632d Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Wed, 22 Oct 2025 18:44:05 +0200 Subject: [PATCH 2/5] alpine: enable automatic upgrades only for virtual machines And factor out VM stuff into a separate file. --- roles/alpine/tasks/main.yml | 29 +++-------------------------- roles/alpine/tasks/vm.yml | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 26 deletions(-) create mode 100644 roles/alpine/tasks/vm.yml diff --git a/roles/alpine/tasks/main.yml b/roles/alpine/tasks/main.yml index 9fce34c..4292d41 100644 --- a/roles/alpine/tasks/main.yml +++ b/roles/alpine/tasks/main.yml @@ -65,7 +65,6 @@ - acl - git - iproute2 - - logrotate - nftables - procps - rsync @@ -98,33 +97,11 @@ - meta: flush_handlers -- name: Enable QEMU guest agent - when: is_virtual - block: - - name: Install QEMU guest agent package - package: - name: qemu-guest-agent - - - name: Enable QEMU guest agent service - service: - name: qemu-guest-agent - enabled: yes - state: started - -- name: Install automatic upgrade script - copy: - dest: /etc/periodic/weekly/ - src: unattended-upgrade - mode: 0755 - -- name: Configure log rotation for automatic upgrades - copy: - dest: /etc/logrotate.d/unattended-upgrade - src: unattended-upgrade.logrotate - mode: 0644 - - name: Set authorized SSH keys authorized_key: user: root exclusive: true key: "{{ ssh_keys | join('\n') }}" + +- when: is_virtual + include_tasks: vm.yml diff --git a/roles/alpine/tasks/vm.yml b/roles/alpine/tasks/vm.yml new file mode 100644 index 0000000..45ce0af --- /dev/null +++ b/roles/alpine/tasks/vm.yml @@ -0,0 +1,25 @@ +- name: Install QEMU guest agent package + package: + name: qemu-guest-agent + +- name: Enable QEMU guest agent service + service: + name: qemu-guest-agent + enabled: yes + state: started + +- name: Install logrotate + package: + name: logrotate + +- name: Install automatic upgrade script + copy: + dest: /etc/periodic/weekly/ + src: unattended-upgrade + mode: "0755" + +- name: Configure log rotation for automatic upgrades + copy: + dest: /etc/logrotate.d/unattended-upgrade + src: unattended-upgrade.logrotate + mode: "0644" From 7a4a868d416c18733b12acd1774f40fe9303062c Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Wed, 22 Oct 2025 18:46:49 +0200 Subject: [PATCH 3/5] alpine: add support for VRF interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mostly so we can merge the firewall role from the network repo, there aren’t any other current users. --- roles/alpine/templates/interfaces.j2 | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/roles/alpine/templates/interfaces.j2 b/roles/alpine/templates/interfaces.j2 index 98126f0..a18ebbe 100644 --- a/roles/alpine/templates/interfaces.j2 +++ b/roles/alpine/templates/interfaces.j2 @@ -5,6 +5,16 @@ iface lo {% endif -%} +{# Define VRFs. #} +{% for vrf in interfaces | selectattr("vrf") | map(attribute="vrf.name") %} +auto {{ vrf }} +iface {{ vrf }} + pre-up ip link add $IFACE type vrf table {{ 100 + loop.index }} + up ip link set dev $IFACE up + post-down ip link del $IFACE + +{% endfor -%} + {# Skip disabled and OOB management interfaces. #} {# For VMs we have to set the attribute manually (to false) so rejectattr works. #} {% for iface in interfaces @@ -13,6 +23,10 @@ iface lo | selectattr('enabled') %} auto {{ iface.name }} iface {{ iface.name }} +{% if iface.vrf %} + requires {{ iface.vrf.name }} + pre-up ip link set $IFACE master {{ iface.vrf.name }} +{% endif %} {% if iface.mtu %} mtu {{ iface.mtu }} {% endif %} @@ -23,9 +37,13 @@ iface {{ iface.name }} {% set prefix = prefixes | selectattr('prefix', '==', subnet) | first %} {% set gateway = prefix.custom_fields.gateway.address %} {% if gateway is defined and gateway != address.address %} +{% if iface.vrf %} + up ip route add default via {{ gateway | ipaddr('address') }} {% if iface.vrf.name %}vrf {{ iface.vrf.name }}{% endif +%} +{% else %} gateway {{ gateway | ipaddr('address') }} {% endif %} {% endif %} +{% endif %} {% endfor -%} {# disable SLAAC if we have a manually set IPv6 address #} From 6a5ebfe5b5c5e086510be0c84941c17d29e784aa Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Wed, 22 Oct 2025 18:48:52 +0200 Subject: [PATCH 4/5] =?UTF-8?q?alpine:=20don=E2=80=99t=20disable=20IPv6=20?= =?UTF-8?q?autoconf=20on=20loopback=20interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not sure if it makes a difference but let’s keep the generated config minimal. --- roles/alpine/templates/interfaces.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/alpine/templates/interfaces.j2 b/roles/alpine/templates/interfaces.j2 index a18ebbe..882e93e 100644 --- a/roles/alpine/templates/interfaces.j2 +++ b/roles/alpine/templates/interfaces.j2 @@ -47,7 +47,7 @@ iface {{ iface.name }} {% endfor -%} {# disable SLAAC if we have a manually set IPv6 address #} -{% if iface.ip_addresses | selectattr("family.value", "==", 6) %} +{% if iface.ip_addresses | selectattr("family.value", "==", 6) and iface.name != "lo" %} pre-up echo 0 > /proc/sys/net/ipv6/conf/$IFACE/autoconf {% endif %} From 2f02f1eb2c55b608ae8630178e874565ce0b298a Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Wed, 22 Oct 2025 19:28:53 +0200 Subject: [PATCH 5/5] debian: enable automatic upgrades only for virtual machines And factor out VM stuff into a separate file. --- roles/debian/tasks/main.yml | 16 +++------------- roles/debian/tasks/vm.yml | 12 ++++++++++++ 2 files changed, 15 insertions(+), 13 deletions(-) create mode 100644 roles/debian/tasks/vm.yml diff --git a/roles/debian/tasks/main.yml b/roles/debian/tasks/main.yml index 11d7942..cf25d0e 100644 --- a/roles/debian/tasks/main.yml +++ b/roles/debian/tasks/main.yml @@ -89,19 +89,6 @@ include_tasks: firewall.yml when: not is_proxmox # proxmox has its own firewall configuration -- name: Install automatic upgrade package - package: - name: unattended-upgrades - -- name: Configure automatic upgrades - lineinfile: - path: /etc/apt/apt.conf.d/20auto-upgrades - create: yes - line: '{{ item }}' - loop: - - 'APT::Periodic::Update-Package-Lists "1";' - - 'APT::Periodic::Unattended-Upgrade "1";' - - name: Run SSH instance in management VRF when: interfaces | selectattr('vrf') | selectattr('vrf.name', '==', 'mgmt') block: @@ -124,3 +111,6 @@ name: sshd@mgmt enabled: yes notify: reboot + +- when: is_virtual + include_tasks: vm.yml diff --git a/roles/debian/tasks/vm.yml b/roles/debian/tasks/vm.yml new file mode 100644 index 0000000..1b6fa97 --- /dev/null +++ b/roles/debian/tasks/vm.yml @@ -0,0 +1,12 @@ +- name: Install automatic upgrade package + package: + name: unattended-upgrades + +- name: Configure automatic upgrades + lineinfile: + path: /etc/apt/apt.conf.d/20auto-upgrades + create: yes + line: '{{ item }}' + loop: + - 'APT::Periodic::Update-Package-Lists "1";' + - 'APT::Periodic::Unattended-Upgrade "1";'