diff --git a/roles/backup/handlers/main.yml b/roles/backup/handlers/main.yml
index e80266417eef64beb96acdb1bfb3e87a05f4053e..17ac19038e5f35451aae918b1279d0b174588963 100644
--- a/roles/backup/handlers/main.yml
+++ b/roles/backup/handlers/main.yml
@@ -1,7 +1,7 @@
 ---
 
 - name: Assemble Duply include patterns
-  assemble:
+  ansible.builtin.assemble:
     dest: "/etc/duply/main/include"
     src: "/etc/duply/main/patterns"
     owner: root
diff --git a/roles/backup/molecule/default/prepare.yml b/roles/backup/molecule/default/prepare.yml
index eefd77c3d02929d5fe3bed6cc81072fdb26e7060..ad4260a270d56a9bbe635a177383b7e91432684d 100644
--- a/roles/backup/molecule/default/prepare.yml
+++ b/roles/backup/molecule/default/prepare.yml
@@ -7,10 +7,10 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
diff --git a/roles/backup/tasks/main.yml b/roles/backup/tasks/main.yml
index d4f756b5a9b53fee2b25f9d5577311219ff79b82..5812d96fc008b10d4422921a687344a2e1ae7779 100644
--- a/roles/backup/tasks/main.yml
+++ b/roles/backup/tasks/main.yml
@@ -1,7 +1,7 @@
 ---
 
 - name: Configure backup patterns
-  template:
+  ansible.builtin.template:
     src: "backup_patterns.j2"
     dest: "/etc/duply/main/patterns/{{ backup_patterns_filename }}"
     owner: root
@@ -11,7 +11,7 @@
     - Assemble Duply include patterns
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/backup_client/handlers/main.yml b/roles/backup_client/handlers/main.yml
index bb42e51c762fc7dc69777db0c94b94f3e3778fbf..056198233719bea7ff880dd73000d6b1bd4e7c47 100644
--- a/roles/backup_client/handlers/main.yml
+++ b/roles/backup_client/handlers/main.yml
@@ -7,10 +7,10 @@
   #   This task is invoked only if user is very specific about requiring to
   #   run the handlers manually as a way to bring the system to consistency
   #   after interrupted runs.
-  command: "rm -rf /etc/duply/main/gnupg"
+  ansible.builtin.command: "rm -rf /etc/duply/main/gnupg"
 
 - name: Create keyring directory
-  file:
+  ansible.builtin.file:
     path: "/etc/duply/main/gnupg"
     state: directory
     owner: root
@@ -22,12 +22,12 @@
   #   This task is invoked only if user is very specific about requiring to
   #   run the handlers manually as a way to bring the system to consistency
   #   after interrupted runs.
-  command: "gpg --no-tty --homedir /etc/duply/main/gnupg --import /etc/duply/main/private_keys.asc"
+  ansible.builtin.command: "gpg --no-tty --homedir /etc/duply/main/gnupg --import /etc/duply/main/private_keys.asc"
 
 - name: Import public keys  # noqa no-changed-when
   # [no-changed-when] Commands should not change things if nothing needs doing
   #   This task is invoked only if user is very specific about requiring to
   #   run the handlers manually as a way to bring the system to consistency
   #   after interrupted runs.
-  command: "gpg --no-tty --homedir /etc/duply/main/gnupg --import /etc/duply/main/public_keys.asc"
+  ansible.builtin.command: "gpg --no-tty --homedir /etc/duply/main/gnupg --import /etc/duply/main/public_keys.asc"
   when: backup_additional_encryption_keys | length > 0
diff --git a/roles/backup_client/molecule/default/converge.yml b/roles/backup_client/molecule/default/converge.yml
index 01a6de15bf3f0a336c0f650bfb66c844806f00e9..d79497e4529129377f974bac48c7ed3a0ce2914f 100644
--- a/roles/backup_client/molecule/default/converge.yml
+++ b/roles/backup_client/molecule/default/converge.yml
@@ -13,7 +13,7 @@
   tasks:
 
     - name: Deploy pre-backup script
-      copy:
+      ansible.builtin.copy:
         src: tests/data/10-test-pre-backup.sh
         dest: /etc/duply/main/pre.d/10-test-pre-backup.sh
         owner: root
diff --git a/roles/backup_client/molecule/default/prepare.yml b/roles/backup_client/molecule/default/prepare.yml
index 8bd2d5b25faf4c7e24752fd7809ceff043252cb5..2b9e2e137365788216a5abab6af98a98e39bef64 100644
--- a/roles/backup_client/molecule/default/prepare.yml
+++ b/roles/backup_client/molecule/default/prepare.yml
@@ -7,11 +7,11 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
 
@@ -21,7 +21,7 @@
   tasks:
 
     - name: Deploy SSH server keys
-      copy:
+      ansible.builtin.copy:
         content: "{{ lookup('file', item.key) + '\n' }}"
         dest: "{{ item.value }}"
         owner: root
@@ -35,7 +35,7 @@
         - Restart ssh
 
     - name: Drop the outdated public keys
-      file:
+      ansible.builtin.file:
         path: "{{ item }}"
         state: absent
       with_items:
@@ -44,14 +44,14 @@
         - /etc/ssh/ssh_host_ecdsa_key.pub
 
     - name: Force the use of internal-sftp subsystem for SFTP
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/ssh/sshd_config
         regexp: "^Subsystem.*sftp"
         line: "Subsystem sftp internal-sftp"
         state: present
 
     - name: Deploy custom SSH server configuration that chroots users
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/backup_server-sshd-chroot_backup_users.conf"
         dest: "/etc/ssh/sshd_config.d/chroot_backup_users.conf"
         owner: root
@@ -61,16 +61,16 @@
         - Restart ssh
 
     - name: Set-up backup group that will contain all backup users
-      group:
+      ansible.builtin.group:
         name: "backup-users"
 
     - name: Set-up backup user groups
-      group:
+      ansible.builtin.group:
         name: "{{ item.name }}"
       with_items: "{{ backup_users }}"
 
     - name: Set-up backup users
-      user:
+      ansible.builtin.user:
         name: "{{ item.name }}"
         group: "{{ item.name }}"
         groups:
@@ -78,20 +78,20 @@
       with_items: "{{ backup_users }}"
 
     - name: Set-up authorised keys
-      authorized_key:
+      ansible.posix.authorized_key:
         user: "{{ item.name }}"
         key: "{{ item.key }}"
       with_items: "{{ backup_users }}"
 
     - name: Set-up port forwarding
-      command: "iptables -t nat -A PREROUTING -p tcp -m tcp --dport '{{ item }}' -j REDIRECT --to-ports 22"
+      ansible.builtin.command: "iptables -t nat -A PREROUTING -p tcp -m tcp --dport '{{ item }}' -j REDIRECT --to-ports 22"
       changed_when: false
       with_items:
         - 2222
         - 3333
 
     - name: Change ownership of home directories for SFTP chroot to work
-      file:
+      ansible.builtin.file:
         path: "/home/{{ item.name }}"
         state: directory
         owner: root
@@ -100,7 +100,7 @@
       with_items: "{{ backup_users }}"
 
     - name: Set-up duplicity backup directories
-      file:
+      ansible.builtin.file:
         path: "~{{ item.name }}/duplicity"
         state: directory
         owner: root
@@ -110,7 +110,7 @@
 
   handlers:
     - name: Restart ssh
-      service:
+      ansible.builtin.service:
         name: ssh
         state: restarted
 
diff --git a/roles/backup_client/tasks/main.yml b/roles/backup_client/tasks/main.yml
index c09f302722240da8b39868b7f2fe68bce8bd935d..dcbcd1d0581ee168fb8a8100d5c47715326d0f23 100644
--- a/roles/backup_client/tasks/main.yml
+++ b/roles/backup_client/tasks/main.yml
@@ -1,14 +1,14 @@
 ---
 
 - name: Install backup software
-  apt:
+  ansible.builtin.apt:
     name:
       - duplicity
       - duply
     state: present
 
 - name: Set-up Duply directories
-  file:
+  ansible.builtin.file:
     path: "{{ item }}"
     state: directory
     owner: root
@@ -24,7 +24,7 @@
     - "/var/cache/duply/main"
 
 - name: Deploy GnuPG private keys
-  copy:
+  ansible.builtin.copy:
     content: "{{ backup_encryption_key }}"
     dest: "/etc/duply/main/private_keys.asc"
     owner: root
@@ -37,7 +37,7 @@
     - Import public keys
 
 - name: Deploy GnuPG public keys
-  copy:
+  ansible.builtin.copy:
     content: "{{ backup_additional_encryption_keys | join('\n') }}"
     dest: "/etc/duply/main/public_keys.asc"
     owner: root
@@ -50,7 +50,7 @@
     - Import public keys
 
 - name: Extract encryption key identifier (Duplicty requires key ID in hexadecimal format)
-  shell: "set -o pipefail && gpg --no-tty --list-packets /etc/duply/main/private_keys.asc | grep keyid: |
+  ansible.builtin.shell: "set -o pipefail && gpg --no-tty --list-packets /etc/duply/main/private_keys.asc | grep keyid: |
     head -n1 | sed -e 's/.*: //'"
   args:
     executable: /bin/bash
@@ -59,7 +59,7 @@
   failed_when: not backup_encryption_key_id.stdout
 
 - name: Extract additional encryption keys identifiers (Duplicty requires key ID in hexadecimal format)
-  shell: "set -o pipefail &&  gpg --no-tty --list-packets /etc/duply/main/public_keys.asc | grep keyid: |
+  ansible.builtin.shell: "set -o pipefail &&  gpg --no-tty --list-packets /etc/duply/main/public_keys.asc | grep keyid: |
     sed -e 's/.*: //' | sort -u | tr '\n' ',' | sed -e 's/,$//'"
   args:
     executable: /bin/bash
@@ -69,7 +69,7 @@
   failed_when: not backup_additional_encryption_keys_ids.stdout
 
 - name: Deploy private SSH key for logging-in into backup server
-  copy:
+  ansible.builtin.copy:
     content: "{{ backup_ssh_key }}"
     dest: "/etc/duply/main/ssh/identity"
     owner: root
@@ -78,7 +78,7 @@
   no_log: true
 
 - name: Deploy custom known_hosts for backup purposes
-  template:
+  ansible.builtin.template:
     src: "known_hosts.j2"
     dest: "/etc/duply/main/ssh/known_hosts"
     owner: root
@@ -86,7 +86,7 @@
     mode: "0600"
 
 - name: Deploy Duply configuration file
-  template:
+  ansible.builtin.template:
     src: "duply_main_conf.j2"
     dest: "/etc/duply/main/conf"
     owner: root
@@ -94,7 +94,7 @@
     mode: "0600"
 
 - name: Deploy base exclude pattern (exclude all by default)
-  copy:
+  ansible.builtin.copy:
     content: "- **"
     dest: "/etc/duply/main/exclude"
     owner: root
@@ -102,7 +102,7 @@
     mode: "0600"
 
 - name: Set-up directory for storing pre-backup scripts
-  file:
+  ansible.builtin.file:
     path: "/etc/duply/main/pre.d/"
     state: directory
     owner: root
@@ -110,7 +110,7 @@
     mode: "0700"
 
 - name: Set-up script for running all pre-backup scripts
-  copy:
+  ansible.builtin.copy:
     src: "duply_pre"
     dest: "/etc/duply/main/pre"
     owner: root
@@ -118,7 +118,7 @@
     mode: "0700"
 
 - name: Deploy crontab entry for running backups
-  cron:
+  ansible.builtin.cron:
     name: backup
     cron_file: backup
     hour: "2"
@@ -128,7 +128,7 @@
     user: root
 
 - name: Ensure the file with include patterns exists (but do not overwrite)
-  copy:
+  ansible.builtin.copy:
     content: ""
     dest: /etc/duply/main/include
     force: false
@@ -137,7 +137,7 @@
     mode: "0600"
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/backup_server/handlers/main.yml b/roles/backup_server/handlers/main.yml
index 918490612f90e0d3dc7be27b1d3a87677655c6c2..b963d40b3dbc95764825196b84aa67e9fc734bf3 100644
--- a/roles/backup_server/handlers/main.yml
+++ b/roles/backup_server/handlers/main.yml
@@ -1,6 +1,6 @@
 ---
 
 - name: Restart backup SSH server
-  service:
+  ansible.builtin.service:
     name: ssh-backup
     state: restarted
diff --git a/roles/backup_server/molecule/default/prepare.yml b/roles/backup_server/molecule/default/prepare.yml
index d5df27dc533f1e55e4f81dfdc20b703950416bd9..e65b73ad375ca7229b0190091f897584ffc4756e 100644
--- a/roles/backup_server/molecule/default/prepare.yml
+++ b/roles/backup_server/molecule/default/prepare.yml
@@ -6,7 +6,7 @@
   tasks:
 
     - name: Fix SSH client file permissions locally, otherwise we get error from SSH
-      file:
+      ansible.builtin.file:
         path: "{{ item }}"
         mode: g=,o=
       with_items:
@@ -20,9 +20,9 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
diff --git a/roles/backup_server/tasks/main.yml b/roles/backup_server/tasks/main.yml
index a77ff31150051e0956d88b102289b85ab4d88c42..1f1f95ee23075309473e2ac450c9811e8cddb2d7 100644
--- a/roles/backup_server/tasks/main.yml
+++ b/roles/backup_server/tasks/main.yml
@@ -1,14 +1,14 @@
 ---
 
 - name: Install backup software
-  apt:
+  ansible.builtin.apt:
     name:
       - duplicity
       - duply
     state: present
 
 - name: Create directory for storing backups
-  file:
+  ansible.builtin.file:
     path: "/srv/backups"
     state: directory
     owner: root
@@ -16,14 +16,14 @@
     mode: "0751"
 
 - name: Create backup client groups
-  group:
+  ansible.builtin.group:
     name: "{{ item.server | replace('.', '_') | regex_replace('^', 'bak-') }}"
     gid: "{{ item.uid | default(omit) }}"
     system: true
   with_items: "{{ backup_clients }}"
 
 - name: Create backup client users
-  user:
+  ansible.builtin.user:
     name: "{{ item.server | replace('.', '_') | regex_replace('^', 'bak-') }}"
     group: "{{ item.server | replace('.', '_') | regex_replace('^', 'bak-') }}"
     groups: "backup"
@@ -35,7 +35,7 @@
   with_items: "{{ backup_clients }}"
 
 - name: Create home directories for backup client users
-  file:
+  ansible.builtin.file:
     path: "/srv/backups/{{ item.server }}"
     state: directory
     owner: root
@@ -44,7 +44,7 @@
   with_items: "{{ backup_clients }}"
 
 - name: Create duplicity directories for backup client users
-  file:
+  ansible.builtin.file:
     path: "/srv/backups/{{ item.server }}/duplicity"
     state: directory
     owner: "{{ item.server | replace('.', '_') | regex_replace('^', 'bak-') }}"
@@ -53,7 +53,7 @@
   with_items: "{{ backup_clients }}"
 
 - name: Create SSH directory for backup client users
-  file:
+  ansible.builtin.file:
     path: "/srv/backups/{{ item.server }}/.ssh"
     state: directory
     owner: root
@@ -62,7 +62,7 @@
   with_items: "{{ backup_clients }}"
 
 - name: Populate authorized keys for backup client users
-  authorized_key:
+  ansible.posix.authorized_key:
     user: "{{ item.server | replace('.', '_') | regex_replace('^', 'bak-') }}"
     key: "{{ item.public_key }}"
     manage_dir: false
@@ -70,7 +70,7 @@
   with_items: "{{ backup_clients }}"
 
 - name: Set-up authorized_keys file permissions for backup client users
-  file:
+  ansible.builtin.file:
     path: "/srv/backups/{{ item.server }}/.ssh/authorized_keys"
     state: file
     owner: root
@@ -79,7 +79,7 @@
   with_items: "{{ backup_clients }}"
 
 - name: Deny the backup group login via regular SSH
-  lineinfile:
+  ansible.builtin.lineinfile:
     dest: "/etc/ssh/sshd_config"
     state: present
     line: "DenyGroups backup"
@@ -87,7 +87,7 @@
     - Restart SSH
 
 - name: Set-up directory for the backup OpenSSH server instance
-  file:
+  ansible.builtin.file:
     path: "/etc/ssh-backup/"
     state: directory
     owner: root
@@ -95,7 +95,7 @@
     mode: "0700"
 
 - name: Deploy configuration file for the backup OpenSSH server instance service
-  copy:
+  ansible.builtin.copy:
     src: "ssh-backup.default"
     dest: "/etc/default/ssh-backup"
     owner: root
@@ -105,7 +105,7 @@
     - Restart backup SSH server
 
 - name: Deploy configuration file for the backup OpenSSH server instance
-  copy:
+  ansible.builtin.copy:
     src: "backup-sshd_config"
     dest: "/etc/ssh-backup/sshd_config"
     owner: root
@@ -115,7 +115,7 @@
     - Restart backup SSH server
 
 - name: Deploy the private keys for backup OpenSSH server instance
-  template:
+  ansible.builtin.template:
     src: "ssh_host_key.j2"
     dest: "/etc/ssh-backup/ssh_host_{{ item.key }}_key"
     owner: root
@@ -127,7 +127,7 @@
   no_log: true
 
 - name: Deploy backup OpenSSH server systemd service file
-  copy:
+  ansible.builtin.copy:
     src: "ssh-backup.service"
     dest: "/etc/systemd/system/ssh-backup.service"
     owner: root
@@ -138,13 +138,13 @@
     - Restart backup SSH server
 
 - name: Start and enable OpenSSH backup service
-  service:
+  ansible.builtin.service:
     name: "ssh-backup"
     state: started
     enabled: true
 
 - name: Deploy firewall configuration for backup server
-  template:
+  ansible.builtin.template:
     src: "ferm_backup.conf.j2"
     dest: "/etc/ferm/conf.d/40-backup.conf"
     owner: root
@@ -154,7 +154,7 @@
     - Restart ferm
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/bootstrap/handlers/main.yml b/roles/bootstrap/handlers/main.yml
index 8dae2fd6fcd7ea5173f2e61f1ea32b955134ba09..64ed8c7d39295a6b5016864971d59d5a1bfc1728 100644
--- a/roles/bootstrap/handlers/main.yml
+++ b/roles/bootstrap/handlers/main.yml
@@ -1,5 +1,5 @@
 ---
 
 - name: Dummy handler to suppress Ansible warnings
-  debug:
+  ansible.builtin.debug:
     msg: "This is just a dummy task to suppress the Ansible warning about an empty include."
