Compare commits

...

11 commits

Author SHA1 Message Date
Ada
f4109954e1
wip
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-04-22 18:08:14 +02:00
Ada
440ab26df6
WIP 2024-04-22 18:08:14 +02:00
Ada
c20f8e5df0
WIP 2024-04-22 18:08:14 +02:00
Ada
c9a1def59e
Add knot roles 2024-04-22 18:08:11 +02:00
Ada
c2b15b5eaa
Add upgrade playbook
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-04-22 18:02:01 +02:00
Ada
f8cbb9b783
Add gitignore 2024-04-22 17:59:44 +02:00
Ada
30cd1289c0
Add knot authoritative dns
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-18 20:42:26 +02:00
Ada
3ddcd23102
Add DHCP
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-17 15:07:25 +02:00
Ada
f5c29bad3f
Add UFW firewall for debian based distro
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-17 11:30:18 +02:00
Ada
b7c5c87319
Fix fail2ban backend 2024-04-17 11:23:06 +02:00
Ada
9ed1ddfc97
Add knot roles 2024-04-17 11:23:04 +02:00
39 changed files with 670 additions and 25 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
venv/

View file

@ -1,2 +1,3 @@
---
skip_list: skip_list:
- '403' # Package installs should not use latest. - "403" # Package installs should not use latest.

33
ansible/deploy.yml Normal file
View file

@ -0,0 +1,33 @@
---
- name: Configure base
hosts: all
become: true
roles:
- role: dnf
when: ansible_facts['os_family'] == "RedHat"
- auditd
- fail2ban
- journald
- sshd
- role: timesyncd
when: ansible_facts['os_family'] == "Debian"
- role: ufw
when: ansible_facts['os_family'] == "Ubuntu"
- name: Resolver
hosts: resolver
become: true
roles:
- knot_resolver
- name: DHCP
hosts: kea-dhcp
become: true
roles:
- kea_dhcp
- name: Knot
hosts: dns-authoritative
become: true
roles:
- knot

View file

@ -0,0 +1,2 @@
---
resolver_ip: 10.20.0.42

View file

@ -0,0 +1,11 @@
---
acls:
- id: ddns
action: update
address: 10.20.0.42/32
zones:
- domain: lab.r4.pm
acl: ddns
listen_ip: 10.20.0.44

View file

@ -0,0 +1,19 @@
---
domain: r4.pm
domain_search:
- lab.r4.pm
- r4.pm
networks:
- subnet: 10.15.0.0/24
start: 10.15.0.200
end: 10.15.0.254
routers: 10.15.0.1
- subnet: 10.20.0.0/24
start: 10.20.0.200
end: 10.20.0.254
routers: 10.20.0.1
- subnet: 10.30.0.0/24
start: 10.30.0.200
end: 10.30.0.254
routers: 10.30.0.1

View file

@ -0,0 +1,9 @@
---
kresd_allow:
- 10.0.0.0/8
- 172.16.0.0/12
forward:
- zone: lab.r4.pm.
address: 10.20.0.44
ds: "lab.r4.pm. DS 61454 13 4 c510acc4a85ee8cfd93205b0cdc8d65a9e5376cf45517e5bd7db7fc836d076df688b11cf7f3a3b33a9b1011d74d00e74"

28
ansible/hosts.yml Normal file
View file

@ -0,0 +1,28 @@
<<<<<<< HEAD
---
=======
>>>>>>> 2410885 (Add knot roles)
all:
hosts:
resolver-1:
ansible_host: 10.20.0.42
<<<<<<< HEAD
dhcp-1:
ansible_host: 10.20.0.43
authoritative-1:
ansible_host: 10.20.0.44
=======
>>>>>>> 2410885 (Add knot roles)
children:
resolver:
hosts:
resolver-1:
<<<<<<< HEAD
kea-dhcp:
hosts:
dhcp-1:
dns-authoritative:
hosts:
authoritative-1:
=======
>>>>>>> 2410885 (Add knot roles)

View file