diff --git a/roles/bootstrap/molecule/default/prepare.yml b/roles/bootstrap/molecule/default/prepare.yml
index 7f1c268a76b571a1cedb0cf1578a7267ac17c11e..834afd2c843bf184ce4c2c515080b15b1ab70f13 100644
--- a/roles/bootstrap/molecule/default/prepare.yml
+++ b/roles/bootstrap/molecule/default/prepare.yml
@@ -7,11 +7,11 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
 
@@ -22,7 +22,7 @@
   tasks:
 
     - name: Deploy authorized_keys to mimic set-up via preseed file
-      authorized_key:
+      ansible.posix.authorized_key:
         user: root
         key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
 
@@ -33,6 +33,6 @@
   tasks:
 
     - name: Deploy authorized_keys to mimic set-up via preseed file
-      authorized_key:
+      ansible.posix.authorized_key:
         user: root
         key: "{{ lookup('file', 'tests/data/ansible_key.pub') }}"
diff --git a/roles/bootstrap/tasks/main.yml b/roles/bootstrap/tasks/main.yml
index 1a412c52d1b7a5518767caa846dfbc85a92a68df..b4a99f15f40f1d7545a950d43f1c87a259cd0bc7 100644
--- a/roles/bootstrap/tasks/main.yml
+++ b/roles/bootstrap/tasks/main.yml
@@ -1,29 +1,29 @@
 ---
 
 - name: Install sudo
-  apt:
+  ansible.builtin.apt:
     name: sudo
     state: present
 
 - name: Set-up the Ansible group
-  group:
+  ansible.builtin.group:
     name: ansible
     system: true
 
 - name: Set-up the Ansible user
-  user:
+  ansible.builtin.user:
     name: ansible
     system: true
     group: ansible
     shell: /bin/bash
 
 - name: Set-up authorized key for the Ansible user
-  authorized_key:
+  ansible.posix.authorized_key:
     user: ansible
     key: "{{ ansible_key }}"
 
 - name: Set-up password-less sudo for the ansible user
-  copy:
+  ansible.builtin.copy:
     src: "ansible_sudo"
     dest: "/etc/sudoers.d/ansible"
     mode: "0640"
@@ -31,13 +31,13 @@
     group: root
 
 - name: Revoke rights for Ansible user to log-in as root to server via ssh
-  authorized_key:
+  ansible.posix.authorized_key:
     user: root
     key: "{{ ansible_key }}"
     state: absent
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml
index 5bd739c169425f9999d638c49d843bd6d3f6012e..022af6ddfc1b2b20e04ab592c9e04293b0f861da 100644
--- a/roles/common/handlers/main.yml
+++ b/roles/common/handlers/main.yml
@@ -5,10 +5,10 @@
   #   This task is invoked only if user is very specific about requiring to
   #   run the handlers manually as a way to bring the system to consistency
   #   after interrupted runs.
-  command: "/usr/sbin/pam-auth-update --package"
+  ansible.builtin.command: "/usr/sbin/pam-auth-update --package"
 
 - name: Restart SSH
-  service:
+  ansible.builtin.service:
     name: ssh
     state: restarted
 
@@ -17,19 +17,19 @@
   #   This task is invoked only if user is very specific about requiring to
   #   run the handlers manually as a way to bring the system to consistency
   #   after interrupted runs.
-  command: "/usr/sbin/update-ca-certificates --fresh"
+  ansible.builtin.command: "/usr/sbin/update-ca-certificates --fresh"
 
 - name: Restart ferm
-  service:
+  ansible.builtin.service:
     name: ferm
     state: restarted
 
 - name: Reload systemd
-  systemd:
+  ansible.builtin.systemd:
     daemon_reload: true
 
 - name: Restart NTP server
-  service:
+  ansible.builtin.service:
     name: ntpsec
     state: restarted
   when: ntp_pools | length > 0
diff --git a/roles/common/molecule/default/cleanup.yml b/roles/common/molecule/default/cleanup.yml
index c99ee79c29bc84b49f955fbcdf8734cda064bc64..32ba90b5c0f67eede47dee009ed76de8acd3ea27 100644
--- a/roles/common/molecule/default/cleanup.yml
+++ b/roles/common/molecule/default/cleanup.yml
@@ -7,7 +7,7 @@
   tasks:
 
     - name: Remove X.509 material
-      file:
+      ansible.builtin.file:
         path: "{{ item }}"
         state: absent
       with_items:
diff --git a/roles/common/molecule/default/converge.yml b/roles/common/molecule/default/converge.yml
index c5feb2ad46188500960bb93dc23157a0502b7d11..5e271d0326dff9ba63772d07bebb039506a33653 100644
--- a/roles/common/molecule/default/converge.yml
+++ b/roles/common/molecule/default/converge.yml
@@ -12,7 +12,7 @@
   tasks:
 
     - name: Set-up directories for testing pip requirements upgrade checks script
-      file:
+      ansible.builtin.file:
         path: "{{ item }}"
         state: directory
         owner: root
@@ -24,7 +24,7 @@
         - "/tmp/pip_check_requirements_upgrades/without_updates"
 
     - name: Deploy files for testing pip requirements upgrade checks script
-      copy:
+      ansible.builtin.copy:
         src: "{{ item }}"
         dest: "/tmp/{{ item }}"
         owner: root
@@ -38,12 +38,12 @@
         - "pip_check_requirements_upgrades/without_updates/requirements.txt"
 
     - name: Install web server for testing connectivity
-      apt:
+      ansible.builtin.apt:
         name: nginx
         state: present
 
     - name: Deploy firewall configuration file for the web server
-      copy:
+      ansible.builtin.copy:
         src: ferm_http.conf
         dest: /etc/ferm/conf.d/99-http.conf
         owner: root
@@ -55,6 +55,6 @@
   handlers:
 
     - name: Restart ferm
-      service:
+      ansible.builtin.service:
         name: ferm
         state: restarted
diff --git a/roles/common/molecule/default/prepare.yml b/roles/common/molecule/default/prepare.yml
index 58d895c7482b2afb250d8b8f398a2e85a4e579a6..266cf5c2e4d66351659808367726a05672cfcac0 100644
--- a/roles/common/molecule/default/prepare.yml
+++ b/roles/common/molecule/default/prepare.yml
@@ -7,13 +7,13 @@
   tasks:
 
     - name: Initialise CA hierarchy
-      command: "gimmecert init --ca-hierarchy-depth 2"
+      ansible.builtin.command: "gimmecert init --ca-hierarchy-depth 2"
       args:
         creates: ".gimmecert/ca/level1.cert.pem"
         chdir: "tests/data/"
 
     - name: Set-up link to generated X.509 material
-      file:
+      ansible.builtin.file:
         src: ".gimmecert"
         dest: "tests/data/x509"
         state: link
@@ -25,21 +25,21 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
 
     - name: Install net-tools for running Testinfra host.socket tests