@ -10,8 +10,10 @@
- journald - journald
- sshd - sshd
- role: timesyncd - role: timesyncd
when: ansible_facts['os_family'] == "Ubuntu" when: ansible_facts['os_family'] == "Debian"
- role: ufw
when: ansible_facts['os_family'] == "Debian"
post_tasks: post_tasks:
- name: Clean cloud-init - name: Clean cloud-init
ansible.builtin.command: "cloud-init clean" ansible.builtin.command: cloud-init clean
changed_when: false changed_when: false

0
ansible/roles/auditd/files/custom.rules Executable file → Normal file
View file

0
ansible/roles/auditd/handlers/main.yml Executable file → Normal file
View file

4
ansible/roles/auditd/tasks/main.yml Executable file → Normal file
View file

@ -19,6 +19,6 @@
- name: Add rules - name: Add rules
ansible.builtin.copy: ansible.builtin.copy:
src: 'custom.rules' src: custom.rules
dest: '/etc/audit/rules.d/custom.rules' dest: /etc/audit/rules.d/custom.rules
mode: "0640" mode: "0640"

View file

@ -0,0 +1,19 @@
---
- name: Package cache update
become: true
ansible.builtin.package:
update_cache: true
- name: Restart knot resolver
become: true
ansible.builtin.service:
state: restarted
name: kresd@{{ item }}.service
with_sequence: count={{ ansible_processor_vcpus }}
- name: Enable knot resolver
become: true
ansible.builtin.service:
enabled: true
name: kresd@{{ item }}.service
with_sequence: count={{ ansible_processor_vcpus }}

View file

@ -0,0 +1,43 @@
---
- name: Get authentik source
ansible.builtin.git:
repo: https://github.com/goauthentik/authentik.git
dest: /opt/authentik/src
version: version/2024.2.2
force: true
- name: Build front
ansible.builtin.shell:
executable: /bin/bash
cmd: |
export NODE_ENV=production
cd /opt/authentik/src/website
npm ci --include=dev
npm run build-docs-only
cd /opt/authentik/src/web
npm ci --include=dev
npm run build
- name: Build go proxy
ansible.builtin.shell:
executable: /bin/bash
cmd: |
cd /opt/authentik/src/
go mod download
CGO_ENABLED=0 go build -o /opt/authentik/server ./cmd/server
- name: Create virtualenv
ansible.builtin.command: python3.12 -m venv /opt/authentik/src/venv
- name: Installl poetry and dependencies
ansible.builtin.shell:
executable: /bin/bash
cmd: |
cd /opt/authentik/src
source /opt/authentik/src/venv/bin/activate
export VENV_PATH=/opt/authentik/src/venv
export POETRY_VIRTUALENVS_CREATE=false
venv/bin/pip3 install --upgrade pip
venv/bin/pip3 install poetry
venv/bin/poetry venv use venv/python3.12
venv/bin/poetry install --only=main --no-ansi --no-interaction --no-root

View file

@ -0,0 +1,63 @@
---
- name: Install roles dependencies
ansible.builtin.apt:
install_recommends: false
name: "{{ item }}"
with_items:
- git
- build-essential
- pkg-config
- zlib1g-dev
- libpq-dev
- libxmlsec1-dev
- name: Add deadsnake ppa for python3.12
ansible.builtin.apt_repository:
repo: ppa:deadsnakes/ppa
- name: Install python3.12
ansible.builtin.apt:
name: "{{ item }}"
with_items:
- python3.12
- python3.12-distutils
- python3.12-venv
- python3.12-dev
- name: Add longsleep ppa for go 1.22
ansible.builtin.apt_repository:
repo: ppa:longsleep/golang-backports
- name: Install go 1.22
ansible.builtin.apt:
name: golang-go
- name: Download node GPG key
ansible.builtin.get_url:
url: https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key
dest: /usr/share/keyrings/node-archive-keyring.asc
mode: "0644"
validate_certs: true
checksum: sha512:36c77b2bddaea0523ab90962a38ebd3ee90c3d5cf17e525f02898aa8e7b14fd1026f6d659b99d931fe907e9142a98ff08075ebfc56f0f1e2001c6ba4791d3daa
changed_when: false
no_log: false
- name: Add nodesource repo for node
ansible.builtin.apt_repository:
repo: deb [arch=amd64 signed-by=/usr/share/keyrings/node-archive-keyring.asc] https://deb.nodesource.com/node_21.x nodistro main
- name: Install nodejs
ansible.builtin.apt:
name: nodejs
- name: Add authentik user
ansible.builtin.user:
name: authentik
system: true
- name: Create /opt/authentik
ansible.builtin.file:
path: /opt/authentik
state: directory
mode: "0755"
owner: authentik

View file

@ -0,0 +1,32 @@
---
- name: Install dependencies
ansible.builtin.import_tasks: dependencies.yml
become: true
tags:
- install_dependencies
- name: Build authentik
ansible.builtin.import_tasks: build.yml
become: true
tags:
- build
become_user: authentik
- name: Create useful directory
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: "0755"
owner: authentik
with_items:
- /opt/authentik/certs
- /opt/authentik/media
- /etc/authentik
- name: Test
ansible.builtin.copy:
remote_src: true
src: /opt/authentik/src/blueprints
dest: /opt/authentik/blueprints
owner: authentik
become: true

View file

@ -0,0 +1,26 @@
net.listen('{{resolver_ip}}', 53, { kind = 'dns'})
cache.size = 128 * MB
modules = {
'hints > iterate', -- Allow loading /etc/hosts or custom root hints
'predict', -- Prefetch expiring/frequent records
}
modules.load('prefill')
prefill.config({
['.'] = {
url = 'https://www.internic.net/domain/root.zone',
interval = 86400, -- seconds
}
})
modules.load('view')
view:addr('127.0.0.0/8', policy.all(policy.PASS))
view:addr('::1/128', policy.all(policy.PASS))
{% for prefix in kresd_allow %}
view:addr('{{ prefix }}', policy.all(policy.PASS))
{% endfor %}
view:addr('0.0.0.0/0', policy.all(policy.DROP))
view:addr('::/0', policy.all(policy.DROP))
log_target('stdout')
log_level('debug')

View file

@ -6,5 +6,5 @@
- name: Install epel - name: Install epel
ansible.builtin.dnf: ansible.builtin.dnf:
name: "epel-release" name: epel-release
state: "latest" state: latest

0
ansible/roles/fail2ban/handlers/main.yml Executable file → Normal file
View file

8
ansible/roles/fail2ban/tasks/main.yml Executable file → Normal file
View file

@ -1,20 +1,20 @@
--- ---
- name: Install fail2ban - name: Install fail2ban
ansible.builtin.apt: ansible.builtin.apt:
name: "fail2ban" name: fail2ban
state: latest state: latest
when: ansible_facts['os_family'] == "Debian" when: ansible_facts['os_family'] == "Debian"
- name: Install fail2ban - name: Install fail2ban
ansible.builtin.dnf: ansible.builtin.dnf:
name: "fail2ban" name: fail2ban
state: latest state: latest
when: ansible_facts['os_family'] == "RedHat" when: ansible_facts['os_family'] == "RedHat"
- name: Copy sshd.conf - name: Copy sshd.conf
ansible.builtin.template: ansible.builtin.template:
src: 'sshd.conf.j2' src: sshd.conf.j2
dest: '/etc/fail2ban/jail.d/sshd.conf' dest: /etc/fail2ban/jail.d/sshd.conf
mode: "0640" mode: "0640"
notify: notify:
- Restart fail2ban - Restart fail2ban

2
ansible/roles/fail2ban/templates/sshd.conf.j2 Executable file → Normal file
View file

@ -2,7 +2,7 @@
enabled = true enabled = true
bantime = -1 bantime = -1
maxretry = 3 maxretry = 3
{% if ansible_facts['os_family'] == "RedHat" %}
backend = systemd backend = systemd
{% if ansible_facts['os_family'] == "RedHat" %}
banaction = firewallcmd-ipset banaction = firewallcmd-ipset
{% endif %} {% endif %}

0
ansible/roles/journald/files/retention-time.conf Executable file → Normal file
View file

0
ansible/roles/journald/handlers/main.yml Executable file → Normal file
View file

8
ansible/roles/journald/tasks/main.yml Executable file → Normal file
View file