-      apt:
+      ansible.builtin.apt:
         name: net-tools
         state: present
 
     - name: Remove the ss utility (see https://github.com/philpep/testinfra/pull/320)
-      file:
+      ansible.builtin.file:
         path: "/bin/ss"
         state: absent
 
@@ -49,7 +49,7 @@
   tasks:
 
     - name: Install apt-cacher-ng
-      apt:
+      ansible.builtin.apt:
         name: apt-cacher-ng
         state: present
 
@@ -59,12 +59,12 @@
   tasks:
 
     - name: Install tool for testing TCP connectivity
-      apt:
+      ansible.builtin.apt:
         name: nmap
         state: present
 
     - name: Set-up /etc/hosts with entries for all servers
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/hosts
         regexp: "^{{ item.key }}"
         line: "{{ item.key }} {{ item.value }}"
@@ -84,7 +84,7 @@
   tasks:
 
     - name: Set-up /etc/hosts with entries for all servers
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/hosts
         regexp: "^{{ item.key }}"
         line: "{{ item.key }} {{ item.value }}"
@@ -97,7 +97,7 @@
         192.168.56.4: client2
 
     - name: Load legacy iptables to test their removal
-      modprobe:
+      community.general.modprobe:
         name: "{{ item }}"
         state: present
       with_items:
@@ -115,7 +115,7 @@
     - name: Create some custom legacy iptables chains for testing their removal (max chain name length is 29)  # noqa no-changed-when
       # [no-changed-when] Commands should not change things if nothing needs doing
       #   Does not matter in test prepare stage.
-      command: "iptables-legacy -t '{{ item }}' -N '{{ (ansible_date_time.iso8601_micro | to_uuid)[:28] }}'"
+      ansible.builtin.command: "iptables-legacy -t '{{ item }}' -N '{{ (ansible_date_time.iso8601_micro | to_uuid)[:28] }}'"
       with_items:
         - filter
         - nat
@@ -126,7 +126,7 @@
     - name: Create some custom legacy ip6tables chains for testing their removal (max chain name length is 29)  # noqa no-changed-when
       # [no-changed-when] Commands should not change things if nothing needs doing
       #   Does not matter in test prepare stage.
-      command: "ip6tables-legacy -t '{{ item }}' -N '{{ (ansible_date_time.iso8601_micro | to_uuid)[:28] }}'"
+      ansible.builtin.command: "ip6tables-legacy -t '{{ item }}' -N '{{ (ansible_date_time.iso8601_micro | to_uuid)[:28] }}'"
       with_items:
         - filter
         - nat
@@ -135,7 +135,7 @@
         - raw
 
     - name: Create deprecated directory for storing requirements files created using Python 3 (pip requirements upgrade checks)
-      file:
+      ansible.builtin.file:
         path: "/etc/pip_check_requirements_upgrades-py3"
         state: directory
         owner: root
@@ -143,7 +143,7 @@
         mode: "0750"
 
     - name: Create deprecated directory for Python 3 virtual environment (pip requirements upgrade checks)
-      file:
+      ansible.builtin.file:
         path: "/var/lib/pipreqcheck/virtualenv-py3/"
         state: directory
         owner: root
@@ -151,7 +151,7 @@
         mode: "0750"
 
     - name: Create deprecated cronjob file for Python 3 (pip requirements upgrade checks)
-      file:
+      ansible.builtin.file:
         path: "/etc/cron.d/check_pip_requirements-py3"
         state: touch
         owner: root
@@ -159,7 +159,7 @@
         mode: "0644"
 
     - name: Install the deprecated/obsolete NTP-related packages
-      apt:
+      ansible.builtin.apt:
         name:
           - ntp
           - ntpdate
diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml
index a00536bfd5690bab774f1e4e8058e0d18a3a478c..d46c144af2bf070bfba9447ce9f6708863cdc171 100644
--- a/roles/common/tasks/main.yml
+++ b/roles/common/tasks/main.yml
@@ -4,7 +4,7 @@
 # ===========
 
 - name: Drop deprecated directories and files
-  file:
+  ansible.builtin.file:
     path: "{{ item }}"
     state: absent
   with_items:
@@ -13,7 +13,7 @@
     - "/etc/cron.d/check_pip_requirements-py3"
 
 - name: Drop deprecated packages
-  apt:
+  ansible.builtin.apt:
     name:
       - ntp
       - ntpdate
@@ -24,7 +24,7 @@
 # ===================
 
 - name: Enable use of proxy for retrieving system packages via apt
-  template:
+  ansible.builtin.template:
     src: "apt_proxy.j2"
     dest: "/etc/apt/apt.conf.d/00proxy"
     owner: root
@@ -33,13 +33,13 @@
   when: apt_proxy is defined
 
 - name: Disable use of proxy for retrieving system packages via apt
-  file:
+  ansible.builtin.file:
     path: "/etc/apt/apt.conf.d/00proxy"
     state: absent
   when: apt_proxy is undefined
 
 - name: Deploy pam-auth-update configuration file for enabling pam_umask
-  copy:
+  ansible.builtin.copy:
     src: "pam_umask"
     dest: "/usr/share/pam-configs/umask"
     owner: root
@@ -55,12 +55,12 @@
   #   subsequent playbook runs, make sure the PAM configuration is
   #   updated immediatelly. This way any files created by commands etc
   #   should end-up with correct permissions straight away.
-  command: "/usr/sbin/pam-auth-update --package"
+  ansible.builtin.command: "/usr/sbin/pam-auth-update --package"
   when: pam_umask.changed
   changed_when: true  # Always results in change due to task logic.
 
 - name: Set login UMASK
-  lineinfile:
+  ansible.builtin.lineinfile:
     dest: "/etc/login.defs"
     state: present
     backrefs: true
@@ -68,7 +68,7 @@
     line: 'UMASK\g<1>027'
 
 - name: Set home directory mask
-  lineinfile:
+  ansible.builtin.lineinfile:
     dest: "/etc/adduser.conf"
     state: present
     backrefs: true
@@ -76,7 +76,7 @@
     line: 'DIR_MODE=0750'
 
 - name: Deploy bash profile configuration for fancier prompts
-  template:
+  ansible.builtin.template:
     src: "bash_prompt.sh.j2"
     dest: "/etc/profile.d/bash_prompt.sh"
     owner: root
@@ -84,7 +84,7 @@
     mode: "0644"
 
 - name: Deploy profile configuration that allows for user-specific profile.d files
-  copy:
+  ansible.builtin.copy:
     src: "user_profile_d.sh"
     dest: "/etc/profile.d/z99-user_profile_d.sh"
     owner: root
@@ -92,7 +92,7 @@
     mode: "0644"
 
 - name: Replace default and skeleton bashrc
-  copy:
+  ansible.builtin.copy:
     src: "{{ item.key }}"
     dest: "{{ item.value }}"
     owner: root
@@ -103,12 +103,12 @@
     skel_bashrc: "/etc/skel/.bashrc"
 
 - name: Calculate stock checksum for bashrc root account
-  stat:
+  ansible.builtin.stat:
     path: "/root/.bashrc"
   register: root_bashrc_stat
 
 - name: Replace stock bashrc for root account with skeleton one
-  copy:
+  ansible.builtin.copy:
     src: "skel_bashrc"
     dest: "/root/.bashrc"
     owner: root
@@ -119,22 +119,22 @@
     root_bashrc_stat.stat.checksum == "1a422a148ad225aa5ba33f8dafd2b7cfcdbd701f"
 
 - name: Install sudo
-  apt:
+  ansible.builtin.apt:
     name: sudo
     state: present
 
 - name: Install ssl-cert package
-  apt:
+  ansible.builtin.apt:
     name: ssl-cert
     state: present
 
 - name: Install common packages
-  apt:
+  ansible.builtin.apt:
     name: "{{ common_packages }}"
     state: "present"
 
 - name: Disable electric-indent-mode for Emacs by default for all users
-  copy:
+  ansible.builtin.copy:
     src: "01disable-electric-indent-mode.el"
     dest: "/etc/emacs/site-start.d/01disable-electric-indent-mode.el"
     owner: root
@@ -143,34 +143,34 @@
   when: "['emacs24', 'emacs24-nox', 'emacs25', 'emacs25-nox', 'emacs', 'emacs-nox'] | intersect(common_packages) | length > 0"
 
 - name: Set-up operating system groups
-  group:
+  ansible.builtin.group:
     name: "{{ item.name }}"
     gid: "{{ item.gid | default(omit) }}"
     state: present
   with_items: "{{ os_groups }}"
 
 - name: Set-up operating system user groups
-  group:
+  ansible.builtin.group:
     name: "{{ item.name }}"
     gid: "{{ item.uid | default(omit) }}"
     state: present
   with_items: "{{ os_users }}"
 
 - name: Set-up operating system users
-  user:
+  ansible.builtin.user:
     name: "{{ item.name }}"
     uid: "{{ item.uid | default(omit) }}"
     group: "{{ item.name }}"
     groups: "{{ ','.join(item.additional_groups | default([])) }}"
     append: true
-    shell: /bin/bash
+    ansible.builtin.shell: /bin/bash
     state: present
     password: "{{ item.password | default('!') }}"
     update_password: on_create
   with_items: "{{ os_users }}"
 
 - name: Set-up authorised keys
-  authorized_key:
+  ansible.posix.authorized_key:
     user: "{{ item.0.name }}"
     key: "{{ item.1 }}"
   with_subelements:
@@ -178,7 +178,7 @@
     - authorized_keys
 
 - name: Disable remote logins for root
-  lineinfile:
+  ansible.builtin.lineinfile:
     dest: "/etc/ssh/sshd_config"
     state: present
     regexp: "^PermitRootLogin"
@@ -187,7 +187,7 @@
     - Restart SSH
 
 - name: Disable remote login authentication via password
-  lineinfile:
+  ansible.builtin.lineinfile:
     dest: "/etc/ssh/sshd_config"
     state: present
     regexp: "^PasswordAuthentication"
@@ -196,7 +196,7 @@
     - Restart SSH
 
 - name: Deploy CA certificates
-  copy:
+  ansible.builtin.copy:
     content: "{{ item.value }}"
     dest: "/usr/local/share/ca-certificates/{{ item.key }}.crt"
     owner: root
@@ -210,12 +210,12 @@
   #   CA certificate cache must be updated immediatelly in order for
   #   applications depending on deployed CA certificates can use them to
   #   validate server/client certificates.
-  command: "/usr/sbin/update-ca-certificates --fresh"
+  ansible.builtin.command: "/usr/sbin/update-ca-certificates --fresh"
   when: deploy_ca_certificates_result.changed
   changed_when: true  # Always results in change due to task logic.
 
 - name: Set-up file diversions for custom files that overrride package-provided ones
-  command: "dpkg-divert --divert '{{ item }}.original' --rename '{{ item }}'"
+  ansible.builtin.command: "dpkg-divert --divert '{{ item }}.original' --rename '{{ item }}'"
   register: "dpkg_divert"
   changed_when: "'Adding' in dpkg_divert.stdout"
   with_items:
@@ -224,7 +224,7 @@
     - Restart ferm
 
 - name: Deploy the patched ferm binary that disables use of legacy iptables
-  copy:
+  ansible.builtin.copy:
     src: ferm_binary
     dest: /usr/sbin/ferm
     owner: root
@@ -234,12 +234,12 @@
     - Restart ferm
 
 - name: Install ferm (for firewall management)
-  apt:
+  ansible.builtin.apt:
     name: ferm
     state: present
 
 - name: Configure ferm init script coniguration file
-  copy:
+  ansible.builtin.copy:
     src: "ferm_default"
     dest: "/etc/default/ferm"
     owner: root
@@ -249,7 +249,7 @@
     - Restart ferm
 
 - name: Create directory for storing ferm configuration files
-  file:
+  ansible.builtin.file:
     dest: "/etc/ferm/conf.d/"
     state: directory
     owner: root
@@ -257,7 +257,7 @@
     mode: "0750"
 
 - name: Deploy main ferm configuration file
-  copy:
+  ansible.builtin.copy:
     src: "ferm.conf"
     dest: "/etc/ferm/ferm.conf"
     owner: root
@@ -267,13 +267,13 @@
     - Restart ferm
 
 - name: Verify maintenance_allowed_sources parameter
-  fail:
+  ansible.builtin.fail:
     msg: "Items in maintenance_allowed_sources must IPv4/IPv6 addresses or subnets: {{ item }}"
   when: "not (item is ansible.utils.ipv4_address or item is ansible.utils.ipv6_address)"
   with_items: "{{ maintenance_allowed_sources }}"
 
 - name: Deploy ferm base rules
-  template:
+  ansible.builtin.template:
     src: "00-base.conf.j2"
     dest: "/etc/ferm/conf.d/00-base.conf"
     owner: root
@@ -283,13 +283,13 @@
     - Restart ferm
 
 - name: Enable and start ferm
-  service:
+  ansible.builtin.service:
     name: ferm
     state: started
     enabled: true
 
 - name: Deploy script for flushing legacy iptables rules
-  copy:
+  ansible.builtin.copy:
     src: "legacy_iptables_rules.sh"
     dest: "/usr/local/sbin/drop_legacy_iptables_rules.sh"
     owner: root
@@ -297,14 +297,14 @@
     mode: "0755"
 
 - name: Drop legacy iptables rules
-  command: "/usr/local/sbin/drop_legacy_iptables_rules.sh remove"
+  ansible.builtin.command: "/usr/local/sbin/drop_legacy_iptables_rules.sh remove"
   register: legacy_iptables_rules
   changed_when: "'Removed legacy iptables for families' in legacy_iptables_rules.stdout"
   notify:
     - Restart ferm
 
 - name: Deploy script for validating server certificates
-  copy:
+  ansible.builtin.copy:
     src: "check_certificate.sh"
     dest: "/usr/local/bin/check_certificate.sh"
     owner: root
@@ -312,7 +312,7 @@
     mode: "0755"
 
 - name: Set-up directory for holding configuration for certificate validation script
-  file:
+  ansible.builtin.file:
     path: "/etc/check_certificate"
     state: "directory"
     owner: root
@@ -320,7 +320,7 @@
     mode: "0755"
 
 - name: Deploy crontab entry for checking certificates
-  cron:
+  ansible.builtin.cron:
     name: "check_certificate"
     cron_file: "check_certificate"
     hour: "0"
@@ -330,31 +330,31 @@
     user: nobody
 
 - name: Install apticron (for checking available upgrades)
-  apt:
+  ansible.builtin.apt:
     name: apticron
     state: present
 
 # It would be too much hassle to detect changed state, so just ignore it.
 - name: Preventively run apticron to avoid issues with locking
-  command: /usr/sbin/apticron --cron
+  ansible.builtin.command: /usr/sbin/apticron --cron
   changed_when: false
 
 # Implementation for checking pip requirements files via via pip-tools.
 - name: Install packages required for running pip requirements checks
-  apt:
+  ansible.builtin.apt:
     name:
       - python3-setuptools
       - virtualenv
     state: present
 
 - name: Create dedicated group for user running pip requirements checks
-  group:
+  ansible.builtin.group:
     name: "pipreqcheck"
     gid: "{{ pipreqcheck_gid | default(omit) }}"
     state: present
 
 - name: Create user for running pip requirements checks
-  user:
+  ansible.builtin.user:
     name: "pipreqcheck"
     uid: "{{ pipreqcheck_uid | default(omit) }}"
     group: "pipreqcheck"
@@ -362,7 +362,7 @@
     state: present
 
 - name: Retrieve system Python interpreter version
-  command:
+  ansible.builtin.command:
     argv:
       - "/usr/bin/python3"
       - "-c"
@@ -371,7 +371,7 @@
   register: python_interpreter_version
 
 - name: Retrieve virtual environment Python interpreter version (if initialised)
-  command:
+  ansible.builtin.command:
     argv:
       - "/var/lib/pipreqcheck/virtualenv/bin/python"
       - "-c"
@@ -384,7 +384,7 @@
   register: virtualenv_python_version
 
 - name: Retrieve virtual environment prompt
-  command:
+  ansible.builtin.command:
     argv:
       - "bash"
       - "-c"
@@ -396,7 +396,7 @@
   register: current_virtualenv_prompt
 
 - name: Remove virtual environment in case of mismatches
-  file:
+  ansible.builtin.file:
     path: "/var/lib/pipreqcheck/virtualenv"
     state: absent
   when: |
@@ -405,7 +405,7 @@
     current_virtualenv_prompt.stdout != "(pipreqcheck) "
 
 - name: Create directory for Python virtual environment used for installing/running pip-tools
-  file:
+  ansible.builtin.file:
     path: "{{ item }}"
     state: directory
     owner: pipreqcheck
@@ -416,7 +416,7 @@
     - "/var/lib/pipreqcheck/virtualenv"
 
 - name: Create Python virtual environment used for installing/running pip-tools
-  command: "/usr/bin/virtualenv --python '{{ item.python_path }}' --prompt '{{ item.virtualenv_prompt }}' '{{ item.virtualenv_path }}'"
+  ansible.builtin.command: "/usr/bin/virtualenv --python '{{ item.python_path }}' --prompt '{{ item.virtualenv_prompt }}' '{{ item.virtualenv_path }}'"
   args:
     creates: "{{ item.creates }}"
   become: true
@@ -429,7 +429,7 @@
       creates: "/var/lib/pipreqcheck/virtualenv/bin/python3"
 
 - name: Create directory for storing pip requirements files
-  file:
+  ansible.builtin.file:
     path: "{{ item }}"
     state: "directory"
     owner: root
@@ -439,7 +439,7 @@
     - "/etc/pip_check_requirements_upgrades"
 
 - name: Set-up directory for storing pip requirements file for pip-tools virtual environment itself
-  file:
+  ansible.builtin.file:
     path: "{{ item }}"
     state: "directory"
     owner: root
@@ -449,7 +449,7 @@
     - "/etc/pip_check_requirements_upgrades/pipreqcheck"
 
 - name: Deploy .in file for pip requirements in pip-tools virtual environment
-  template:
+  ansible.builtin.template:
     src: "pipreqcheck_requirements.in.j2"
     dest: "{{ item.path }}"
     owner: root
@@ -460,7 +460,7 @@
       requirements: "{{ pip_check_requirements_in }}"
 
 - name: Deploy requirements file for pipreqcheck virtual environment
-  template:
+  ansible.builtin.template:
     src: "pipreqcheck_requirements.txt.j2"
     dest: "{{ item.file }}"
     owner: root
@@ -471,7 +471,7 @@
       requirements: "{{ pip_check_requirements }}"
 
 - name: Install requirements in the pipreqcheck virtual environment
-  pip:
+  ansible.builtin.pip:
     requirements: "{{ item.requirements }}"
     virtualenv: "{{ item.virtualenv }}"
   become: true
@@ -481,7 +481,7 @@
       requirements: "/etc/pip_check_requirements_upgrades/pipreqcheck/requirements.txt"
 
 - name: Synchronise pip-tools virtual environment via deployed requirements file
-  shell: "source ~pipreqcheck/virtualenv/bin/activate && pip-sync /etc/pip_check_requirements_upgrades/pipreqcheck/requirements.txt"
+  ansible.builtin.shell: "source ~pipreqcheck/virtualenv/bin/activate && pip-sync /etc/pip_check_requirements_upgrades/pipreqcheck/requirements.txt"
   args:
     executable: /bin/bash
   become: true
@@ -490,7 +490,7 @@
   changed_when: "pipreqcheck_pip_sync.stdout != 'Everything up-to-date'"
 
 - name: Deploy script for checking available upgrades
-  copy:
+  ansible.builtin.copy:
     src: "pip_check_requirements_upgrades.sh"
     dest: "/usr/local/bin/pip_check_requirements_upgrades.sh"
     owner: root
@@ -498,7 +498,7 @@
     mode: "0755"
 
 - name: Deploy crontab entry for checking pip requirements
-  copy:
+  ansible.builtin.copy:
     src: "cron_check_pip_requirements"
     dest: "/etc/cron.d/check_pip_requirements"
     owner: root
@@ -506,7 +506,7 @@
     mode: "0644"
 
 - name: Install NTP packages
-  apt:
+  ansible.builtin.apt:
     name:
       - ntpsec
       - ntpsec-ntpdate
@@ -514,7 +514,7 @@
   when: ntp_pools | length > 0
 
 - name: Remove NTP packages
-  apt:
+  ansible.builtin.apt:
     name:
       - ntpsec
       - ntpsec-ntpdate
@@ -523,7 +523,7 @@
   when: ntp_pools | length == 0
 
 - name: Deploy NTP configuration
-  template:
+  ansible.builtin.template:
     src: "ntp.conf.j2"
     dest: "/etc/ntpsec/ntp.conf"
     owner: root
@@ -534,7 +534,7 @@
     - Restart NTP server
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/database/handlers/main.yml b/roles/database/handlers/main.yml
index 8dae2fd6fcd7ea5173f2e61f1ea32b955134ba09..64ed8c7d39295a6b5016864971d59d5a1bfc1728 100644
--- a/roles/database/handlers/main.yml
+++ b/roles/database/handlers/main.yml
@@ -1,5 +1,5 @@
 ---
 
 - name: Dummy handler to suppress Ansible warnings
-  debug:
+  ansible.builtin.debug:
     msg: "This is just a dummy task to suppress the Ansible warning about an empty include."
diff --git a/roles/database/molecule/default/prepare.yml b/roles/database/molecule/default/prepare.yml
index b89a35b8ff052860e49c4e0d1048cdaae3d271bd..3a369193a203c05e6f57462d37f7e1d07254da99 100644
--- a/roles/database/molecule/default/prepare.yml
+++ b/roles/database/molecule/default/prepare.yml
@@ -7,11 +7,11 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
 
diff --git a/roles/database/tasks/backup.yml b/roles/database/tasks/backup.yml
index 72656fc8481d9f9d0b3a05ca31da4204d094a1ff..0b992ff438cb8c2c6d306a73b3b535adaebc0b3c 100644
--- a/roles/database/tasks/backup.yml
+++ b/roles/database/tasks/backup.yml
@@ -1,7 +1,7 @@
 ---
 
 - name: Create directory for storing MariaDB database dumps
-  file:
+  ansible.builtin.file:
     path: "{{ item }}"
     state: directory
     owner: root
@@ -12,7 +12,7 @@
     - "/srv/backup/mariadb"
 
 - name: Deploy script for creating database backup dumps
-  template:
+  ansible.builtin.template:
     src: "dump_db.sh.j2"
     dest: "/etc/duply/main/pre.d/dump_{{ db_name }}.sh"
     owner: root
diff --git a/roles/database/tasks/main.yml b/roles/database/tasks/main.yml
index 2cb7e24ba94588490e8e740ed2b1fac4aa9df7a4..228bed06ce65ebb30fbb89950a55bffe4973aa76 100644
--- a/roles/database/tasks/main.yml
+++ b/roles/database/tasks/main.yml
@@ -1,13 +1,13 @@
 ---
 
 - name: "Create database {{ db_name }}"
-  mysql_db:
+  community.mysql.mysql_db:
     name: "{{ db_name }}"
     state: present
     login_unix_socket: "/var/run/mysqld/mysqld.sock"
 
 - name: "Create database user {{ db_name }}"
-  mysql_user:
+  community.mysql.mysql_user:
     name: "{{ db_name }}"
     password: "{{ db_password }}"
     priv: "{{ db_name }}.*:ALL"
@@ -15,11 +15,11 @@
     login_unix_socket: "/var/run/mysqld/mysqld.sock"
 
 - name: Enable backup
-  include_tasks: backup.yml
+  ansible.builtin.include_tasks: backup.yml
   when: enable_backup
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/database_server/handlers/main.yml b/roles/database_server/handlers/main.yml
index 2908002246efdd1f81a2b1d4e54f531918d4bba4..b9de094e6ee889b0bdd825c68a1ceaa9325dde7d 100644
--- a/roles/database_server/handlers/main.yml
+++ b/roles/database_server/handlers/main.yml
@@ -1,6 +1,6 @@
 ---
 
 - name: Restart MariaDB
-  service:
+  ansible.builtin.service:
     name: mysql
     state: restarted
diff --git a/roles/database_server/molecule/default/prepare.yml b/roles/database_server/molecule/default/prepare.yml
index eefd77c3d02929d5fe3bed6cc81072fdb26e7060..ad4260a270d56a9bbe635a177383b7e91432684d 100644
--- a/roles/database_server/molecule/default/prepare.yml
+++ b/roles/database_server/molecule/default/prepare.yml
@@ -7,10 +7,10 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
diff --git a/roles/database_server/tasks/main.yml b/roles/database_server/tasks/main.yml
index d8d2d090760c255608a2012d4d35ec682ce17d98..7ea641346446fe5953ee863e08b7d26fc2a9b0af 100644
--- a/roles/database_server/tasks/main.yml
+++ b/roles/database_server/tasks/main.yml
@@ -1,7 +1,7 @@
 ---
 
 - name: Install MariaDB
-  apt:
+  ansible.builtin.apt:
     name:
       - mariadb-client
       - mariadb-server
@@ -9,13 +9,13 @@
     state: present
 
 - name: Enable and start MariaDB
-  service:
+  ansible.builtin.service:
     name: mysql
     state: started
     enabled: true
 
 - name: Set UTF-8 encoding as default for MariaDB
-  template:
+  ansible.builtin.template:
     src: "utf8.cnf.j2"
     dest: "/etc/mysql/mariadb.conf.d/90-utf8.cnf"
     owner: root
@@ -28,13 +28,13 @@
   #   UTF-8 configuration must be applied immediatelly in order to ensure that
   #   subsequent tasks that create databases will end-up with correct (UTF-8)
   #   encoding. Otherwise they will be created using default latin1.
-  service:
+  ansible.builtin.service:
     name: mysql
     state: restarted
   when: mariadb_utf8_configuration.changed
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/ldap_client/handlers/main.yml b/roles/ldap_client/handlers/main.yml
index 8dae2fd6fcd7ea5173f2e61f1ea32b955134ba09..64ed8c7d39295a6b5016864971d59d5a1bfc1728 100644
--- a/roles/ldap_client/handlers/main.yml
+++ b/roles/ldap_client/handlers/main.yml
@@ -1,5 +1,5 @@
 ---
 
 - name: Dummy handler to suppress Ansible warnings
-  debug:
+  ansible.builtin.debug:
     msg: "This is just a dummy task to suppress the Ansible warning about an empty include."
diff --git a/roles/ldap_client/molecule/default/prepare.yml b/roles/ldap_client/molecule/default/prepare.yml
index eefd77c3d02929d5fe3bed6cc81072fdb26e7060..ad4260a270d56a9bbe635a177383b7e91432684d 100644
--- a/roles/ldap_client/molecule/default/prepare.yml
+++ b/roles/ldap_client/molecule/default/prepare.yml
@@ -7,10 +7,10 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
diff --git a/roles/ldap_client/tasks/main.yml b/roles/ldap_client/tasks/main.yml
index c73295d26dc2d36ddaef2e8f0a32a47fce381985..6462a251c1d6fea559a96ed42d2eefef0c1d3eab 100644
--- a/roles/ldap_client/tasks/main.yml
+++ b/roles/ldap_client/tasks/main.yml
@@ -1,12 +1,12 @@
 ---
 
 - name: Install OpenLDAP client tools
-  apt:
+  ansible.builtin.apt:
     name: ldap-utils
     state: present
 
 - name: Set-up LDAP client configuration directory
-  file:
+  ansible.builtin.file:
     path: /etc/ldap/
     state: directory
     owner: root
@@ -14,7 +14,7 @@
     mode: "0755"
 
 - name: Deploy LDAP client configuration file
-  template:
+  ansible.builtin.template:
     src: ldap.conf.j2
     dest: /etc/ldap/ldap.conf
     owner: root
@@ -22,7 +22,7 @@
     mode: "0644"
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/ldap_server/handlers/main.yml b/roles/ldap_server/handlers/main.yml
index b7ad66e94652650fec8be772b56b40d1527dd357..1a40a67728a03a8ba631a7b264a7e1990a0432a9 100644
--- a/roles/ldap_server/handlers/main.yml
+++ b/roles/ldap_server/handlers/main.yml
@@ -1,6 +1,6 @@
 ---
 
 - name: Restart slapd
-  service:
+  ansible.builtin.service:
     name: slapd
     state: restarted
diff --git a/roles/ldap_server/molecule/default/cleanup.yml b/roles/ldap_server/molecule/default/cleanup.yml
index c99ee79c29bc84b49f955fbcdf8734cda064bc64..32ba90b5c0f67eede47dee009ed76de8acd3ea27 100644
--- a/roles/ldap_server/molecule/default/cleanup.yml
+++ b/roles/ldap_server/molecule/default/cleanup.yml
@@ -7,7 +7,7 @@
   tasks:
 
     - name: Remove X.509 material
-      file:
+      ansible.builtin.file:
         path: "{{ item }}"
         state: absent
       with_items:
diff --git a/roles/ldap_server/molecule/default/prepare.yml b/roles/ldap_server/molecule/default/prepare.yml
index a55be1d1c533968da81c2bc5f5c2c8460b825d5d..b1642b31658ef77bcd2317a4415ac6aa5429eb43 100644
--- a/roles/ldap_server/molecule/default/prepare.yml
+++ b/roles/ldap_server/molecule/default/prepare.yml
@@ -7,13 +7,13 @@
   tasks:
 
     - name: Initialise CA hierarchy
-      command: "gimmecert init"
+      ansible.builtin.command: "gimmecert init"
       args:
         creates: ".gimmecert/ca/level1.cert.pem"
         chdir: "tests/data/"
 
     - name: Generate server private keys and certificates
-      command:
+      ansible.builtin.command:
       args:
         chdir: "tests/data/"
         creates: ".gimmecert/server/{{ item.name }}.cert.pem"
@@ -29,7 +29,7 @@
           fqdn: parameters-optional
 
     - name: Set-up link to generated X.509 material
-      file:
+      ansible.builtin.file:
         src: ".gimmecert"
         dest: "tests/data/x509"
         state: link
@@ -41,16 +41,16 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
 
     - name: Deploy CA certificate
-      copy:
+      ansible.builtin.copy:
         src: tests/data/x509/ca/level1.cert.pem
         dest: /etc/ssl/certs/testca.cert.pem
         owner: root
@@ -58,12 +58,12 @@
         mode: "0644"
 
     - name: Remove the ss utility (see https://github.com/philpep/testinfra/pull/320)
-      file:
+      ansible.builtin.file:
         path: "/bin/ss"
         state: absent
 
     - name: Install tools for testing
-      apt:
+      ansible.builtin.apt:
         name:
           - net-tools
           - nmap
@@ -76,12 +76,12 @@
   tasks:
 
     - name: Install tool for teting TCP connectivity
-      apt:
+      ansible.builtin.apt:
         name: hping3
         state: present
 
     - name: Set-up /etc/hosts with entries for all servers
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/hosts
         regexp: "^{{ item.key }}"
         line: "{{ item.key }} {{ item.value }}"
@@ -99,7 +99,7 @@
   tasks:
 
     - name: Set-up the hosts file
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/hosts
         regexp: "^{{ item.key }}"
         line: "{{ item.key }} {{ item.value }}"
@@ -116,7 +116,7 @@
   tasks:
 
     - name: Set-up the hosts file
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/hosts
         regexp: "^{{ item.key }}"
         line: "{{ item.key }} {{ item.value }}"
diff --git a/roles/ldap_server/tasks/backup.yml b/roles/ldap_server/tasks/backup.yml
index 14aff20fee7c1baada76ab88b316ff630aa114c3..6ffbaab230bd545f80e21711ee0ec981439e2584 100644
--- a/roles/ldap_server/tasks/backup.yml
+++ b/roles/ldap_server/tasks/backup.yml
@@ -1,7 +1,7 @@
 ---
 
 - name: Create directory for storing LDAP database dumps
-  file:
+  ansible.builtin.file:
     path: "{{ item }}"
     state: directory
     owner: root
@@ -11,7 +11,7 @@
     - "/srv/backup"
 
 - name: Deploy script for creating LDAP database backup dumps
-  copy:
+  ansible.builtin.copy:
     src: "ldapdump.sh"
     dest: "/etc/duply/main/pre.d/ldapdump.sh"
     owner: root
diff --git a/roles/ldap_server/tasks/main.yml b/roles/ldap_server/tasks/main.yml
index 37d4d516a65970125bcfdd0f569b20a122754e03..e3d64f87b2974cdf6afaf1dd2cc629537f740945 100644
--- a/roles/ldap_server/tasks/main.yml
+++ b/roles/ldap_server/tasks/main.yml
@@ -1,26 +1,26 @@
 ---
 
 - name: Set domain for slapd
-  debconf:
+  ansible.builtin.debconf:
     name: slapd
     question: slapd/domain
     vtype: string
     value: "{{ ldap_server_domain }}"
 
 - name: Set organisation for slapd
-  debconf:
+  ansible.builtin.debconf:
     name: slapd
     question: shared/organization
     vtype: string
     value: "{{ ldap_server_organization }}"
 
 - name: Install slapd
-  apt:
+  ansible.builtin.apt:
     name: slapd
     state: present
 
 - name: Allow OpenLDAP user to traverse the directory with TLS private keys
-  user:
+  ansible.builtin.user:
     name: openldap
     append: true
     groups: ssl-cert
@@ -31,18 +31,18 @@
   #   In order to be able to change LDAP server TLS configuration, it must be
   #   able to read both the private key and certificate. Therefore we need to
   #   immediatelly restart (since configuration is done live on the server.
-  service:
+  ansible.builtin.service:
     name: slapd
     state: restarted
   when: openldap_in_ssl_cert.changed
 
 - name: Install Python LDAP bindings
-  apt:
+  ansible.builtin.apt:
     name: python3-pyldap
     state: present
 
 - name: Set-up LDAP server to listen on legacy SSL port
-  lineinfile:
+  ansible.builtin.lineinfile:
     dest: /etc/default/slapd
     state: present
     backrefs: true
@@ -52,7 +52,7 @@
     - Restart slapd
 
 - name: Enable and start slapd service
-  service:
+  ansible.builtin.service:
     name: slapd
     state: started
     enabled: true
@@ -65,12 +65,12 @@
     values: "{{ ldap_server_log_level }}"
 
 - name: Test if LDAP misc schema has been applied
-  command: "ldapsearch -H ldapi:/// -Q -LLL -A -Y EXTERNAL -b cn=schema,cn=config -s one '(cn={*}misc)' cn"
+  ansible.builtin.command: "ldapsearch -H ldapi:/// -Q -LLL -A -Y EXTERNAL -b cn=schema,cn=config -s one '(cn={*}misc)' cn"
   register: ldap_misc_schema_present
   changed_when: false
 
 - name: Deploy LDAP misc schema
-  command: "ldapadd -H ldapi:/// -Q -Y EXTERNAL -f /etc/ldap/schema/misc.ldif"
+  ansible.builtin.command: "ldapadd -H ldapi:/// -Q -Y EXTERNAL -f /etc/ldap/schema/misc.ldif"
   when: not ldap_misc_schema_present.stdout
   changed_when: true  # Always results in change due to task logic.
 
@@ -79,7 +79,7 @@
 # against under Debian) picking a matching DH parameter from RFC-7919
 # (https://www.ietf.org/rfc/rfc7919.txt).
 - name: Generate the LDAP server Diffie-Hellman parameter
-  openssl_dhparam:
+  community.crypto.openssl_dhparam:
     owner: root
     group: openldap
     mode: "0640"
@@ -89,7 +89,7 @@
     - Restart slapd
 
 - name: Deploy LDAP TLS private key
-  template:
+  ansible.builtin.template:
     src: "ldap_tls_key.j2"
     dest: "/etc/ssl/private/{{ ansible_fqdn }}_ldap.key"
     mode: "0640"
@@ -99,7 +99,7 @@
     - Restart slapd
 
 - name: Deploy LDAP TLS certificate
-  template:
+  ansible.builtin.template:
     src: "ldap_tls_cert.j2"
     dest: "/etc/ssl/certs/{{ ansible_fqdn }}_ldap.pem"
     mode: "0644"
@@ -109,7 +109,7 @@
     - Restart slapd
 
 - name: Deploy configuration file for checking certificate validity via cron
-  copy:
+  ansible.builtin.copy:
     content: "/etc/ssl/certs/{{ ansible_fqdn }}_ldap.pem"
     dest: "/etc/check_certificate/{{ ansible_fqdn }}_ldap.conf"
     owner: root
@@ -193,7 +193,7 @@
     values: "{1}memberof"
 
 - name: Enable the memberof overlay for database
-  ldap_entry:
+  community.general.ldap_entry:
     dn: "olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config"
     objectClass:
       - olcConfig
@@ -211,12 +211,12 @@
     rules: "{{ ldap_permissions }}"
 
 - name: Drop the admin entry corresponding to olcRootDN for database from directory
-  ldap_entry:
+  community.general.ldap_entry:
     dn: "cn=admin,{{ ldap_server_int_basedn }}"
     state: absent
 
 - name: Create basic LDAP directory structure
-  ldap_entry:
+  community.general.ldap_entry:
     dn: "ou={{ item }},{{ ldap_server_int_basedn }}"
     objectClass:
       - organizationalUnit
@@ -228,7 +228,7 @@
     - services
 
 - name: Create the entry that will contain mail service information
-  ldap_entry:
+  community.general.ldap_entry:
     dn: "ou=mail,ou=services,{{ ldap_server_int_basedn }}"
     objectClass:
       - organizationalUnit
@@ -236,7 +236,7 @@
       ou: mail
 
 - name: Create LDAP directory structure for mail service
-  ldap_entry:
+  community.general.ldap_entry:
     dn: "ou={{ item }},ou=mail,ou=services,{{ ldap_server_int_basedn }}"
     objectClass:
       - organizationalUnit
@@ -247,7 +247,7 @@
     - aliases
 
 - name: Create or remove login entries for services
-  ldap_entry:
+  community.general.ldap_entry:
     dn: "cn={{ item.name }},ou=services,{{ ldap_server_int_basedn }}"
     objectClass:
       - applicationProcess
@@ -268,7 +268,7 @@
   when: "item.state | default('present') == 'present'"
 
 - name: Create or remove user-supplied groups
-  ldap_entry:
+  community.general.ldap_entry:
     dn: "cn={{ item.name }},ou=groups,{{ ldap_server_int_basedn }}"
     objectClass:
       - groupOfUniqueNames
@@ -279,7 +279,7 @@
   with_items: "{{ ldap_server_groups }}"
 
 - name: Create user-supplied LDAP entries
-  ldap_entry:
+  community.general.ldap_entry:
     dn: "{{ item.dn }}"
     objectClass: "{{ item.attributes.objectClass }}"
     attributes: "{{ item.attributes }}"
@@ -287,7 +287,7 @@
   with_items: "{{ ldap_entries }}"
 
 - name: Deploy firewall configuration for LDAP
-  copy:
+  ansible.builtin.copy:
     src: "ferm_ldap.conf"
     dest: "/etc/ferm/conf.d/10-ldap.conf"
     owner: root
@@ -300,7 +300,7 @@
 #        was in use (where community collection has the ldap_search
 #        module.
 - name: Deploy temporary file with LDAP admin password
-  template:
+  ansible.builtin.template:
     src: "ldap_admin_password.j2"
     dest: "/root/.ldap_admin_password"
     owner: root
@@ -309,7 +309,7 @@
   changed_when: false
 
 - name: Test if LDAP admin password needs to be changed
-  command: "ldapwhoami -H ldapi:/// -D 'cn=admin,{{ ldap_server_int_basedn }}' -x -y /root/.ldap_admin_password"
+  ansible.builtin.command: "ldapwhoami -H ldapi:/// -D 'cn=admin,{{ ldap_server_int_basedn }}' -x -y /root/.ldap_admin_password"
   register: ldap_admin_password_check
   changed_when: ldap_admin_password_check.rc != 0
   failed_when: false
@@ -323,17 +323,17 @@
   when: ldap_admin_password_check.rc != 0
 
 - name: Remove temporary file with LDAP admin password
-  file:
+  ansible.builtin.file:
     path: "/root/.ldap_admin_password"
     state: absent
   changed_when: false
 
 - name: Enable backup
-  include_tasks: backup.yml
+  ansible.builtin.include_tasks: backup.yml
   when: enable_backup
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/mail_forwarder/handlers/main.yml b/roles/mail_forwarder/handlers/main.yml
index 51e8cb8d2e30a7bde7d909f0671c6b0da741a342..50816fae35c6052a4fb379f7c7e9c49b79b990f1 100644
--- a/roles/mail_forwarder/handlers/main.yml
+++ b/roles/mail_forwarder/handlers/main.yml
@@ -5,9 +5,9 @@
   #   This task is invoked only if user is very specific about requiring to
   #   run the handlers manually as a way to bring the system to consistency
   #   after interrupted runs.
-  command: "/usr/bin/newaliases"
+  ansible.builtin.command: "/usr/bin/newaliases"
 
 - name: Restart Postfix
-  service:
+  ansible.builtin.service:
     name: postfix
     state: restarted
diff --git a/roles/mail_forwarder/molecule/default/cleanup.yml b/roles/mail_forwarder/molecule/default/cleanup.yml
index c99ee79c29bc84b49f955fbcdf8734cda064bc64..32ba90b5c0f67eede47dee009ed76de8acd3ea27 100644
--- a/roles/mail_forwarder/molecule/default/cleanup.yml
+++ b/roles/mail_forwarder/molecule/default/cleanup.yml
@@ -7,7 +7,7 @@
   tasks:
 
     - name: Remove X.509 material
-      file:
+      ansible.builtin.file:
         path: "{{ item }}"
         state: absent
       with_items:
diff --git a/roles/mail_forwarder/molecule/default/prepare.yml b/roles/mail_forwarder/molecule/default/prepare.yml
index 2e7623a9266bc0949b623eef17fb2d2b02e7f879..35ebdd99197ee391d5c280ab2a514fe80284301e 100644
--- a/roles/mail_forwarder/molecule/default/prepare.yml
+++ b/roles/mail_forwarder/molecule/default/prepare.yml
@@ -7,13 +7,13 @@
   tasks:
 
     - name: Initialise CA hierarchy
-      command: "gimmecert init"
+      ansible.builtin.command: "gimmecert init"
       args:
         creates: ".gimmecert/ca/level1.cert.pem"
         chdir: "tests/data/"
 
     - name: Generate server private keys and certificates
-      command:
+      ansible.builtin.command:
       args:
         chdir: "tests/data/"
         creates: ".gimmecert/server/{{ item.name }}.cert.pem"
@@ -27,7 +27,7 @@
           fqdn: mail-server
 
     - name: Set-up link to generated X.509 material
-      file:
+      ansible.builtin.file:
         src: ".gimmecert"
         dest: "tests/data/x509"
         state: link
@@ -39,16 +39,16 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
 
     - name: Set-up the hosts file
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/hosts
         regexp: "^{{ item.key }}"
         line: "{{ item.key }} {{ item.value }}"
@@ -64,7 +64,7 @@
         192.168.56.23: "parameters-no-incoming-bookworm"
 
     - name: Install tools for testing
-      apt:
+      ansible.builtin.apt:
         name: gnutls-bin
         state: present
 
@@ -74,17 +74,17 @@
   tasks:
 
     - name: Install SWAKS for testing SMTP capability
-      apt:
+      ansible.builtin.apt:
         name: swaks
         state: present
 
     - name: Install tool for testing TCP connectivity
-      apt:
+      ansible.builtin.apt:
         name: hping3
         state: present
 
     - name: Deploy CA certificate
-      copy:
+      ansible.builtin.copy:
         src: tests/data/x509/ca/level1.cert.pem
         dest: /usr/local/share/ca-certificates/testca.crt
         owner: root
@@ -98,7 +98,7 @@
     - name: Update CA certificate cache  # noqa no-changed-when
       # [no-changed-when] Commands should not change things if nothing needs doing
       #   Does not matter in test prepare stage.
-      command: /usr/sbin/update-ca-certificates --fresh
+      ansible.builtin.command: /usr/sbin/update-ca-certificates --fresh
 
 - name: Prepare, helpers
   hosts: mail-servers
@@ -106,7 +106,7 @@
   tasks:
 
     - name: Deploy CA certificate
-      copy:
+      ansible.builtin.copy:
         src: tests/data/x509/ca/level1.cert.pem
         dest: /usr/local/share/ca-certificates/testca.crt
         owner: root
@@ -116,7 +116,7 @@
         - Update CA certificate cache
 
     - name: Deploy SMTP private key and certificate
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/x509/server/{{ item }}"
         dest: "/etc/ssl/{{ item }}"
         owner: root
@@ -127,18 +127,18 @@
         - mail-server_smtp.key.pem
 
     - name: Install Postfix
-      apt:
+      ansible.builtin.apt:
         name: "postfix"
         state: present
 
     - name: Purge Exim configuration
-      apt:
+      ansible.builtin.apt:
         name: "exim4*"
         state: absent
         purge: true
 
     - name: Deploy Postfix configuration
-      copy:
+      ansible.builtin.copy:
         src: tests/data/main.cf
         dest: /etc/postfix/main.cf
         owner: root
@@ -148,17 +148,17 @@
         - Restart Postfix
 
     - name: Install tool for testing TCP connectivity
-      apt:
+      ansible.builtin.apt:
         name: hping3
         state: present
 
     - name: Install SWAKS for testing SMTP capability
-      apt:
+      ansible.builtin.apt:
         name: swaks
         state: present
 
     - name: Set-up port forwarding
-      command: "iptables -t nat -A PREROUTING -p tcp -m tcp --dport 27 -j REDIRECT --to-ports 25"
+      ansible.builtin.command: "iptables -t nat -A PREROUTING -p tcp -m tcp --dport 27 -j REDIRECT --to-ports 25"
       changed_when: false
 
   handlers:
@@ -166,10 +166,10 @@
     - name: Update CA certificate cache  # noqa no-changed-when
       # [no-changed-when] Commands should not change things if nothing needs doing
       #   Does not matter in test prepare stage.
-      command: /usr/sbin/update-ca-certificates --fresh
+      ansible.builtin.command: /usr/sbin/update-ca-certificates --fresh
 
     - name: Restart Postfix
-      service:
+      ansible.builtin.service:
         name: postfix
         state: restarted
 
@@ -179,10 +179,10 @@
   tasks:
 
     - name: Create additional group for testing local aliases
-      group:
+      ansible.builtin.group:
         name: testuser
 
     - name: Create additional user for testing local aliases
-      user:
+      ansible.builtin.user:
         name: testuser
         group: testuser
diff --git a/roles/mail_forwarder/tasks/main.yml b/roles/mail_forwarder/tasks/main.yml
index 247d66de50f442c34cb50c018feeeb7aa0c0569e..a58530e2e04815b1969d5c5b0190ef55602b1b37 100644
--- a/roles/mail_forwarder/tasks/main.yml
+++ b/roles/mail_forwarder/tasks/main.yml
@@ -1,23 +1,23 @@
 ---
 
 - name: Install Postfix
-  apt:
+  ansible.builtin.apt:
     name: postfix
     state: present
 
 - name: Install procmail
-  apt:
+  ansible.builtin.apt:
     name: procmail
     state: present
 
 - name: Purge Exim configuration
-  apt:
+  ansible.builtin.apt:
     name: "exim4*"
     state: absent
     purge: true
 
 - name: Deploy the SMTP relay TLS truststore
-  copy:
+  ansible.builtin.copy:
     content: "{{ smtp_relay_truststore }}"
     dest: "/etc/ssl/certs/smtp_relay_truststore.pem"
     owner: root
@@ -25,7 +25,7 @@
     mode: "0644"
 
 - name: Generate the SMTP server Diffie-Hellman parameter
-  openssl_dhparam:
+  community.crypto.openssl_dhparam:
     owner: root
     group: root
     mode: "0640"
@@ -35,7 +35,7 @@
     - Restart Postfix
 
 - name: Configure visible mail name of the system
-  copy:
+  ansible.builtin.copy:
     content: "{{ inventory_hostname }}"
     dest: "/etc/mailname"
     owner: root
@@ -45,7 +45,7 @@
     - Restart Postfix
 
 - name: Deploy Postfix main configuration
-  template:
+  ansible.builtin.template:
     src: "main.cf.j2"
     dest: "/etc/postfix/main.cf"
     owner: root
@@ -55,7 +55,7 @@
     - Restart Postfix
 
 - name: Set-up local mail aliases
-  lineinfile:
+  ansible.builtin.lineinfile:
     dest: "/etc/aliases"
     line: "{{ item.key }}: {{ item.value }}"
     regexp: "^{{ item.key }}"
@@ -65,13 +65,13 @@
     - Rebuild mail aliases
 
 - name: Enable and start postfix service
-  service:
+  ansible.builtin.service:
     name: postfix
     state: started
     enabled: true
 
 - name: Retrieve IPv4 addresses of SMTP relay host
-  shell: "getent ahostsv4 '{{ smtp_relay_host }}' | awk '{ print $1 }' | sort -u"  # noqa risky-shell-pipe
+  ansible.builtin.shell: "getent ahostsv4 '{{ smtp_relay_host }}' | awk '{ print $1 }' | sort -u"  # noqa risky-shell-pipe
   # [risky-shell-pipe] Shells that use pipes should set the pipefail option
   #   The getent ahostsv4 command has non-zero exit code if the
   #   supplies name cannot be resolved. However, that is a valid
@@ -82,7 +82,7 @@
   register: smtp_relay_host_ipv4
 
 - name: Retrieve IPv6 addresses of SMTP relay host
-  shell: "getent ahostsv6 '{{ smtp_relay_host }}' | awk '{ print $1 }' | grep -v '^::ffff:' | sort -u"  # noqa risky-shell-pipe
+  ansible.builtin.shell: "getent ahostsv6 '{{ smtp_relay_host }}' | awk '{ print $1 }' | grep -v '^::ffff:' | sort -u"  # noqa risky-shell-pipe
   # [risky-shell-pipe] Shells that use pipes should set the pipefail option
   #   The getent ahostsv6 command has non-zero exit code if the
   #   supplies name cannot be resolved. However, that is a valid
@@ -93,17 +93,17 @@
   register: smtp_relay_host_ipv6
 
 - name: Normalise the SMTP relay host IPv4 addresses variable
-  set_fact:
+  ansible.builtin.set_fact:
     smtp_relay_host_ipv4: "{{ smtp_relay_host_ipv4.stdout_lines | reject('equalto', '') | list }}"
   when: "smtp_relay_host | length != 0"
 
 - name: Normalise the SMTP relay host IPv6 addresses variable
-  set_fact:
+  ansible.builtin.set_fact:
     smtp_relay_host_ipv6: "{{ smtp_relay_host_ipv6.stdout_lines | reject('equalto', '') | list }}"
   when: "smtp_relay_host | length != 0"
 
 - name: Deploy firewall configuration for mail forwader
-  template:
+  ansible.builtin.template:
     src: "ferm_mail.conf.j2"
     dest: "/etc/ferm/conf.d/20-mail.conf"
     owner: root
@@ -113,12 +113,12 @@
     - Restart ferm
 
 - name: Install SWAKS
-  apt:
+  ansible.builtin.apt:
     name: swaks
     state: present
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/mail_server/handlers/main.yml b/roles/mail_server/handlers/main.yml
index 3a8553c1819916d9531bdd83a580bf79b2f7ce16..6bb6f5bd1903583433ed1c06320992f9f7253242 100644
--- a/roles/mail_server/handlers/main.yml
+++ b/roles/mail_server/handlers/main.yml
@@ -1,17 +1,17 @@
 ---
 
 - name: Restart Postfix
-  service:
+  ansible.builtin.service:
     name: postfix
     state: restarted
 
 - name: Restart Dovecot
-  service:
+  ansible.builtin.service:
     name: dovecot
     state: restarted
 
 - name: Restart ClamAV Milter
-  service:
+  ansible.builtin.service:
     name: clamav-milter
     state: restarted
 
@@ -20,4 +20,4 @@
   #   This task is invoked only if user is very specific about requiring to
   #   run the handlers manually as a way to bring the system to consistency
   #   after interrupted runs.
-  command: /usr/bin/newaliases
+  ansible.builtin.command: /usr/bin/newaliases
diff --git a/roles/mail_server/molecule/default/cleanup.yml b/roles/mail_server/molecule/default/cleanup.yml
index c99ee79c29bc84b49f955fbcdf8734cda064bc64..32ba90b5c0f67eede47dee009ed76de8acd3ea27 100644
--- a/roles/mail_server/molecule/default/cleanup.yml
+++ b/roles/mail_server/molecule/default/cleanup.yml
@@ -7,7 +7,7 @@
   tasks:
 
     - name: Remove X.509 material
-      file:
+      ansible.builtin.file:
         path: "{{ item }}"
         state: absent
       with_items:
diff --git a/roles/mail_server/molecule/default/prepare.yml b/roles/mail_server/molecule/default/prepare.yml
index d17af227f5c44ae7dd3c4e8d6f5d6b45b0191156..c9823d72283b1eb0647fb900d13625b121cbabae 100644
--- a/roles/mail_server/molecule/default/prepare.yml
+++ b/roles/mail_server/molecule/default/prepare.yml
@@ -7,13 +7,13 @@
   tasks:
 
     - name: Initialise CA hierarchy
-      command: "gimmecert init"
+      ansible.builtin.command: "gimmecert init"
       args:
         creates: ".gimmecert/ca/level1.cert.pem"
         chdir: "tests/data/"
 
     - name: Generate server private keys and certificates
-      command:
+      ansible.builtin.command:
       args:
         chdir: "tests/data/"
         creates: ".gimmecert/server/{{ item.name }}.cert.pem"
@@ -39,7 +39,7 @@
           fqdn: parameters-optional-bookworm
 
     - name: Set-up link to generated X.509 material
-      file:
+      ansible.builtin.file:
         src: ".gimmecert"
         dest: "tests/data/x509"
         state: link
@@ -50,16 +50,16 @@
   gather_facts: false
   tasks:
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
 
     - name: Install tools for testing
-      apt:
+      ansible.builtin.apt:
         name:
           - gnutls-bin
           - nmap
@@ -71,14 +71,14 @@
   tasks:
 
     - name: Install system packages for hosting the ClamAV database
-      apt:
+      ansible.builtin.apt:
         name:
           - nginx
           - virtualenv
         state: present
 
     - name: Set-up directory for ClamAV database sync tool virtual environment
-      file:
+      ansible.builtin.file:
         path: /var/lib/cvdupdate
         state: directory
         owner: vagrant
@@ -88,12 +88,12 @@
     - name: Create virtual environment for running ClamAV database sync tool
       become: true
       become_user: vagrant
-      command:
+      ansible.builtin.command:
         cmd: "/usr/bin/virtualenv --python /usr/bin/python3 --prompt '(cvdupdate) ' /var/lib/cvdupdate"
         creates: "/var/lib/cvdupdate"
 
     - name: Deploy pip requirements file for running the ClamAV database sync tool
-      copy:
+      ansible.builtin.copy:
         src: cvdupdate-requirements.txt
         dest: /var/lib/cvdupdate/requirements.txt
         owner: vagrant
@@ -103,17 +103,17 @@
     - name: Install requirements in the pipreqcheck virtual environment
       become: true
       become_user: vagrant
-      pip:
+      ansible.builtin.pip:
         requirements: /var/lib/cvdupdate/requirements.txt
         virtualenv: /var/lib/cvdupdate
 
     - name: Allow traversal of Vagrant directory by the http server user
-      file:
+      ansible.builtin.file:
         path: /vagrant/
         mode: "0711"
 
     - name: Create directory for storing ClamAV database files
-      file:
+      ansible.builtin.file:
         path: /vagrant/clamav-database
         state: directory
         owner: vagrant
@@ -125,23 +125,23 @@
       #   Does not matter in test prepare step.
       become: true
       become_user: vagrant
-      command: "/var/lib/cvdupdate/bin/cvd config set --dbdir /vagrant/clamav-database/"
+      ansible.builtin.command: "/var/lib/cvdupdate/bin/cvd config set --dbdir /vagrant/clamav-database/"
 
     - name: Download/update the ClamAV database files  # noqa no-changed-when
       # [no-changed-when] Commands should not change things if nothing needs doing
       #   Does not matter in test prepare stage.
       become: true
       become_user: vagrant
-      command: "/var/lib/cvdupdate/bin/cvd update"
+      ansible.builtin.command: "/var/lib/cvdupdate/bin/cvd update"
 
     - name: Allow all users to read ClamAV database files
-      file:
+      ansible.builtin.file:
         path: "/vagrant/clamav-database/"
         mode: "g=u-w,o=u-w"
         recurse: true
 
     - name: Deploy nginx TLS private key
-      copy:
+      ansible.builtin.copy:
         dest: "/etc/ssl/private/nginx_https.key"
         content: "{{ clamav_database_http_server_tls_key }}"
         mode: "0640"
@@ -151,7 +151,7 @@
         - Restart nginx
 
     - name: Deploy nginx TLS certificate
-      copy:
+      ansible.builtin.copy:
         dest: "/etc/ssl/certs/nginx_https.pem"
         content: "{{ clamav_database_http_server_tls_certificate }}"
         mode: "0644"
@@ -161,7 +161,7 @@
         - Restart nginx
 
     - name: Deploy nginx configuration for serving the ClamAV database files
-      copy:
+      ansible.builtin.copy:
         src: clamav-database-nginx.conf
         dest: /etc/nginx/sites-available/default
         owner: root
@@ -173,7 +173,7 @@
   handlers:
 
     - name: Restart nginx
-      service:
+      ansible.builtin.service:
         name: nginx
         state: restarted
 
@@ -183,7 +183,7 @@
   tasks:
 
     - name: Enable TLSv1.0+ in global OpenSSL configuration file in order to be able to test the web_server_tls_protocols parameter
-      blockinfile:
+      ansible.builtin.blockinfile:
         path: "/etc/ssl/openssl.cnf"
         block: |
           [openssl_init]
@@ -201,7 +201,7 @@
         state: present
 
     - name: Set-up the hosts file
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/hosts
         regexp: "^{{ item.key }}"
         line: "{{ item.key }} {{ item.value }}"
@@ -224,7 +224,7 @@
   tasks:
 
     - name: Install tool for testing SMTP capability
-      apt:
+      ansible.builtin.apt:
         name: swaks
         state: present
 
@@ -232,17 +232,17 @@
       block:
 
         - name: Install required system packages
-          apt:
+          ansible.builtin.apt:
             name: python3-venv
             state: present
 
         - name: Set-up dedicated Python virtual environment for running the tool
-          command: "python3 -m venv /opt/imap-cli"
+          ansible.builtin.command: "python3 -m venv /opt/imap-cli"
           args:
             creates: /opt/imap-cli/bin/python
 
         - name: Install IMAP CLI
-          pip:
+          ansible.builtin.pip:
             name:
               - Imap-CLI==0.7
               - six
@@ -250,7 +250,7 @@
             virtualenv: /opt/imap-cli
 
         - name: Set-up symlinks for running the tool
-          file:
+          ansible.builtin.file:
             src: "/opt/imap-cli/bin/{{ item }}"
             dest: "/usr/local/bin/{{ item }}"
             owner: root
@@ -270,17 +270,17 @@
             - imap-cli-list
 
     - name: Install tool for testing SIEVE
-      apt:
+      ansible.builtin.apt:
         name: sieve-connect
         state: present
 
     - name: Install tool for testing TCP connectivity
-      apt:
+      ansible.builtin.apt:
         name: hping3
         state: present
 
     - name: Deploy IMAP CLI configuration
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/{{ item }}"
         dest: "/home/vagrant/{{ item }}"
         owner: vagrant
@@ -293,7 +293,7 @@
         - imapcli-parameters-optional-jane_doe.conf
 
     - name: Deploy CA certificate
-      copy:
+      ansible.builtin.copy:
         src: tests/data/x509/ca/level1.cert.pem
         dest: /usr/local/share/ca-certificates/testca.crt
         owner: root
@@ -306,18 +306,18 @@
       block:
 
         - name: Install Postfix
-          apt:
+          ansible.builtin.apt:
             name: postfix
             state: present
 
         - name: Purge Exim
-          apt:
+          ansible.builtin.apt:
             name: "exim4*"
             state: absent
             purge: true
 
         - name: Configure Postfix
-          template:
+          ansible.builtin.template:
             src: "helper_smtp_main.cf.j2"
             dest: "/etc/postfix/main.cf"
             owner: root
@@ -327,7 +327,7 @@
             - Restart Postfix
 
         - name: Enable Postfix service
-          service:
+          ansible.builtin.service:
             name: postfix
             state: started
             enabled: true
@@ -335,12 +335,12 @@
   handlers:
 
     - name: Update CA certificate cache  # noqa no-changed-when
-      command: /usr/sbin/update-ca-certificates --fresh
+      ansible.builtin.command: /usr/sbin/update-ca-certificates --fresh
       # [no-changed-when] Commands should not change things if nothing needs doing
       #   Does not matter in test prepare stage.
 
     - name: Restart Postfix
-      service:
+      ansible.builtin.service:
         name: postfix
         state: restarted
 
@@ -357,7 +357,7 @@
   tasks:
 
     - name: Create LDAP accounts for testing
-      ldap_entry:
+      community.general.ldap_entry:
         dn: "{{ item.dn }}"
         objectClass: "{{ item.objectClass }}"
         attributes: "{{ item.attributes }}"
@@ -436,10 +436,10 @@
   tasks:
 
     - name: Create group for user used for local mail delivery testing
-      group:
+      ansible.builtin.group:
         name: localuser
 
     - name: Create user for local mail delivery testing
-      user:
+      ansible.builtin.user:
         name: localuser
         group: localuser
diff --git a/roles/mail_server/tasks/main.yml b/roles/mail_server/tasks/main.yml
index 4024e27bc0efe4ff088893d6b5731906293ddc28..486ff223d636232437b3d613253bf0ffd679ca87 100644
--- a/roles/mail_server/tasks/main.yml
+++ b/roles/mail_server/tasks/main.yml
@@ -1,12 +1,12 @@
 ---
 
 - name: Install rsync
-  apt:
+  ansible.builtin.apt:
     name: rsync
     state: present
 
 - name: Install Dovecot packages
-  apt:
+  ansible.builtin.apt:
     name:
       - dovecot-imapd
       - dovecot-ldap
@@ -15,32 +15,32 @@
     state: present
 
 - name: Install Postfix packages
-  apt:
+  ansible.builtin.apt:
     name:
       - postfix
       - postfix-ldap
     state: present
 
 - name: Purge Exim configuration
-  apt:
+  ansible.builtin.apt:
     name: "exim4*"
     state: absent
     purge: true
 
 - name: Allow Postfix user to traverse the directory with TLS private keys
-  user:
+  ansible.builtin.user:
     name: postfix
     append: true
     groups: ssl-cert
 
 - name: Allow Dovecot user to traverse the directory with TLS private keys
-  user:
+  ansible.builtin.user:
     name: dovecot
     append: true
     groups: ssl-cert
 
 - name: Deploy SMTP TLS private key
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/private/{{ ansible_fqdn }}_smtp.key"
     content: "{{ smtp_tls_key }}"
     mode: "0640"
@@ -50,7 +50,7 @@
     - Restart Postfix
 
 - name: Deploy SMTP TLS certificate
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/certs/{{ ansible_fqdn }}_smtp.pem"
     content: "{{ smtp_tls_certificate }}"
     mode: "0644"
@@ -60,7 +60,7 @@
     - Restart Postfix
 
 - name: Generate the SMTP server Diffie-Hellman parameter
-  openssl_dhparam:
+  community.crypto.openssl_dhparam:
     owner: root
     group: root
     mode: "0640"
@@ -70,7 +70,7 @@
     - Restart Postfix
 
 - name: Deploy IMAP TLS private key
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/private/{{ ansible_fqdn }}_imap.key"
     content: "{{ imap_tls_key }}"
     mode: "0640"
@@ -80,7 +80,7 @@
     - Restart Dovecot
 
 - name: Deploy IMAP TLS certificate
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/certs/{{ ansible_fqdn }}_imap.pem"
     content: "{{ imap_tls_certificate }}"
     mode: "0644"
@@ -90,7 +90,7 @@
     - Restart Dovecot
 
 - name: Generate the IMAP server Diffie-Hellman parameter
-  openssl_dhparam:
+  community.crypto.openssl_dhparam:
     owner: root
     group: root
     mode: "0640"
@@ -100,7 +100,7 @@
     - Restart Dovecot
 
 - name: Deploy configuration files for checking certificate validity via cron
-  copy:
+  ansible.builtin.copy:
     content: "/etc/ssl/certs/{{ ansible_fqdn }}_{{ item }}.pem"
     dest: "/etc/check_certificate/{{ ansible_fqdn }}_{{ item }}.conf"
     owner: root
@@ -111,17 +111,17 @@
     - imap
 
 - name: Install SWAKS
-  apt:
+  ansible.builtin.apt:
     name: swaks
     state: present
 
 - name: Install milter packages
-  apt:
+  ansible.builtin.apt:
     name: clamav-milter
     state: present
 
 - name: Configure ClamAV Milter
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/clamav/clamav-milter.conf"
     src: "clamav-milter.conf"
     mode: "0644"
@@ -131,7 +131,7 @@
     - Restart ClamAV Milter
 
 - name: Set-up privileges for directories within Postfix chroot
-  file:
+  ansible.builtin.file:
     dest: "{{ item }}"
     mode: "0755"
     state: directory
@@ -142,7 +142,7 @@
     - /var/spool/postfix/var/run
 
 - name: Set-up privileges for directories within Postfix chroot
-  file:
+  ansible.builtin.file:
     dest: "{{ item }}"
     state: directory
     owner: clamav
@@ -152,7 +152,7 @@
     - /var/spool/postfix/var/run/clamav
 
 - name: Deploy the LDAP TLS truststore in default location
-  copy:
+  ansible.builtin.copy:
     content: "{{ mail_ldap_tls_truststore }}"
     dest: "/etc/ssl/certs/mail_ldap_tls_truststore.pem"
     owner: root
@@ -160,7 +160,7 @@
     mode: "0644"
 
 - name: Deploy the LDAP TLS truststore in Postfix chroot
-  copy:
+  ansible.builtin.copy:
     content: "{{ mail_ldap_tls_truststore }}"
     dest: "/var/spool/postfix/etc/ssl/certs/mail_ldap_tls_truststore.pem"
     owner: root
@@ -170,7 +170,7 @@
     - Restart Postfix
 
 - name: Configure visible mail name of the system
-  copy:
+  ansible.builtin.copy:
     content: "{{ inventory_hostname }}"
     dest: "/etc/mailname"
     owner: root
@@ -180,7 +180,7 @@
     - Restart Postfix
 
 - name: Deploy Postfix configurations files for LDAP look-ups
-  template:
+  ansible.builtin.template:
     src: "{{ item }}.cf.j2"
     dest: "/etc/postfix/{{ item }}.cf"
     owner: root
@@ -194,7 +194,7 @@
     - Restart Postfix
 
 - name: Deploy Postfix main configuration
-  template:
+  ansible.builtin.template:
     src: "main.cf.j2"
     dest: "/etc/postfix/main.cf"
     owner: root
@@ -204,7 +204,7 @@
     - Restart Postfix
 
 - name: Set-up local mail aliases
-  lineinfile:
+  ansible.builtin.lineinfile:
     dest: "/etc/aliases"
     line: "{{ item.key }}: {{ item.value }}"
     regexp: "^{{ item.key }}"
@@ -214,13 +214,13 @@
     - Rebuild mail aliases
 
 - name: Create mail owner group
-  group:
+  ansible.builtin.group:
     name: "{{ mail_user }}"
     gid: "{{ mail_user_gid | default(omit) }}"
     state: present
 
 - name: Create mail owner user
-  user:
+  ansible.builtin.user:
     name: "{{ mail_user }}"
     uid: "{{ mail_user_uid | default(omit) }}"
     group: "{{ mail_user }}"
@@ -228,7 +228,7 @@
     state: present
 
 - name: Disable Dovecot system authentication
-  lineinfile:
+  ansible.builtin.lineinfile:
     dest: "/etc/dovecot/conf.d/10-auth.conf"
     line: "!include auth-system.conf.ext"
     state: absent
@@ -236,7 +236,7 @@
     - Restart Dovecot
 
 - name: Deploy Dovecot configuration file with overrides
-  template:
+  ansible.builtin.template:
     src: "99-local.conf.j2"
     dest: "/etc/dovecot/conf.d/99-local.conf"
     owner: root
@@ -246,7 +246,7 @@
     - Restart Dovecot
 
 - name: Deploy Dovecot configuration file for LDAP look-ups
-  template:
+  ansible.builtin.template:
     src: "dovecot-ldap.conf.ext.j2"
     dest: "/etc/dovecot/dovecot-ldap.conf.ext"
     owner: root
@@ -256,7 +256,7 @@
     - Restart Dovecot
 
 - name: Deploy Postifx master process configuration
-  template:
+  ansible.builtin.template:
     src: "master.cf.j2"
     dest: "/etc/postfix/master.cf"
     owner: root
@@ -266,13 +266,13 @@
     - Restart Postfix
 
 - name: Enable and start ClamAV database update service (freshclam)
-  service:
+  ansible.builtin.service:
     name: clamav-freshclam
     state: started
     enabled: true
 
 - name: Check availability of ClamAV database files
-  stat:
+  ansible.builtin.stat:
     path: "{{ item }}"
   with_items:
     - /var/lib/clamav/bytecode.cld
@@ -283,12 +283,12 @@
 - name: Wait for ClamAV database to be available (up to 10 minutes)
   when: not item.stat.exists
   with_items: "{{ clamav_db_files.results }}"
-  wait_for:
+  ansible.builtin.wait_for:
     path: "{{ item.item | replace('.cld', '.cvd') }}"
     timeout: 600
 
 - name: Enable and start ClamAV daemon and milter services
-  service:
+  ansible.builtin.service:
     name: "{{ item }}"
     state: started
     enabled: true
@@ -298,24 +298,24 @@
 
 # It may take ClamAV a while to read all the necessary database files etc.
 - name: Wait for ClamAV to become available (up to 5 minutes)
-  wait_for:
+  ansible.builtin.wait_for:
     path: "/var/run/clamav/clamd.ctl"
     timeout: 300
 
 - name: Enable and start Postfix service
-  service:
+  ansible.builtin.service:
     name: postfix
     state: started
     enabled: true
 
 - name: Enable and start Dovecot service
-  service:
+  ansible.builtin.service:
     name: dovecot
     state: started
     enabled: true
 
 - name: Deploy firewall configuration for mail server
-  copy:
+  ansible.builtin.copy:
     src: "ferm_mail.conf"
     dest: "/etc/ferm/conf.d/20-mail.conf"
     owner: root
@@ -325,7 +325,7 @@
     - Restart ferm
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/php_website/handlers/main.yml b/roles/php_website/handlers/main.yml
index 8dae2fd6fcd7ea5173f2e61f1ea32b955134ba09..64ed8c7d39295a6b5016864971d59d5a1bfc1728 100644
--- a/roles/php_website/handlers/main.yml
+++ b/roles/php_website/handlers/main.yml
@@ -1,5 +1,5 @@
 ---
 
 - name: Dummy handler to suppress Ansible warnings
-  debug:
+  ansible.builtin.debug:
     msg: "This is just a dummy task to suppress the Ansible warning about an empty include."
diff --git a/roles/php_website/molecule/default/cleanup.yml b/roles/php_website/molecule/default/cleanup.yml
index c99ee79c29bc84b49f955fbcdf8734cda064bc64..32ba90b5c0f67eede47dee009ed76de8acd3ea27 100644
--- a/roles/php_website/molecule/default/cleanup.yml
+++ b/roles/php_website/molecule/default/cleanup.yml
@@ -7,7 +7,7 @@
   tasks:
 
     - name: Remove X.509 material
-      file:
+      ansible.builtin.file:
         path: "{{ item }}"
         state: absent
       with_items:
diff --git a/roles/php_website/molecule/default/converge.yml b/roles/php_website/molecule/default/converge.yml
index 281a31735ae19720b7467fa2524f292fe2878c33..c5567a9a36868757aeba2b3ae4e53ba37190625d 100644
--- a/roles/php_website/molecule/default/converge.yml
+++ b/roles/php_website/molecule/default/converge.yml
@@ -57,7 +57,7 @@
   tasks:
     # parameters-mandatory application
     - name: Set-up directory where PHP files are hosted at
-      file:
+      ansible.builtin.file:
         path: /var/www/parameters-mandatory/htdocs
         state: directory
         owner: admin-parameters-mandatory
@@ -65,7 +65,7 @@
         mode: "0750"
 
     - name: Deploy a couple of PHP pages for testing purposes
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/php/mandatory/{{ item }}"
         dest: "/var/www/parameters-mandatory/htdocs/{{ item }}"
         owner: admin-parameters-mandatory
@@ -77,7 +77,7 @@
 
     # parameters-optional application
     - name: Set-up directory where PHP files are hosted at
-      file:
+      ansible.builtin.file:
         path: /var/www/parameters-optional.local/htdocs
         state: directory
         owner: admin-parameters-optional_local
@@ -85,7 +85,7 @@
         mode: "0750"
 
     - name: Deploy a couple of PHP pages for testing purposes
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/php/optional/{{ item }}"
         dest: "/var/www/parameters-optional.local/htdocs/{{ item }}"
         owner: admin-parameters-optional_local
diff --git a/roles/php_website/molecule/default/prepare.yml b/roles/php_website/molecule/default/prepare.yml
index 020b223c349afcac324b015b6b29228d7f5b7554..1de5e3f8c4bca4e1660e8bdc906fc9495d8afae3 100644
--- a/roles/php_website/molecule/default/prepare.yml
+++ b/roles/php_website/molecule/default/prepare.yml
@@ -7,13 +7,13 @@
   tasks:
 
     - name: Initialise CA hierarchy
-      command: "gimmecert init"
+      ansible.builtin.command: "gimmecert init"
       args:
         creates: ".gimmecert/ca/level1.cert.pem"
         chdir: "tests/data/"
 
     - name: Generate server private keys and certificates
-      command:
+      ansible.builtin.command:
       args:
         chdir: "tests/data/"
         creates: ".gimmecert/server/{{ item.name }}.cert.pem"
@@ -31,7 +31,7 @@
           fqdn: php-website
 
     - name: Set-up link to generated X.509 material
-      file:
+      ansible.builtin.file:
         src: ".gimmecert"
         dest: "tests/data/x509"
         state: link
@@ -43,42 +43,42 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       become: true
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
 
     - name: Set-up /etc/hosts entries
-      lineinfile:
+      ansible.builtin.lineinfile:
         dest: /etc/hosts
         line: "{{ ansible_eth0.ipv4.address }} parameters-mandatory parameters-optional.local php-website"
 
     - name: Install curl for testing redirects and webpage content
-      apt:
+      ansible.builtin.apt:
         name: curl
         state: present
 
     - name: Install swaks for testing mail forwarding
-      apt:
+      ansible.builtin.apt:
         name: swaks
         state: present
 
     - name: Install Postfix for testing mail forwarding (Exim4 not covered)
-      apt:
+      ansible.builtin.apt:
         name: postfix
         state: present
 
     - name: Install procmail for consistency with mail_server and mail_forwarder roles
-      apt:
+      ansible.builtin.apt:
         name: procmail
         state: present
 
     - name: Update Postfix configuration
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/postfix/main.cf
         regexp: "^{{ item.key }}"
         line: "{{ item.value }}"
@@ -90,7 +90,7 @@
         - Restart Postfix
 
     - name: Direct all mails from the root account to vagrant
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/aliases
         regexp: "^root"
         line: "root: vagrant"
@@ -99,12 +99,12 @@
         - Generate aliases database
 
     - name: Set-up group for an additional user
-      group:
+      ansible.builtin.group:
         name: user
         state: present
 
     - name: Set-up additional user for testing mail delivery
-      user:
+      ansible.builtin.user:
         name: user
         group: user
         shell: /bin/bash
@@ -112,11 +112,11 @@
   handlers:
 
     - name: Restart Postfix
-      service:
+      ansible.builtin.service:
         name: postfix
         state: restarted
 
     - name: Generate aliases database  # noqa no-changed-when
-      command: "/usr/bin/newaliases"
+      ansible.builtin.command: "/usr/bin/newaliases"
       # [no-changed-when] Commands should not change things if nothing needs doing
       #   Does not matter in test prepare stage.
diff --git a/roles/php_website/tasks/main.yml b/roles/php_website/tasks/main.yml
index 13751868d871a4bd4d35d18b13d8a950754d76c4..79badd10eecaab00605bc0aec986ccaff6d9977e 100644
--- a/roles/php_website/tasks/main.yml
+++ b/roles/php_website/tasks/main.yml
@@ -1,23 +1,23 @@
 ---
 
 - name: Create PHP website group
-  group:
+  ansible.builtin.group:
     name: "{{ user }}"
     gid: "{{ uid | default(omit) }}"
     state: present
 
 - name: Create PHP website admin user
-  user:
+  ansible.builtin.user:
     name: "{{ admin }}"
     uid: "{{ admin_uid | default(omit) }}"
     group: "{{ user }}"
-    shell: /bin/bash
+    ansible.builtin.shell: /bin/bash
     createhome: true
     home: "{{ home }}"
     state: present
 
 - name: Set-up directory for storing user profile configuration files
-  file:
+  ansible.builtin.file:
     path: "{{ home }}/.profile.d"
     state: directory
     owner: "{{ admin }}"
@@ -25,7 +25,7 @@
     mode: "0750"
 
 - name: Create PHP website user
-  user:
+  ansible.builtin.user:
     name: "{{ user }}"
     uid: "{{ uid | default(omit) }}"
     group: "{{ user }}"
@@ -37,10 +37,10 @@
     # This is a workaround for a rather stupid bug that Debian seems
     # uninterested to backport -
     # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865762
-    shell: /bin/sh
+    ansible.builtin.shell: /bin/sh
 
 - name: Add nginx user to website group
-  user:
+  ansible.builtin.user:
     name: "www-data"
     groups: "{{ user }}"
     append: "yes"
@@ -50,7 +50,7 @@
 # Ownership set to root so Postfix would not check if correct user owns the
 # file.
 - name: Set-up forwarding for mails delivered to local application user/admin
-  template:
+  ansible.builtin.template:
     src: "forward.j2"
     dest: "{{ home }}/.forward"
     owner: root
@@ -58,12 +58,12 @@
     mode: "0640"
 
 - name: Install extra packages for website
-  apt:
+  ansible.builtin.apt:
     name: "{{ packages }}"
     state: present
 
 - name: Deploy PHP FPM configuration file for website
-  template:
+  ansible.builtin.template:
     src: "fpm_site.conf.j2"
     dest: "{{ php_fpm_pool_directory }}/{{ fqdn }}.conf"
     validate: "{{ php_fpm_binary }} -t -y %s"
@@ -74,7 +74,7 @@
     - Restart PHP-FPM
 
 - name: Deploy nginx TLS private key for website
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/private/{{ fqdn }}_https.key"
     content: "{{ https_tls_key }}"
     owner: root
@@ -84,7 +84,7 @@
     - Restart nginx
 
 - name: Deploy nginx TLS certificate for website
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/certs/{{ fqdn }}_https.pem"
     content: "{{ https_tls_certificate }}"
     owner: root
@@ -94,7 +94,7 @@
     - Restart nginx
 
 - name: Deploy configuration file for checking certificate validity via cron
-  copy:
+  ansible.builtin.copy:
     content: "/etc/ssl/certs/{{ fqdn }}_https.pem"
     dest: "/etc/check_certificate/{{ fqdn }}_https.conf"
     owner: root
@@ -102,7 +102,7 @@
     mode: "0644"
 
 - name: Deploy nginx configuration file for website
-  template:
+  ansible.builtin.template:
     src: "nginx_site.j2"
     dest: "/etc/nginx/sites-available/{{ fqdn }}"
     owner: root
@@ -113,7 +113,7 @@
     - Restart nginx
 
 - name: Enable website
-  file:
+  ansible.builtin.file:
     src: "/etc/nginx/sites-available/{{ fqdn }}"
     dest: "/etc/nginx/sites-enabled/{{ fqdn }}"
     state: link
@@ -121,7 +121,7 @@
     - Restart nginx
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/preseed/handlers/main.yml b/roles/preseed/handlers/main.yml
index 8dae2fd6fcd7ea5173f2e61f1ea32b955134ba09..64ed8c7d39295a6b5016864971d59d5a1bfc1728 100644
--- a/roles/preseed/handlers/main.yml
+++ b/roles/preseed/handlers/main.yml
@@ -1,5 +1,5 @@
 ---
 
 - name: Dummy handler to suppress Ansible warnings
-  debug:
+  ansible.builtin.debug:
     msg: "This is just a dummy task to suppress the Ansible warning about an empty include."
diff --git a/roles/preseed/molecule/default/prepare.yml b/roles/preseed/molecule/default/prepare.yml
index eefd77c3d02929d5fe3bed6cc81072fdb26e7060..ad4260a270d56a9bbe635a177383b7e91432684d 100644
--- a/roles/preseed/molecule/default/prepare.yml
+++ b/roles/preseed/molecule/default/prepare.yml
@@ -7,10 +7,10 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
diff --git a/roles/preseed/tasks/main.yml b/roles/preseed/tasks/main.yml
index a46d16b73e4949bb767031ecbe6e4821162146a3..7be8ddb2c805deab40f98d645f17b9d2becc4d38 100644
--- a/roles/preseed/tasks/main.yml
+++ b/roles/preseed/tasks/main.yml
@@ -1,13 +1,13 @@
 ---
 
 - name: Create directory for storing preseed configurations
-  file:
+  ansible.builtin.file:
     path: "{{ preseed_directory }}"
     mode: "0750"
     state: directory
 
 - name: Create preseed configuration file
-  template:
+  ansible.builtin.template:
     src: "preseed.cfg.j2"
     dest: "{{ preseed_directory }}/{{ item }}.cfg"
     mode: "0640"
@@ -15,7 +15,7 @@
   with_items: "{{ groups['all'] }}"
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/web_server/handlers/main.yml b/roles/web_server/handlers/main.yml
index eb37ccbd5a810918ddcdfcb5a4855edb318ab49f..dc6065c4d957ecc9c6ed9884c4d8893ae14c0cd0 100644
--- a/roles/web_server/handlers/main.yml
+++ b/roles/web_server/handlers/main.yml
@@ -1,15 +1,15 @@
 ---
 
 - name: Reload systemd
-  systemd:
+  ansible.builtin.systemd:
     daemon_reload: true
 
 - name: Restart nginx
-  service:
+  ansible.builtin.service:
     name: nginx
     state: restarted
 
 - name: Restart PHP-FPM
-  service:
+  ansible.builtin.service:
     name: "{{ php_fpm_service_name }}"
     state: restarted
diff --git a/roles/web_server/molecule/default/cleanup.yml b/roles/web_server/molecule/default/cleanup.yml
index c99ee79c29bc84b49f955fbcdf8734cda064bc64..32ba90b5c0f67eede47dee009ed76de8acd3ea27 100644
--- a/roles/web_server/molecule/default/cleanup.yml
+++ b/roles/web_server/molecule/default/cleanup.yml
@@ -7,7 +7,7 @@
   tasks:
 
     - name: Remove X.509 material
-      file:
+      ansible.builtin.file:
         path: "{{ item }}"
         state: absent
       with_items:
diff --git a/roles/web_server/molecule/default/prepare.yml b/roles/web_server/molecule/default/prepare.yml
index 4e4b727b882399cd82335e66f3f884a9d0bc03e8..a2786386705b904507e654d59e321465baf3de2d 100644
--- a/roles/web_server/molecule/default/prepare.yml
+++ b/roles/web_server/molecule/default/prepare.yml
@@ -7,13 +7,13 @@
   tasks:
 
     - name: Initialise CA hierarchy
-      command: "gimmecert init"
+      ansible.builtin.command: "gimmecert init"
       args:
         creates: ".gimmecert/ca/level1.cert.pem"
         chdir: "tests/data/"
 
     - name: Generate server private keys and certificates
-      command:
+      ansible.builtin.command:
       args:
         chdir: "tests/data/"
         creates: ".gimmecert/server/{{ item.name }}.cert.pem"
@@ -29,7 +29,7 @@
           fqdn: parameters-optional-bookworm
 
     - name: Set-up link to generated X.509 material
-      file:
+      ansible.builtin.file:
         src: ".gimmecert"
         dest: "tests/data/x509"
         state: link
@@ -41,16 +41,16 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
 
     - name: Install tools for testing
-      apt:
+      ansible.builtin.apt:
         name:
           - gnutls-bin
           - nmap
@@ -62,7 +62,7 @@
   tasks:
 
     - name: Enable TLSv1.0+ in global OpenSSL configuration file in order to be able to test the web_server_tls_protocols parameter
-      blockinfile:
+      ansible.builtin.blockinfile:
         path: "/etc/ssl/openssl.cnf"
         block: |
           [openssl_init]
@@ -85,7 +85,7 @@
   tasks:
 
     - name: Set-up the hosts file
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/hosts
         regexp: "^{{ item.key }}"
         line: "{{ item.key }} {{ item.value }}"
@@ -99,7 +99,7 @@
         192.168.56.22: "parameters-optional-bookworm"
 
     - name: Install curl for testing redirects and webpage content
-      apt:
+      ansible.builtin.apt:
         name: curl
         state: present
 
@@ -109,17 +109,17 @@
   tasks:
 
     - name: Install tool for testing TCP connectivity
-      apt:
+      ansible.builtin.apt:
         name: hping3
         state: present
 
     - name: Install console-based web browser for interactive testing
-      apt:
+      ansible.builtin.apt:
         name: lynx
         state: present
 
     - name: Deploy CA certificate
-      copy:
+      ansible.builtin.copy:
         src: tests/data/x509/ca/level1.cert.pem
         dest: /usr/local/share/ca-certificates/testca.crt
         owner: root
@@ -131,6 +131,6 @@
   handlers:
 
     - name: Update CA certificate cache  # noqa no-changed-when
-      command: /usr/sbin/update-ca-certificates --fresh
+      ansible.builtin.command: /usr/sbin/update-ca-certificates --fresh
       # [no-changed-when] Commands should not change things if nothing needs doing
       #   Does not matter in test prepare stage.
diff --git a/roles/web_server/tasks/main.yml b/roles/web_server/tasks/main.yml
index 5231de98a857f8f8c810a65b7cde8a08adfd63cc..1f33b0473f3bacf13d42f38867de597f47185f85 100644
--- a/roles/web_server/tasks/main.yml
+++ b/roles/web_server/tasks/main.yml
@@ -1,12 +1,12 @@
 ---
 
 - name: Install nginx
-  apt:
+  ansible.builtin.apt:
     name: nginx
     state: present
 
 - name: Allow nginx user to traverse the directory with TLS private keys
-  user:
+  ansible.builtin.user:
     name: www-data
     append: true
     groups: ssl-cert
@@ -14,7 +14,7 @@
     - Restart nginx
 
 - name: Deploy nginx TLS private key
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/private/{{ ansible_fqdn }}_https.key"
     content: "{{ default_https_tls_key }}"
     mode: "0640"
@@ -24,7 +24,7 @@
     - Restart nginx
 
 - name: Deploy nginx TLS certificate
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/certs/{{ ansible_fqdn }}_https.pem"
     content: "{{ default_https_tls_certificate }}"
     mode: "0644"
@@ -34,7 +34,7 @@
     - Restart nginx
 
 - name: Generate the HTTPS server Diffie-Hellman parameter
-  openssl_dhparam:
+  community.crypto.openssl_dhparam:
     owner: root
     group: root
     mode: "0640"
@@ -44,7 +44,7 @@
     - Restart nginx
 
 - name: Deploy configuration file for checking certificate validity via cron
-  copy:
+  ansible.builtin.copy:
     content: "/etc/ssl/certs/{{ ansible_fqdn }}_https.pem"
     dest: "/etc/check_certificate/{{ ansible_fqdn }}_https.conf"
     owner: root
@@ -52,7 +52,7 @@
     mode: "0644"
 
 - name: Remove TLS protocol configuration from the main configuration file
-  lineinfile:
+  ansible.builtin.lineinfile:
     dest: "/etc/nginx/nginx.conf"
     backrefs: true
     regexp: "^\\s*ssl_protocols"
@@ -61,7 +61,7 @@
     - Restart nginx
 
 - name: Harden TLS by allowing only TLSv1.2 and PFS ciphers
-  template:
+  ansible.builtin.template:
     dest: "/etc/nginx/conf.d/tls.conf"
     src: "tls.conf.j2"
     owner: "root"
@@ -71,7 +71,7 @@
     - Restart nginx
 
 - name: Deploy script for verification of nginx vhost configurations
-  copy:
+  ansible.builtin.copy:
     src: "nginx_verify_site.sh"
     dest: "/usr/local/bin/nginx_verify_site.sh"
     owner: root
@@ -79,7 +79,7 @@
     mode: "0755"
 
 - name: Deploy default vhost configuration
-  template:
+  ansible.builtin.template:
     src: "nginx-default.j2"
     dest: "/etc/nginx/sites-available/default"
     owner: root
@@ -90,7 +90,7 @@
     - Restart nginx
 
 - name: Enable default website
-  file:
+  ansible.builtin.file:
     src: "/etc/nginx/sites-available/default"
     dest: "/etc/nginx/sites-enabled/default"
     state: link
@@ -98,7 +98,7 @@
     - Restart nginx
 
 - name: Deploy firewall configuration for web server
-  copy:
+  ansible.builtin.copy:
     src: "ferm_http.conf"
     dest: "/etc/ferm/conf.d/30-web.conf"
     owner: root
@@ -108,7 +108,7 @@
     - Restart ferm
 
 - name: Remove the default Debian html files
-  file:
+  ansible.builtin.file:
     path: "{{ item }}"
     state: absent
   with_items:
@@ -116,7 +116,7 @@
     - /var/www/html/
 
 - name: Create directory for storing the default website page
-  file:
+  ansible.builtin.file:
     path: "/var/www/default/"
     state: directory
     owner: root
@@ -124,7 +124,7 @@
     mode: "0750"
 
 - name: Deploy the default index.html
-  template:
+  ansible.builtin.template:
     src: "index.html.j2"
     dest: /var/www/default/index.html
     owner: root
@@ -132,13 +132,13 @@
     mode: "0640"
 
 - name: Enable nginx service
-  service:
+  ansible.builtin.service:
     name: nginx
     enabled: true
     state: started
 
 - name: Install base packages for Python web applications
-  apt:
+  ansible.builtin.apt:
     name:
       - python3-setuptools
       - virtualenv
@@ -146,12 +146,12 @@
     state: present
 
 - name: Install base packages for PHP web applications
-  apt:
+  ansible.builtin.apt:
     name: "{{ php_fpm_package_name }}"
     state: present
 
 - name: Create directories for storing per-site socket files
-  file:
+  ansible.builtin.file:
     path: "/run/{{ item }}"
     state: directory
     owner: root
@@ -162,7 +162,7 @@
     - php
 
 - name: Create directories for storing per-site socket files on boot
-  copy:
+  ansible.builtin.copy:
     content: "d /run/{{ item.socket_dir }}/ 0750 root www-data - -"
     dest: "/etc/tmpfiles.d/{{ item.tmpfiles_d }}"
     owner: root
@@ -175,7 +175,7 @@
       tmpfiles_d: "{{ php_fpm_service_name }}.conf"
 
 - name: Create directory for storing PHP-FPM service configuration overrides
-  file:
+  ansible.builtin.file:
     path: "/etc/systemd/system/{{ php_fpm_service_name }}.service.d/"
     state: directory
     owner: root
@@ -183,7 +183,7 @@
     mode: "0755"
 
 - name: Configure PHP-FPM service to run with umask 0007
-  copy:
+  ansible.builtin.copy:
     src: "php_fpm_umask.conf"
     dest: "/etc/systemd/system/{{ php_fpm_service_name }}.service.d/umask.conf"
     owner: root
@@ -194,18 +194,18 @@
     - Restart PHP-FPM
 
 - name: Enable service used for running PHP web applications
-  service:
+  ansible.builtin.service:
     name: "{{ php_fpm_service_name }}"
     enabled: true
     state: started
 
 - name: Read timezone on server
-  slurp:
+  ansible.builtin.slurp:
     src: "/etc/timezone"
   register: server_timezone
 
 - name: Configure timezone for PHP
-  template:
+  ansible.builtin.template:
     src: "php_timezone.ini.j2"
     dest: "{{ item }}/30-timezone.ini"
     owner: root
@@ -218,7 +218,7 @@
     - Restart PHP-FPM
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/wsgi_website/handlers/main.yml b/roles/wsgi_website/handlers/main.yml
index 85cf33f3ed06ea1e3d29e3b6013a820062f21df3..e11ee2361e866cbb0a26495279cd53b13f3a0a9b 100644
--- a/roles/wsgi_website/handlers/main.yml
+++ b/roles/wsgi_website/handlers/main.yml
@@ -1,7 +1,7 @@
 ---
 
 - name: Restart WSGI services
-  service:
+  ansible.builtin.service:
     name: "{{ item }}"
     state: restarted
   with_items: "{{ wsgi_services_to_restart }}"
diff --git a/roles/wsgi_website/molecule/default/cleanup.yml b/roles/wsgi_website/molecule/default/cleanup.yml
index c99ee79c29bc84b49f955fbcdf8734cda064bc64..32ba90b5c0f67eede47dee009ed76de8acd3ea27 100644
--- a/roles/wsgi_website/molecule/default/cleanup.yml
+++ b/roles/wsgi_website/molecule/default/cleanup.yml
@@ -7,7 +7,7 @@
   tasks:
 
     - name: Remove X.509 material
-      file:
+      ansible.builtin.file:
         path: "{{ item }}"
         state: absent
       with_items:
diff --git a/roles/wsgi_website/molecule/default/converge.yml b/roles/wsgi_website/molecule/default/converge.yml
index 1ecfd890eee621f7c78902930f70da3f9f0b21f4..b9087f4851f1313737980f4e82aa4512a3793652 100644
--- a/roles/wsgi_website/molecule/default/converge.yml
+++ b/roles/wsgi_website/molecule/default/converge.yml
@@ -97,7 +97,7 @@
   tasks:
     # parameters-mandatory application
     - name: Set-up directories where application files are hosted at
-      file:
+      ansible.builtin.file:
         path: "/var/www/parameters-mandatory/{{ item }}"
         state: directory
         owner: admin-parameters-mandatory
@@ -108,7 +108,7 @@
         - htdocs/media
         - code
     - name: Deploy WSGI application
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/python/wsgi/testapp.py"
         dest: "/var/www/parameters-mandatory/code/testapp.py"
         owner: admin-parameters-mandatory
@@ -117,14 +117,14 @@
       notify:
         - Restart parameters-mandatory
     - name: Deploy a static file
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/static_file.txt"
         dest: "/var/www/parameters-mandatory/htdocs/static/static_file.txt"
         owner: admin-parameters-mandatory
         group: web-parameters-mandatory
         mode: "0640"
     - name: Deploy a media file
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/media_file.txt"
         dest: "/var/www/parameters-mandatory/htdocs/media/media_file.txt"
         owner: admin-parameters-mandatory
@@ -133,7 +133,7 @@
 
     # parameters-optional application
     - name: Set-up directories where application files are hosted at
-      file:
+      ansible.builtin.file:
         path: "/var/www/parameters-optional.local/{{ item }}"
         state: directory
         owner: admin-parameters-optional_local
@@ -144,7 +144,7 @@
         - htdocs/media
         - code
     - name: Deploy WSGI application
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/python/wsgi/testapp.py"
         dest: "/var/www/parameters-optional.local/code/testapp.py"
         owner: admin-parameters-optional_local
@@ -153,14 +153,14 @@
       notify:
         - Restart parameters-optional.local
     - name: Deploy a static file
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/static_file.txt"
         dest: "/var/www/parameters-optional.local/htdocs/static/static_file.txt"
         owner: admin-parameters-optional_local
         group: web-parameters-optional_local
         mode: "0640"
     - name: Deploy a media file
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/media_file.txt"
         dest: "/var/www/parameters-optional.local/htdocs/media/media_file.txt"
         owner: admin-parameters-optional_local
@@ -169,7 +169,7 @@
 
     # parameters-paste-req application
     - name: Set-up directories where application files are hosted at
-      file:
+      ansible.builtin.file:
         path: "/var/www/parameters-paste-req/{{ item }}"
         state: directory
         owner: admin-parameters-paste-req
@@ -180,7 +180,7 @@
         - htdocs/media
         - code
     - name: Deploy WSGI application
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/python/paste/{{ item }}"
         dest: "/var/www/parameters-paste-req/code/{{ item }}"
         owner: admin-parameters-paste-req
@@ -193,14 +193,14 @@
       notify:
         - Restart parameters-paste-req
     - name: Deploy a static file
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/static_file.txt"
         dest: "/var/www/parameters-paste-req/htdocs/static/static_file.txt"
         owner: admin-parameters-paste-req
         group: web-parameters-paste-req
         mode: "0640"
     - name: Deploy a media file
-      copy:
+      ansible.builtin.copy:
         src: "tests/data/media_file.txt"
         dest: "/var/www/parameters-paste-req/htdocs/media/media_file.txt"
         owner: admin-parameters-paste-req
@@ -209,14 +209,14 @@
 
   handlers:
     - name: Restart parameters-mandatory
-      service:
+      ansible.builtin.service:
         name: parameters-mandatory
         state: restarted
     - name: Restart parameters-optional.local
-      service:
+      ansible.builtin.service:
         name: parameters-optional.local
         state: restarted
     - name: Restart parameters-paste-req
-      service:
+      ansible.builtin.service:
         name: parameters-paste-req
         state: restarted
diff --git a/roles/wsgi_website/molecule/default/prepare.yml b/roles/wsgi_website/molecule/default/prepare.yml
index 7112f12c9130fab03c04f342c5a42f006914d07d..e5de092b6fb1b6d2d84afdcd4d6569499bd1a2b2 100644
--- a/roles/wsgi_website/molecule/default/prepare.yml
+++ b/roles/wsgi_website/molecule/default/prepare.yml
@@ -7,13 +7,13 @@
   tasks:
 
     - name: Initialise CA hierarchy
-      command: "gimmecert init"
+      ansible.builtin.command: "gimmecert init"
       args:
         creates: ".gimmecert/ca/level1.cert.pem"
         chdir: "tests/data/"
 
     - name: Generate server private keys and certificates
-      command:
+      ansible.builtin.command:
       args:
         chdir: "tests/data/"
         creates: ".gimmecert/server/{{ item.name }}.cert.pem"
@@ -33,7 +33,7 @@
           fqdn: wsgi-website
 
     - name: Set-up link to generated X.509 material
-      file:
+      ansible.builtin.file:
         src: ".gimmecert"
         dest: "tests/data/x509"
         state: link
@@ -45,16 +45,16 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
 
     - name: Remove the ss utility (see https://github.com/philpep/testinfra/pull/320)
-      file:
+      ansible.builtin.file:
         path: "/bin/ss"
         state: absent
 
@@ -64,37 +64,37 @@
   tasks:
 
     - name: Set-up /etc/hosts entries
-      lineinfile:
+      ansible.builtin.lineinfile:
         dest: /etc/hosts
         line: "{{ ansible_eth0.ipv4.address }} parameters-mandatory parameters-optional.local parameters-paste-req wsgi-website"
 
     - name: Install curl for testing redirects and webpage content
-      apt:
+      ansible.builtin.apt:
         name: curl
         state: present
 
     - name: Install swaks for testing mail forwarding
-      apt:
+      ansible.builtin.apt:
         name: swaks
         state: present
 
     - name: Install net-tools for testing sockets
-      apt:
+      ansible.builtin.apt:
         name: net-tools
         state: present
 
     - name: Install Postfix for testing mail forwarding (Exim4 not covered)
-      apt:
+      ansible.builtin.apt:
         name: postfix
         state: present
 
     - name: Install procmail for consistency with mail_server and mail_forwarder roles
-      apt:
+      ansible.builtin.apt:
         name: procmail
         state: present
 
     - name: Update Postfix configuration
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/postfix/main.cf
         regexp: "^{{ item.key }}"
         line: "{{ item.value }}"
@@ -106,7 +106,7 @@
         - Restart Postfix
 
     - name: Direct all mails from the root account to vagrant
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/aliases
         regexp: "^root"
         line: "root: vagrant"
@@ -115,12 +115,12 @@
         - Generate aliases database
 
     - name: Set-up group for an additional user
-      group:
+      ansible.builtin.group:
         name: user
         state: present
 
     - name: Set-up additional user for testing mail delivery
-      user:
+      ansible.builtin.user:
         name: user
         group: user
         shell: /bin/bash
@@ -128,11 +128,11 @@
   handlers:
 
     - name: Restart Postfix
-      service:
+      ansible.builtin.service:
         name: postfix
         state: restarted
 
     - name: Generate aliases database  # noqa no-changed-when
-      command: "/usr/bin/newaliases"
+      ansible.builtin.command: "/usr/bin/newaliases"
       # [no-changed-when] Commands should not change things if nothing needs doing
       #   Does not matter in test prepare stage.
diff --git a/roles/wsgi_website/tasks/main.yml b/roles/wsgi_website/tasks/main.yml
index d2d9a8f521a4767f6112386b2a7e8094a7c33ccd..bc3d8493041e42bbf38218b8ecc5ef5e791c310c 100644
--- a/roles/wsgi_website/tasks/main.yml
+++ b/roles/wsgi_website/tasks/main.yml
@@ -1,23 +1,23 @@
 ---
 
 - name: Create WSGI website group
-  group:
+  ansible.builtin.group:
     name: "{{ user }}"
     gid: "{{ uid | default(omit) }}"
     state: present
 
 - name: Create WSGI website admin user
-  user:
+  ansible.builtin.user:
     name: "{{ admin }}"
     uid: "{{ admin_uid | default(omit) }}"
     group: "{{ user }}"
-    shell: /bin/bash
+    ansible.builtin.shell: /bin/bash
     createhome: true
     home: "{{ home }}"
     state: present
 
 - name: Set-up directory for storing user profile configuration files
-  file:
+  ansible.builtin.file:
     path: "{{ home }}/.profile.d"
     state: directory
     owner: "{{ admin }}"
@@ -25,7 +25,7 @@
     mode: "0750"
 
 - name: Deploy profile configuration file for auto-activating the virtual environment
-  copy:
+  ansible.builtin.copy:
     src: "profile_virtualenv.sh"
     dest: "{{ home }}/.profile.d/virtualenv.sh"
     owner: root
@@ -33,7 +33,7 @@
     mode: "0640"
 
 - name: Deploy profile configuration file for setting environment variables
-  template:
+  ansible.builtin.template:
     src: "environment.sh.j2"
     dest: "{{ home }}/.profile.d/environment.sh"
     owner: root
@@ -41,7 +41,7 @@
     mode: "0640"
 
 - name: Create WSGI website user
-  user:
+  ansible.builtin.user:
     name: "{{ user }}"
     uid: "{{ uid | default(omit) }}"
     group: "{{ user }}"
@@ -53,10 +53,10 @@
     # This is a workaround for a rather stupid bug that Debian seems
     # uninterested to backport -
     # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865762
-    shell: /bin/sh
+    ansible.builtin.shell: /bin/sh
 
 - name: Add nginx user to website group
-  user:
+  ansible.builtin.user:
     name: www-data
     groups: "{{ user }}"
     append: true
@@ -66,7 +66,7 @@
 # Ownership set to root so Postfix would not check if correct user owns the
 # file.
 - name: Set-up forwarding for mails delivered to local application user/admin
-  template:
+  ansible.builtin.template:
     src: "forward.j2"
     dest: "{{ home }}/.forward"
     owner: root
@@ -74,7 +74,7 @@
     mode: "0640"
 
 - name: Install extra packages for website
-  apt:
+  ansible.builtin.apt:
     name: "{{ packages }}"
     state: present
   register: install_extra_packages
@@ -82,7 +82,7 @@
     - Restart WSGI services
 
 - name: Retrieve requested Python interpreter version
-  command:
+  ansible.builtin.command:
     argv:
       - "{{ python_interpreter }}"
       - "-c"
@@ -91,7 +91,7 @@
   register: python_interpreter_version
 
 - name: Retrieve virtual environment Python interpreter version (if initialised)
-  command:
+  ansible.builtin.command:
     argv:
       - "{{ home }}/virtualenv/bin/python"
       - "-c"
@@ -102,7 +102,7 @@
   register: virtualenv_python_version
 
 - name: Retrieve virtual environment prompt
-  command:
+  ansible.builtin.command:
     argv:
       - "bash"
       - "-c"
@@ -112,7 +112,7 @@
   register: current_virtualenv_prompt
 
 - name: Remove virtual environment in case of mismatches
-  file:
+  ansible.builtin.file:
     path: "{{ home }}/virtualenv"
     state: absent
   when: |
@@ -123,7 +123,7 @@
     - Restart WSGI services
 
 - name: Create directory for storing the Python virtual environment
-  file:
+  ansible.builtin.file:
     path: "{{ home }}/virtualenv"
     state: directory
     owner: "{{ admin }}"
@@ -131,14 +131,14 @@
     mode: "02750"
 
 - name: Create Python virtual environment
-  command: '/usr/bin/virtualenv --python "{{ python_interpreter }}" --prompt "{{ virtualenv_prompt }}" "{{ home }}/virtualenv"'
+  ansible.builtin.command: '/usr/bin/virtualenv --python "{{ python_interpreter }}" --prompt "{{ virtualenv_prompt }}" "{{ home }}/virtualenv"'
   args:
     creates: "{{ home }}/virtualenv/bin/{{ python_interpreter | basename }}"
   become: true
   become_user: "{{ admin }}"
 
 - name: Configure project directory for the Python virtual environment
-  template:
+  ansible.builtin.template:
     src: "venv_project.j2"
     dest: "{{ home }}/virtualenv/.project"
     owner: "{{ admin }}"
@@ -146,7 +146,7 @@
     mode: "0640"
 
 - name: Deploy virtualenv wrapper
-  template:
+  ansible.builtin.template:
     src: "venv_exec.j2"
     dest: "{{ home }}/virtualenv/bin/exec"
     owner: "{{ admin }}"
@@ -154,7 +154,7 @@
     mode: "0750"
 
 - name: Set-up directory for storing requirements file for upgrade checks
-  file:
+  ansible.builtin.file:
     path: "{{ pip_check_requirements_upgrades_directory }}/{{ fqdn }}"
     state: directory
     owner: root
@@ -162,7 +162,7 @@
     mode: "0750"
 
 - name: Deploy WSGI requirements files for upgrade checks
-  template:
+  ansible.builtin.template:
     src: "{{ item }}.j2"
     dest: "{{ pip_check_requirements_upgrades_directory }}/{{ fqdn }}/{{ item }}"
     owner: root
@@ -173,7 +173,7 @@
     - wsgi_requirements.txt
 
 - name: Deploy Gunicorn requirements file for installation purposes
-  template:
+  ansible.builtin.template:
     src: "wsgi_requirements.txt.j2"
     dest: "{{ home }}/.wsgi_requirements.txt"
     owner: "{{ admin }}"
@@ -183,7 +183,7 @@
 - name: Install Gunicorn via requirements file
   become: true
   become_user: "{{ admin }}"
-  pip:
+  ansible.builtin.pip:
     requirements: "{{ home }}/.wsgi_requirements.txt"
     state: present
     virtualenv: "{{ home }}/virtualenv"
@@ -194,7 +194,7 @@
 - name: Install additional packages in Python virtual environment
   become: true
   become_user: "{{ admin }}"
-  pip:
+  ansible.builtin.pip:
     name: "{{ virtualenv_packages }}"
     state: present
     virtualenv: "{{ home }}/virtualenv"
@@ -204,7 +204,7 @@
     - Restart WSGI services
 
 - name: Deploy systemd socket configuration for website
-  template:
+  ansible.builtin.template:
     src: "systemd_wsgi_website.socket.j2"
     dest: "/etc/systemd/system/{{ fqdn }}.socket"
     owner: root
@@ -216,7 +216,7 @@
     - Restart WSGI services
 
 - name: Deploy systemd service configuration for website
-  template:
+  ansible.builtin.template:
     src: "systemd_wsgi_website.service.j2"
     dest: "/etc/systemd/system/{{ fqdn }}.service"
     owner: root
@@ -228,13 +228,13 @@
     - Restart WSGI services
 
 - name: Enable the website service
-  service:
+  ansible.builtin.service:
     name: "{{ fqdn }}"
     enabled: true
     state: started
 
 - name: Create directory where static files can be served from
-  file:
+  ansible.builtin.file:
     path: "{{ home }}/htdocs/"
     state: directory
     owner: "{{ admin }}"
@@ -242,7 +242,7 @@
     mode: "02750"
 
 - name: Deploy nginx TLS private key for website
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/private/{{ fqdn }}_https.key"
     content: "{{ https_tls_key }}"
     owner: root
@@ -252,7 +252,7 @@
     - Restart nginx
 
 - name: Deploy nginx TLS certificate for website
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/certs/{{ fqdn }}_https.pem"
     content: "{{ https_tls_certificate }}"
     owner: root
@@ -262,7 +262,7 @@
     - Restart nginx
 
 - name: Deploy configuration file for checking certificate validity via cron
-  copy:
+  ansible.builtin.copy:
     content: "/etc/ssl/certs/{{ fqdn }}_https.pem"
     dest: "/etc/check_certificate/{{ fqdn }}_https.conf"
     owner: root
@@ -270,7 +270,7 @@
     mode: "0644"
 
 - name: Deploy nginx configuration file for website
-  template:
+  ansible.builtin.template:
     src: "nginx_site.j2"
     dest: "/etc/nginx/sites-available/{{ fqdn }}"
     owner: root
@@ -281,7 +281,7 @@
     - Restart nginx
 
 - name: Enable nginx website
-  file:
+  ansible.builtin.file:
     src: "/etc/nginx/sites-available/{{ fqdn }}"
     dest: "/etc/nginx/sites-enabled/{{ fqdn }}"
     state: link
@@ -289,7 +289,7 @@
     - Restart nginx
 
 - name: Set-up empty list of WSGI services to restart
-  set_fact:
+  ansible.builtin.set_fact:
     wsgi_services_to_restart: []
   when: "wsgi_services_to_restart is not defined"
   tags:
@@ -299,7 +299,7 @@
   # [no-handler] Tasks that run when changed should likely be handlers
   #   This specific task is used in order to work around inability of Ansible
   #   to provide properly parametrised handlers for reusable roles.
-  set_fact:
+  ansible.builtin.set_fact:
     wsgi_services_to_restart: "{{ wsgi_services_to_restart + [fqdn] }}"
   when: |
     fqdn not in wsgi_services_to_restart and
@@ -313,7 +313,7 @@
     - handlers
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers
diff --git a/roles/xmpp_server/handlers/main.yml b/roles/xmpp_server/handlers/main.yml
index 979e1c01ae4bc65689edacb90da2eee13524c9a7..2dd44f736f8c7c4f50bfd52dff2a46746f61025c 100644
--- a/roles/xmpp_server/handlers/main.yml
+++ b/roles/xmpp_server/handlers/main.yml
@@ -1,6 +1,6 @@
 ---
 
 - name: Restart Prosody
-  service:
+  ansible.builtin.service:
     name: prosody
     state: restarted
diff --git a/roles/xmpp_server/molecule/default/cleanup.yml b/roles/xmpp_server/molecule/default/cleanup.yml
index c99ee79c29bc84b49f955fbcdf8734cda064bc64..32ba90b5c0f67eede47dee009ed76de8acd3ea27 100644
--- a/roles/xmpp_server/molecule/default/cleanup.yml
+++ b/roles/xmpp_server/molecule/default/cleanup.yml
@@ -7,7 +7,7 @@
   tasks:
 
     - name: Remove X.509 material
-      file:
+      ansible.builtin.file:
         path: "{{ item }}"
         state: absent
       with_items:
diff --git a/roles/xmpp_server/molecule/default/prepare.yml b/roles/xmpp_server/molecule/default/prepare.yml
index 2812c9662ec7594f387b3ebe317f216fe175c96a..7764229376c314fceaaebb366e191d113b220edf 100644
--- a/roles/xmpp_server/molecule/default/prepare.yml
+++ b/roles/xmpp_server/molecule/default/prepare.yml
@@ -7,13 +7,13 @@
   tasks:
 
     - name: Initialise CA hierarchy
-      command: "gimmecert init"
+      ansible.builtin.command: "gimmecert init"
       args:
         creates: ".gimmecert/ca/level1.cert.pem"
         chdir: "tests/data/"
 
     - name: Generate server private keys and certificates
-      command:
+      ansible.builtin.command:
       args:
         chdir: "tests/data/"
         creates: ".gimmecert/server/{{ item.name }}.cert.pem"
@@ -40,7 +40,7 @@
             - conference.domain3
 
     - name: Set-up link to generated X.509 material
-      file:
+      ansible.builtin.file:
         src: ".gimmecert"
         dest: "tests/data/x509"
         state: link
@@ -52,24 +52,24 @@
   tasks:
 
     - name: Install python for Ansible
-      raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
+      ansible.builtin.raw: test -e /usr/bin/python3 || (apt -y update && apt install -y python3-minimal)
       become: true
       changed_when: false
 
     - name: Update all caches to avoid errors due to missing remote archives
-      apt:
+      ansible.builtin.apt:
         update_cache: true
       changed_when: false
 
     - name: Install tools for testing
-      apt:
+      ansible.builtin.apt:
         name:
           - gnutls-bin
           - nmap
         state: present
 
     - name: Use name provided via CLI when running STARTTLS handshake for XMPP via nmap
-      replace:
+      ansible.builtin.replace:
         path: "/usr/share/nmap/nselib/sslcert.lua"
         regexp: "host\\.name\\)"
         replace: "host.targetname)"
@@ -80,7 +80,7 @@
   tasks:
 
     - name: Enable TLSv1.0+ in global OpenSSL configuration file in order to be able to test the web_server_tls_protocols parameter
-      blockinfile:
+      ansible.builtin.blockinfile:
         path: "/etc/ssl/openssl.cnf"
         block: |
           [openssl_init]
@@ -98,7 +98,7 @@
         state: present
 
     - name: Set-up the hosts file
-      lineinfile:
+      ansible.builtin.lineinfile:
         path: /etc/hosts
         regexp: "^{{ item.key }}"
         line: "{{ item.key }} {{ item.value }}"
@@ -118,12 +118,12 @@
   tasks:
 
     - name: Install tool for testing TCP connectivity
-      apt:
+      ansible.builtin.apt:
         name: hping3
         state: present
 
     - name: Deploy CA certificate
-      copy:
+      ansible.builtin.copy:
         src: tests/data/x509/ca/level1.cert.pem
         dest: /usr/local/share/ca-certificates/testca.crt
         owner: root
@@ -133,28 +133,28 @@
         - Update CA certificate cache
 
     - name: Install console-based XMPP client (for interactive testing)
-      apt:
+      ansible.builtin.apt:
         name: mcabber
         state: present
 
     - name: Install console-based XMPP tool (for non-interactive testing)
-      apt:
+      ansible.builtin.apt:
         name: go-sendxmpp
         state: present
 
     - name: Create dedicated group for testing
-      group:
+      ansible.builtin.group:
         name: user
         state: present
 
     - name: Create dedicated user for testing
-      user:
+      ansible.builtin.user:
         name: user
         group: user
-        shell: /bin/bash
+        ansible.builtin.shell: /bin/bash
 
     - name: Deploy mcabber configuration files
-      template:
+      ansible.builtin.template:
         src: tests/data/mcabber.cfg.j2
         dest: "~user/{{ item.jid }}.cfg"
         owner: user
@@ -185,7 +185,7 @@
   handlers:
 
     - name: Update CA certificate cache  # noqa no-changed-when
-      command: /usr/sbin/update-ca-certificates --fresh
+      ansible.builtin.command: /usr/sbin/update-ca-certificates --fresh
       # [no-changed-when] Commands should not change things if nothing needs doing
       #   Does not matter in test prepare stage.
 
@@ -202,7 +202,7 @@
   tasks:
 
     - name: Create LDAP accounts for testing
-      ldap_entry:
+      community.general.ldap_entry:
         dn: "{{ item.dn }}"
         objectClass: "{{ item.objectClass }}"
         attributes: "{{ item.attributes }}"
@@ -268,14 +268,14 @@
   tasks:
 
     - name: Install console-based XMPP tool (for non-interactive testing)
-      apt:
+      ansible.builtin.apt:
         name: "{{ sendxmpp_package }}"
         state: present
       vars:
         sendxmpp_package: "go-sendxmpp"
 
     - name: Deploy small Lua script for listing the enabled modules in Prosody
-      copy:
+      ansible.builtin.copy:
         src: list_prosody_modules.lua
         dest: "/usr/local/bin/list_prosody_modules.lua"
         owner: root
diff --git a/roles/xmpp_server/tasks/main.yml b/roles/xmpp_server/tasks/main.yml
index 6f344d9686dd1c5a062a5e845cd6eb85d11796ab..9eb00c7bdccdbdd96c02f1d7c0adb504ff73867c 100644
--- a/roles/xmpp_server/tasks/main.yml
+++ b/roles/xmpp_server/tasks/main.yml
@@ -4,7 +4,7 @@
 # ===================
 
 - name: Set-up the Debian backports repository
-  template:
+  ansible.builtin.template:
     src: backports.list.j2
     dest: /etc/apt/sources.list.d/backports.list
     owner: root
@@ -18,12 +18,12 @@
   #   change when changing distro version etc), we have to use
   #   template instead, but this also means we need to trigger the apt
   #   cache reload by hand.
-  apt:
+  ansible.builtin.apt:
     update_cache: true
   when: backports_repository_configuration.changed
 
 - name: Install additional Prosody dependencies
-  apt:
+  ansible.builtin.apt:
     name:
       - lua-ldap
       - prosody-modules
@@ -32,20 +32,20 @@
     - Restart Prosody
 
 - name: Install Prosody
-  apt:
+  ansible.builtin.apt:
     name: prosody
     state: present
   notify:
     - Restart Prosody
 
 - name: Allow Prosody user to traverse the directory with TLS private keys
-  user:
+  ansible.builtin.user:
     name: prosody
     append: true
     groups: ssl-cert
 
 - name: Deploy XMPP TLS private key
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/private/{{ ansible_fqdn }}_xmpp.key"
     content: "{{ xmpp_tls_key }}"
     owner: root
@@ -55,7 +55,7 @@
     - Restart Prosody
 
 - name: Deploy XMPP TLS certificate
-  copy:
+  ansible.builtin.copy:
     dest: "/etc/ssl/certs/{{ ansible_fqdn }}_xmpp.pem"
     content: "{{ xmpp_tls_certificate }}"
     owner: root
@@ -65,7 +65,7 @@
     - Restart Prosody
 
 - name: Generate the XMPP server Diffie-Hellman parameter
-  openssl_dhparam:
+  community.crypto.openssl_dhparam:
     owner: root
     group: prosody
     mode: "0640"
@@ -75,7 +75,7 @@
     - Restart Prosody
 
 - name: Deploy configuration file for checking certificate validity via cron
-  copy:
+  ansible.builtin.copy:
     content: "/etc/ssl/certs/{{ ansible_fqdn }}_xmpp.pem"
     dest: "/etc/check_certificate/{{ ansible_fqdn }}_xmpp.conf"
     owner: root
@@ -83,7 +83,7 @@
     mode: "0644"
 
 - name: Deploy script for validating Prosody certificate
-  copy:
+  ansible.builtin.copy:
     src: "check_prosody_certificate.sh"
     dest: "/usr/local/bin/check_prosody_certificate.sh"
     owner: root
@@ -91,7 +91,7 @@
     mode: "0755"
 
 - name: Set-up crontab task that runs the Prosody certificate checker script once a day
-  copy:
+  ansible.builtin.copy:
     src: "cron_check_prosody_certificate"
     dest: "/etc/cron.d/check_prosody_certificate"
     owner: root
@@ -99,7 +99,7 @@
     mode: "0644"
 
 - name: Deploy LDAP client configuration (for validating LDAP server certificate)
-  copy:
+  ansible.builtin.copy:
     src: prosody_ldaprc
     dest: "/var/lib/prosody/.ldaprc"
     owner: root
@@ -109,7 +109,7 @@
     - Restart Prosody
 
 - name: Deploy Prosody configuration file
-  template:
+  ansible.builtin.template:
     src: "prosody.cfg.lua.j2"
     dest: "/etc/prosody/prosody.cfg.lua"
     owner: root
@@ -119,13 +119,13 @@
     - Restart Prosody
 
 - name: Enable and start Prosody service
-  service:
+  ansible.builtin.service:
     name: prosody
     state: started
     enabled: true
 
 - name: Deploy firewall configuration for XMPP server
-  copy:
+  ansible.builtin.copy:
     src: "ferm_xmpp.conf"
     dest: "/etc/ferm/conf.d/30-xmpp.conf"
     owner: root
@@ -135,7 +135,7 @@
     - Restart ferm
 
 - name: Explicitly run all handlers
-  include_tasks: ../handlers/main.yml
+  ansible.builtin.include_tasks: ../handlers/main.yml
   when: "run_handlers | default(False) | bool()"
   tags:
     - handlers