@ -1,14 +1,14 @@
--- ---
- name: Create /etc/systemd/journald.conf.d - name: Create /etc/systemd/journald.conf.d
ansible.builtin.file: ansible.builtin.file:
path: '/etc/systemd/journald.conf.d' path: /etc/systemd/journald.conf.d
state: 'directory' state: directory
mode: "0750" mode: "0750"
- name: Copy retention-time.conf - name: Copy retention-time.conf
ansible.builtin.copy: ansible.builtin.copy:
src: 'retention-time.conf' src: retention-time.conf
dest: '/etc/systemd/journald.conf.d' dest: /etc/systemd/journald.conf.d
mode: "0640" mode: "0640"
notify: notify:
- Restart journald - Restart journald

View file

@ -0,0 +1,11 @@
---
- name: Restart isc-kea-dhcp4-server
become: true
ansible.builtin.service:
state: restarted
name: isc-kea-dhcp4-server
- name: Enable isc-kea-dhcp4-server
ansible.builtin.service:
enabled: true
name: isc-kea-dhcp4-server

View file

@ -0,0 +1,40 @@
---
- name: Add kea dhcp pgp key
ansible.builtin.get_url:
url: https://dl.cloudsmith.io/public/isc/kea-2-4/gpg.0D9D9A1439E23DB9.key
dest: /usr/share/keyrings/kea-archive-keyring.asc
mode: "0644"
validate_certs: true
checksum: sha512:f58db6baa7f7147c3280275b6f7cc11e34836fb904604d587c1883e6b4a8e89377046809203e2f1a1a87a7f28556728a9ecdb740d62e753592d2dbab0d2e87c8
changed_when: false
no_log: false
- name: Add kea dhcp repository
ansible.builtin.apt_repository:
repo: "deb [signed-by=/usr/share/keyrings/kea-archive-keyring.asc]
https://dl.cloudsmith.io/public/isc/kea-2-4/deb/{{ ansible_distribution|lower }} {{ ansible_distribution_release }} main"
state: present
filename: isc-kea-dhcp
- name: Install isc-kea-dhcp
ansible.builtin.apt:
name: isc-kea-dhcp4-server
notify:
- Enable isc-kea-dhcp4-server
- name: Configure isc-kea-dhcp
ansible.builtin.template:
src: kea-dhcp4.conf.j2
dest: /etc/kea/kea-dhcp4.conf
owner: _kea
mode: '0640'
notify:
- Restart isc-kea-dhcp4-server
- name: Open required ports
community.general.ufw:
rule: allow
port: "{{ item }}"
proto: udp
with_items:
- '67'

View file

@ -0,0 +1,79 @@
{
"Dhcp4": {
"interfaces-config": {
"interfaces": [ "eth0" ],
},
"control-socket": {
"socket-type": "unix",
"socket-name": "/tmp/kea4-ctrl-socket"
},
"lease-database": {
// Memfile is the simplest and easiest backend to use. It's an in-memory
// C++ database that stores its state in CSV file.
"type": "memfile",
"lfc-interval": 3600
},
"expired-leases-processing": {
"reclaim-timer-wait-time": 10,
"flush-reclaimed-timer-wait-time": 25,
"hold-reclaimed-time": 3600,
"max-reclaim-leases": 100,
"max-reclaim-time": 250,
"unwarned-reclaim-cycles": 5
},
"renew-timer": 900,
"rebind-timer": 1800,
"valid-lifetime": 3600,
"option-data": [
{
"name": "domain-name-servers",
"data": "{{ resolver_ip }}"
},
{
"code": 15,
"data": "{{ domain }}"
},
{
"name": "domain-search",
"data": "{{ domain_search|join(', ') }}"
},
],
"subnet4": [
{% for network in networks %}
{
"subnet": "{{ network.subnet }}",
"pools": [ { "pool": "{{ network.start }} - {{ network.end }}" } ],
"option-data": [
{
"name": "routers",
"data": "{{ network.routers }}"
}
],
}{% if not loop.last %},{% endif %}
{% endfor %}
],
"loggers": [
{
"name": "kea-dhcp4",
"output_options": [
{
"output": "stdout",
}
],
"severity": "INFO",
"debuglevel": 0
}
]
}
}

View file

@ -0,0 +1,12 @@
$ORIGIN lab.r4.pm.
$TTL 3600
@ IN SOA knot.lab.r4.pm. admin.r4.pm. (
2024041800 ; serial number
12h ; refresh
15m ; update retry
3w ; expiry
2h ; minimum
)
@ 86400 IN NS knot.lab.r4.pm.
knot.lab.r4.pm. 86400 IN A 10.20.0.44

View file

@ -0,0 +1,15 @@
---
- name: Restart knot
ansible.builtin.service:
state: restarted
name: knot
- name: Reload knot
ansible.builtin.service:
state: reloaded
name: knot
- name: Enable knot
ansible.builtin.service:
enabled: true
name: knot

View file

@ -0,0 +1,57 @@
---
- name: Add knot pgp key
ansible.builtin.get_url:
url: https://pkg.labs.nic.cz/gpg
dest: /usr/share/keyrings/cznic-labs-pkg.gpg
mode: "0644"
validate_certs: true
checksum: sha512:e78a1404feff1040c86f4a199495e4a2cf82684b8ff22ffc318a9bffa0ddf45136e484bc17e4440660c089e1c186af77008c76fb463434611b1f60709b57ee52
changed_when: false
no_log: false
- name: Add knot repository
ansible.builtin.apt_repository:
repo: "deb [signed-by=/usr/share/keyrings/cznic-labs-pkg.gpg] https://pkg.labs.nic.cz/knot-dns {{ ansible_distribution_release }} main"
state: present
filename: knot-dns
- name: Install knot
ansible.builtin.apt:
name: knot
notify:
- Enable knot
- Restart knot
- name: Configure knot
ansible.builtin.template:
src: knot.conf.j2
dest: /etc/knot/knot.conf
owner: knot
mode: '0640'
notify: Restart knot
- name: Allow port 53 (DNS)
community.general.ufw:
rule: allow
port: "{{ item.port }}"
proto: "{{ item.proto }}"
with_items:
- { port: "53", proto: tcp }
- { port: "53", proto: udp }
- name: Create knot zones directory
ansible.builtin.file:
path: /var/lib/knot/zones/
state: directory
mode: '0750'
owner: knot
- name: Copy zone
ansible.builtin.copy:
src: "{{ item }}"
dest: /var/lib/knot/zones/
owner: knot
mode: '0640'
with_fileglob:
- zones/*
notify: Reload knot

View file

@ -0,0 +1,32 @@
server:
rundir: "/run/knot"
user: knot:knot
automatic-acl: on
listen: [ {{ listen_ip }}@53 ]
log:
- target: syslog
any: info
database:
storage: "/var/lib/knot"
acl:
{% for acl in acls %}
- id: {{ acl.id }}
address: {{ acl.address }}
action: {{ acl.action }}
{% endfor %}
template:
- id: default
storage: "/var/lib/knot/zones"
file: "%s.zone"
dnssec-signing: on
serial-policy: dateserial
zone:
{% for zone in zones %}
- domain: {{ zone.domain }}
acl: {{ zone.acl }}
{% endfor %}

View file

@ -0,0 +1,19 @@
---
- name: Package cache update
become: true
ansible.builtin.package:
update_cache: true
- name: Restart knot resolver
become: true
ansible.builtin.service:
state: restarted
name: kresd@{{ item }}.service
with_sequence: count={{ ansible_processor_vcpus }}
- name: Enable knot resolver
become: true
ansible.builtin.service:
enabled: true
name: kresd@{{ item }}.service
with_sequence: count={{ ansible_processor_vcpus }}

View file

@ -0,0 +1,30 @@
---
- name: Install knot repository
ansible.builtin.apt:
deb: https://secure.nic.cz/files/knot-resolver/knot-resolver-release.deb
notify:
- Package cache update
- name: Install knot resolver
ansible.builtin.apt:
name: knot-resolver
notify:
- Enable knot resolver
- Restart knot resolver
- name: Configure
ansible.builtin.template:
src: kresd.conf.j2
dest: /etc/knot-resolver/kresd.conf
mode: "0644"
notify:
- Restart knot resolver
- name: Allow port 53 (DNS)
community.general.ufw:
rule: allow
port: "{{ item.port }}"
proto: "{{ item.proto }}"
with_items:
- { port: "53", proto: tcp }
- { port: "53", proto: udp }

View file

@ -0,0 +1,30 @@
net.listen('{{resolver_ip}}', 53, { kind = 'dns'})
cache.size = 128 * MB
modules = {
'hints > iterate', -- Allow loading /etc/hosts or custom root hints
'predict', -- Prefetch expiring/frequent records
}
modules.load('prefill')
prefill.config({
['.'] = {
url = 'https://www.internic.net/domain/root.zone',
interval = 86400, -- seconds
}
})
modules.load('view')
view:addr('127.0.0.0/8', policy.all(policy.PASS))
view:addr('::1/128', policy.all(policy.PASS))
{% for prefix in kresd_allow %}
view:addr('{{ prefix }}', policy.all(policy.PASS))
{% endfor %}
view:addr('0.0.0.0/0', policy.all(policy.DROP))
view:addr('::/0', policy.all(policy.DROP))
{% for zones in forward %}
policy.add(policy.suffix(policy.FORWARD('{{ zones.address }}'), {todname('{{ zones.zone }}')}))
trust_anchors.add('{{ zones.ds }}')
{% endfor %}
log_target('stdout')
log_level('info')

View file

@ -1,3 +1,4 @@
---
- name: Restart SSH - name: Restart SSH
ansible.builtin.service: ansible.builtin.service:
name: sshd name: sshd

View file

@ -2,8 +2,8 @@
- name: Disable Password Authentication - name: Disable Password Authentication
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config dest: /etc/ssh/sshd_config
regexp: '^PasswordAuthentication' regexp: ^PasswordAuthentication
line: "PasswordAuthentication no" line: PasswordAuthentication no
state: present state: present
backup: true backup: true
notify: notify:
@ -12,8 +12,8 @@
- name: Disable Root Login - name: Disable Root Login
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config dest: /etc/ssh/sshd_config
regexp: '^PermitRootLogin' regexp: ^PermitRootLogin
line: "PermitRootLogin no" line: PermitRootLogin no
state: present state: present
backup: true backup: true
notify: notify:
@ -22,8 +22,8 @@
- name: Restrict host key - name: Restrict host key
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config dest: /etc/ssh/sshd_config
regexp: '#HostKey /etc/ssh/ssh_host_ed25519_key' regexp: "#HostKey /etc/ssh/ssh_host_ed25519_key"
line: "HostKey /etc/ssh/ssh_host_ed25519_key" line: HostKey /etc/ssh/ssh_host_ed25519_key
state: present state: present
backup: true backup: true
notify: notify:
@ -31,8 +31,8 @@
- name: Configure sshd - name: Configure sshd
ansible.builtin.copy: ansible.builtin.copy:
src: "crypto.conf" src: crypto.conf
dest: "/etc/ssh/sshd_config.d/" dest: /etc/ssh/sshd_config.d/
owner: root owner: root
group: root group: root
mode: "0640" mode: "0640"

2
ansible/roles/timesyncd/tasks/main.yml Executable file → Normal file
View file

@ -4,5 +4,5 @@
name: Europe/Brussels name: Europe/Brussels
- name: Enable ntp - name: Enable ntp
ansible.builtin.command: 'timedatectl set-ntp true' ansible.builtin.command: timedatectl set-ntp true
changed_when: false changed_when: false

View file

@ -0,0 +1,14 @@
---
- name: Install UFW
ansible.builtin.apt:
name: ufw
- name: Allow 22/tcp (SSH)
community.general.ufw:
rule: allow
port: "22"
proto: tcp
- name: Enable UFW
community.general.ufw:
state: enabled

16
ansible/upgrade.yml Normal file
View file

@ -0,0 +1,16 @@
---
- name: Upgreade
hosts: all
become: true
tasks:
- name: Ugrade debian based
ansible.builtin.apt:
update_cache: true
upgrade: true
when: ansible_facts['os_family'] == "Debian"
- name: Upgrade all packages
ansible.builtin.dnf:
name: "*"
state: latest
when: ansible_facts['os_family'] == "RedHat"