Changelog¶
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased¶
Highlights: Apache Solr runs on Debian, Ubuntu and RHEL 10 and supports Solr 9.11. Hosts that deploy the OWASP Core Rule Set with apache_httpd need apache_httpd__mod_security_coreruleset_version in their inventory, since the role no longer picks a release on its own and verifies the download against a checksum.
Breaking Changes¶
- role:apache_httpd: The role no longer hands everything below the document root to the web server user, so a hole in a web application can no longer rewrite the code of every site on the host. The roles that install an application set the owners they need. For content placed by hand that Apache has to write, give the writable directories to
apache(www-dataon Debian and Ubuntu) yourself. Removeapache_httpd__skip_document_root_chownfrom your inventory. - role:openvpn_server: The role requires OpenVPN 2.7 and installs or upgrades it from the OpenVPN repository, which the
openvpn_serverplaybook enables with the newrepo_openvpnrole. The upgrade restarts the OpenVPN service from within the package and drops every client, so run it in a maintenance window and restart the service once more afterwards, as the message at the end of the run says. The server refuses client certificates with an RSA key below 2048 bits, a SHA-1 signature or without the TLS Web Client Authentication key usage, and no longer accepts several clients with the same certificate; setopenvpn_server__duplicate_cn: truewhere clients share one. Clients that only speak TLS 1.2 and carry thetls-cipherline of the former example client config must drop that line. Removeopenvpn_server__dhandopenvpn_server__dh_skip_deployfrom your inventory. - role:apache_httpd:
apache_httpd__mod_security_coreruleset_versionhas no default anymore and accepts only the OWASP Core Rule Set releases the CRS project supports with security fixes, currently4.25.2,4.29.0and4.30.0. On hosts withapache_httpd__skip_mod_security_coreruleset: false, set it in the inventory, otherwise the run aborts. - role:apache_solr: Solr listens on
127.0.0.1only and gets 180 seconds to stop gracefully, as upstream ships it, instead of listening on all addresses and being killed after 15 seconds. Setapache_solr__http_bind_address: '0.0.0.0'for a Solr that other hosts have to reach. - role:bind: named validates DNSSEC by default, as the bind package does, and follows the system-wide crypto policy. Forged or broken answers for signed zones are answered with
SERVFAILinstead of being passed on. Theforward,static-stubandstubzones inbind__zonesare excluded from validation; list other internal zones below a signed domain or TLD inbind__dnssec_validate_except, or setbind__dnssec_validation: false. On RHEL 8 the role fails if it has zones to exclude, since BIND 9.11 cannot; setbind__dnssec_validation: falsethere (#355, #356). - role:system_update: On Debian and Ubuntu, the system update no longer updates the database of an AIDE installed by hand, since it also accepted changes that were pending before the update. On such hosts the daily AIDE mail now lists the files each update changed. Deploy the aide role to have its database updated after updates again.
- role:grav: The
grav:crontag is gone. Run the role with--tags gravto deploy the timers and their services, or with--tags grav:stateto enable or disable the timers. - role:firewall: With
firewall__firewall: 'fwbuilder', the default, the run aborts on a host that has neither/etc/fwb.shnorfirewall__fwbuilder_repo_url, before the role stops any firewall. Until nowfwb.servicefailed there and the host ran without a firewall. Deploy/etc/fwb.sh, setfirewall__fwbuilder_repo_url, or setfirewall__firewallto the firewall the host uses. - role:chrony: The role takes effect on Debian and Ubuntu, where chronyd reads
/etc/chrony/chrony.confand ignored the/etc/chrony.confthe role deployed, so these hosts synchronised with the distribution's default pools until now. As on the Red Hat family, chronyd uses only the sources fromchrony__ntp_poolsandchrony__ntp_servers, without the distribution's pools, DHCP sources or/etc/chrony/sources.d. Without either of them, chronyd synchronises withntp.metas.ch. - role:monitoring_plugins: The source install downloads the Python dependencies on the Ansible controller, which therefore needs pip for the Python that runs Ansible and access to PyPI; the targets no longer need Internet access.
- role:kernel_modules: The
tunkernel module is blocked by default (CVE-2026-81000, RHSB-2026-011). This stops OpenVPN, WireGuard in userspace, rootless Podman and Docker networking and libvirt VM networking after the next reboot, which the role requests on hosts wheretunis loaded. Before running the role, addkernel_modules__modules__host_var: [{name: 'tun', enabled: true}]to the inventory of every such host. Rootful Docker and Podman with bridge networking are not affected. - role:grafana:
grafana__users_case_insensitive_loginis gone; remove it from your inventory. Grafana has ignored the setting since v11.0.0 and always matches logins case-insensitively. - role:system_update:
system_update__pre_update_codeandsystem_update__post_update_codenow also run in the daily security lane on Rocky, around the transaction that installs the hot-fixes, where until now only the weekly lane ran them. Setsystem_update__security_pre_update_code: ''andsystem_update__security_post_update_code: ''to keep the security lane free of it, or set either to a codeblock of its own to have the two lanes do different things. - role:wordpress: The vHost file is named after the host of
wordpress__url, for examplewordpress.example.com.80.conf, instead ofwordpress.conf. Remove the old file withrm -f /etc/httpd/sites-{enabled,available}/wordpress.confand reload httpd, otherwise Apache may keep serving the site from it. - role:wordpress: The WordPress core,
wp-config.phpandwp-content/mu-pluginsbelong toroot, so a vulnerable plugin can no longer modify them; plugins and themes can still be installed from the web interface. The core is updated bywordpress-core-minor-update-<instance>.timer(minor releases) and--tags wordpress:updateinstead of by WordPress itself. After a permalink change in the web interface, add the displayed rewrite rules to.htaccessby hand. - role:wordpress: The REST API is restricted to logged-in users by the Disable WP REST API plugin, which replaces Disable REST API (
disable-json-api) and also blocks the routes of plugins installed later. A front-end feature that calls the REST API without a login, such as some contact forms, needs an exception in code. - role:wordpress: Application passwords are switched off, since they bypass a second factor. Set
wordpress__application_passwords_enabled: truefor integrations that use them, such as the WordPress mobile app. - role:wordpress: WordPress honours
X-Forwarded-Foronly from the proxies inwordpress__trusted_proxiesand ignoresX-Forwarded-Host, which any client could set before. Behind a reverse proxy, list its IP address. - role:wordpress:
wordpress__urlmust include the scheme, for examplehttps://wordpress.example.com. The role sets the site address (homeandsiteurl) to it on every run, so the login cookie of anhttps://site carries theSecureflag, and an address changed in the WordPress settings is set back. - role:icinga2_agent: If the agent cannot get a PKI ticket from the Icinga2 master, the run aborts and names the cause and the fix. Until now the role set the agent up anyway, which also replaced the signed certificate of an agent that was already connected with an unsigned one. If you sign agent certificates on the master by hand, or do not set
icinga2_agent__icinga2_api_user_login, seticinga2_agent__skip_pki_ticket: true. - role:dnf_makecache:
dnf_makecache__service_enabledanddnf_makecache__service_stateare gone; remove them from your inventory. The role only managesdnf-makecache.timernow, sincednf-makecache.servicecannot be enabled at boot and only runs when the timer triggers it.dnf_makecache__service_enablednever had an effect, but a run against an unchanged host reported a change for it. A host that setdnf_makecache__service_state: 'started'no longer runsdnf makecacheon every run of the role. Usednf_makecache__timer_enabledanddnf_makecache__timer_statefor the periodic cache refresh. - role:kibana: The session cookie always carries the
Secureflag, also behind a reverse proxy that terminates TLS, where Kibana left the flag off. A Kibana that browsers reach over plain HTTP no longer logs anyone in untilkibana__xpack_security_secure_cookies: falseis set. Removexpack.security.secureCookiesfromkibana__rawif you set it there. - role:icingaweb2: The session and remember-me cookies always carry the
Secureflag, also behind a reverse proxy that terminates TLS and talks plain HTTP to IcingaWeb2, where IcingaWeb2 left the flag off. An IcingaWeb2 that browsers reach over plain HTTP no longer logs anyone in untilicingaweb2__cookie_secure: falseis set. - role:apache_httpd: Every entry in
apache_httpd__htpasswd__*_varneeds thepathsubkey, because the username and the path together identify an entry. Until now, entries with the same username but a differentpathwere collapsed into one, so only the last file got the user; a user listed with different paths in group and host variables is now written to both files. On entries that relied on the default, setpath: '/etc/httpd/.htpasswd'(RedHat) orpath: '/etc/apache2/.htpasswd'(Debian and Ubuntu), otherwise the play fails with an error naming the entry. - role:postfix: On RHEL 10 the role deploys the compatibility level the distribution ships (
3.8) instead of the RHEL 8 / 9 value it applied everywhere. Postfix now matches TLS fingerprints with SHA-256 instead of MD5, evaluates the relay restrictions before the recipient restrictions, and uses the neutral wording in its postscreen log lines. Re-generate any peer fingerprint pinned as MD5 in a TLS policy table, and check log parsers keyed on the old postscreen wording. Setpostfix__compatibility_level: '2'to restore the previous behaviour. RHEL 8, RHEL 9 and Debian are unaffected. - role:login: The default umask in
/etc/login.defsis back to the022the distributions ship, instead of the027set since v7.0.0, so files that users create in a login session are readable by other local users again. Setlogin__login_defs_umask: '027'to keep the stricter value. - playbook:crypto_policy, playbook:kernel_modules, playbook:selinux: These playbooks run
postfix,mailto_rootandschedule_rebootbefore their own role, so that a change needing a reboot can request one.mailto_root__fromandmailto_root__toare therefore mandatory for them; a host set up withsetup_basicalready has both. To keep a playbook as it was, set<playbook>__skip_postfix,<playbook>__skip_mailto_rootand<playbook>__skip_schedule_reboottotrue, for examplecrypto_policy__skip_schedule_reboot: true. - role:fail2ban: Removed
apache-404-matomofilter and jail. Theapache-404filter now matches all supported LogFormats including matomo and vhost_common. Removeapache-404-matomoentries fromfail2ban__filters__*_varandfail2ban__jails__*_varin your inventory and useapache-404instead. - role:fail2ban: Rename
fail2ban__jail_apache_404_ignoreregextofail2ban__filter_apache_404_ignoreregexin your inventory. The regular expressions land in theapache-404andapache-404-matomofilters, which both jails share, so the old name pointed at a jail that never carried the setting. The value itself is unchanged.
Added¶
- role:collabora: Add support for Collabora Online Enterprise 24.04.19, 26.04.3 and 26.04.4.
- role:collabora: Add support for Collabora Online Enterprise 25.04.13.
- role:collabora: Add support for Collabora Online CODE 26.04.5.
- playbook:setup_basic, role:monitoring_plugins: On the Red Hat family,
psi=1is put on the kernel command line, so the psi-* monitoring plugins report pressure stall information instead of finding none; each host reboots once at its maintenance window, andsetup_basic__skip_bootloaderskips it. - role:apache_httpd:
lfops__trusted_proxieslists the reverse proxies in front of a host, and Apache then logs the client fromX-Forwarded-Forinstead of the proxy in the access and the error log. - role:apache_httpd: Creates a self-signed placeholder for every certificate in
apache_httpd__placeholder_certificates__*_varthat does not exist yet, so a TLS vHost starts before its certificate is issued; the playbooks fill the list fromacme_sh__certificates. acme_shcan run as the last role of every playbook withapache_httpd, so a fresh host gets its Let's Encrypt certificates in a single run; enable it with the playbook'sacme_shskip variable (apache_httpdand thesetup_*playbooks withapache_httpd).- role:repo_openvpn, playbook:repo_openvpn: Add a role and playbook that deploy the OpenVPN 2.7 release repository of the OpenVPN community on RHEL 8, 9 and 10, where EPEL ships outdated OpenVPN versions.
- role:openvpn_server: Add
meta/argument_specs.ymldeclaring the user-facing variables, so role-entry validation catches type mismatches and invalid values before any task runs. - role:apache_solr: Supports Solr 10, deployed as a single instance without ZooKeeper, as with Solr 9.
- role:apache_solr: Supports Debian 12 and 13, RHEL 10 and Ubuntu 22.04, 24.04 and 26.04, with the Java the Solr version needs installed from the distribution.
- role:bind: Add
meta/argument_specs.ymldeclaring the user-facing variables, so role-entry validation catches type mismatches and invalid values before any task runs. - role:duplicity: The backup includes the data of the applications LFOps deploys by default:
/data,/srv,/var/lib/grafana,/var/lib/icinga2(including the Icinga2 CA),/var/lib/shiny-server,/var/lib/turn,/var/mail,/var/named,/var/solr/data,/var/spool/mailand/var/www(without the repository mirrors). Hosts without these directories are not affected. On hosts with large data, for example VM images in/data, check the backup size or set the path tostate: 'absent'. - playbook:setup_basic: Installs AIDE on every host, which checks file integrity twice a day and after every boot; skip it with
setup_basic__skip_aide. - role:aide, playbook:aide: Add a role and playbook that install AIDE on Debian 12 and 13, RHEL 8, 9 and 10 and Ubuntu 22.04, 24.04 and 26.04 as the CIS benchmarks recommend, leaving
aidecheck.servicefailed on any finding and keeping the database in step withsystem_updateandunattended-upgrades. - role:lynis, playbook:lynis, playbook:setup_basic: Add a role and playbook that install Lynis on every
setup_basichost and audit it once a day for the lynis-logfile monitoring plugin, with findings accepted throughlynis__skip_testsinstead of a hand-edited/etc/lynis/custom.prf. - role:repo_monitoring_plugins:
--tags repo_monitoring_plugins:removeremoves the repository and its signing key. - role:grafana:
grafana__preinstall_auto_updatecontrols whether Grafana updates its preinstalled plugins on every start. - role:icingaweb2:
icingaweb2__cookie_pathsets the path of the session and remember-me cookies, for example/. - role:collabora: Add support for Collabora Online CODE 26.04.4.
- role:wordpress: Entries in
wordpress__pluginsacceptenabled: false, which keeps a plugin installed but deactivated. - role:system_update: The role's inventory variables are type-checked when it starts, so a mistyped value fails the run right away instead of surfacing further in as a confusing error.
- role:wordpress: Several WordPress instances can share a host as pseudo hosts in the inventory, under different host names as well as under different paths of one host name, such as
https://example.com/blog. - role:fail2ban: The
wordpress-loginfilter andz10-wordpress-loginjail ban IPs with too many failed WordPress logins, on the host whose Apache logs the visitor's address. - role:rstudio_server, playbook:rstudio_server: Add a role and playbook to install RStudio Server Open Source, the browser-based R development environment. Users sign in with their account on the host and have to be a member of a group to be let in at all, the PAM profile covers directory users where the vendor's covers local ones only, and the R sessions can be given a memory and process budget.
- role:shiny_server, playbook:setup_shiny_server: Add a role and playbook to install Shiny Server Open Source and serve several tenants from one host, each with its own hostname, password file, R worker and system account, behind an Apache httpd reverse proxy that also passes the authenticated user into the application. Shiny Server itself listens on the loopback only, because it authenticates nobody and hands every client header to the application.
- role:r, playbook:r: Add a role and playbook to install R and pandoc, point R at the Posit Public Package Manager so that CRAN packages arrive as prebuilt binaries instead of being compiled on the host, and install the CRAN packages an application needs.
- role:borg_local, role:icinga2_master, role:nextcloud, role:schedule_reboot, role:tools:
icinga2_master__downtime_api_usercreates an Icinga2 API user that may only schedule and remove downtimes, and the roles that set a downtime around a backup, a Nextcloud update or a reboot use it unless their own*__icinga2_api_user_loginis set. - role:crypto_policy, role:kernel_modules, role:selinux: A change that only takes effect after a reboot requests one at the maintenance window instead of being left to the operator to notice: a switched crypto policy, a blocked kernel module that is still loaded, and switching SELinux on or off. Where the reboot mechanism is not deployed, the role reports the pending reboot as before.
lfops__reboot_nowperforms it in the same run. - Every playbook prints the manual steps a run leaves to the operator as one block directly above the
PLAY RECAP, collected from all roles of the play instead of scattered over its output. The roles keep printing their message where it occurs as well, so a role used outside this collection still reports it. - role:bootloader: New role that manages the kernel command line, for parameters that only take effect at boot time such as
psi=1. Options are applied to every boot entry of the host, on the Red Hat family withgrubbyand on Debian and Ubuntu through a GRUB drop-in of its own. A changed command line requests a reboot at the maintenance window instead of rebooting right away, or applies it during the run whenlfops__reboot_nowis set, and a--checkrun reports what it would change without touching the host. - role:fail2ban: The
fail2ban:configuretag deploys the actions, filters and jails without touching the packages. - role:fail2ban: Add
meta/argument_specs.ymldeclaring the user-facing variables, so role-entry validation catches type mismatches and invalid values before any task runs.
Changed¶
- role:apache_httpd: Apache answers requests for PHP files that do not exist with 404 itself instead of passing them to PHP-FPM, so scanners no longer tie up pool workers or fill the error log.
- playbook:setup_basic: Checks the variables of all its roles, the compiled firewall in the Firewall Builder repository and the reachability of the Icinga2 master before it changes anything on the host, so a missing prerequisite no longer aborts the run halfway through, after SSH was already hardened.
- Handlers that a role notified before a later task failed run anyway, so a changed configuration reaches the running service; until now it stayed inactive, also across later runs, which reported no change (all playbooks).
- playbook:acme_sh: No longer runs the
appsrole, since theacme_shrole installs curl, openssl and tar itself. - role:acme_sh: Installs a certificate again when the installed file differs from the one acme.sh issued, which replaces a placeholder that an aborted run left behind.
- role:apache_solr: Downloads Solr from the Apache CDN, which is much faster than the Apache archive, and falls back to the archive for releases the CDN no longer carries.
- role:apache_solr: The run aborts for a user whose password equals the username, since Solr 9.11 and newer reject such logins.
- role:apache_solr: A role holding the
allpermission is allowed every request, also one that a more specific permission of another role matches first. - role:apache_solr: The Solr program files belong to
root, as with Solr's own installation script, and files that Solr creates are no longer readable by other users. - Downloads from the Internet, such as release tarballs, GPG keys, git clones, GitHub release lookups and package installations, are retried up to three times, so a brief outage of a download source or package repository no longer aborts the run (all roles).
- role:apache_httpd: Bump the OWASP Core Rule Set to 4.30.0.
- role:apache_httpd: The OWASP Core Rule Set is downloaded on the Ansible controller, so the target no longer needs access to GitHub.
- role:monitoring_plugins: On Linux, the role no longer stops the Icinga2 agent while it deploys the plugins, so a run no longer interrupts the monitoring of the host.
- role:icinga2_agent: The role runs
icinga2 node setupand restarts the agent only when the agent needs a new certificate or its settings changed, instead of on every run. - LFOps requires community.general 7.0.0 or newer (still below 9.0.0), which
ansible-galaxy collection install linuxfabrik.lfopspulls in, while a manually maintained collection list has to be raised. - plugin:bitwarden_item: The lookup syncs the Bitwarden vault once per Ansible run instead of every 60 seconds, which makes runs with many lookups considerably faster, since each sync makes
bw servelist the whole vault. Before it creates a missing item, it syncs again, so an item created elsewhere during the run is not created a second time. - role:icingaweb2_module_generictts: Downloads the module from Linuxfabrik, who maintain it since Icinga archived the original repository. The tarballs of v2.1.0 are identical.
- role:duplicity:
/var/lib/aideis backed up by default, so that the AIDE database can be compared with a copy outside the host. Hosts without AIDE are not affected. - role:monitoring_plugins: The source install removes plugins that an earlier run deployed and the checked-out version no longer carries.
- role:monitoring_plugins: The source install deploys the dependency versions pinned in the monitoring-plugins lockfiles and, for a release, the Linuxfabrik library release they pin, instead of the newest versions of both.
- playbook:icinga2_agent, playbook:setup_basic, playbook:setup_icinga2_master: The Monitoring Plugins repository is only registered for
monitoring_plugins__install_method: 'package'. - role:fail2ban: The
portscanjail no longer bans TCP scans that send no plain SYN, such as FIN, NULL, Xmas and ACK scans, since they find no open port on a stateful firewall. - role:grafana: Grafana no longer updates its preinstalled plugins on every start, so datasources such as InfluxDB and Prometheus no longer disappear from the web interface when the plugin download server is unreachable.
- role:grafana:
grafana.inifollows the file that current Grafana packages ship, so deploying it only changes the settings LFOps manages. As a side effect, recording rules time out after 30 seconds instead of 10. - plugin:bitwarden_item, module:bitwarden_item: A run against a vault that contains no items at all aborts instead of creating the first one, because
bw servebriefly reports an empty vault after every sync (bitwarden/clients#23283). - role:repo_postgresql: The PostgreSQL version repositories take precedence over the distribution's packages of the same name, so on RHEL 10 an install or update no longer switches a PostgreSQL server from the PGDG build to the AppStream build, which uses a different file layout.
- role:apache_httpd: Responses of type
text/markdownare compressed like HTML, so the Markdown versions of pages that CMSs such as Grav hand to AI agents no longer go out uncompressed. - role:grav: The README lists setting
session.secureas a manual step behind a reverse proxy that terminates TLS, where Grav sends its session cookies without theSecureflag. - role:gitlab_ce:
gitlab_ce__rb_external_urlsupportshttps://behind a reverse proxy that terminates TLS, and the README recommends it there. Withhttp://, GitLab's session cookie goes out without theSecureflag. - role:grafana: The login cookie carries the
Secureflag whengrafana__root_urlis anhttps://URL.grafana__cookie_secureoverrides this. - playbook:setup_basic: The mail and reboot roles run before the security roles, so a first run against a fresh host files the reboot request that a changed crypto policy, SELinux state or kernel module blocklist needs. Until now the reboot mechanism was deployed further down the playbook and such a change could only be reported to the operator.
- role:network: The reminder that NetworkManager may have to be restarted by hand is printed only when a connection profile actually changed, instead of on every run.
Removed¶
- role:github_project_createrepo:
github_project_createrepo__webserver_useris gone, since the web server no longer gets an ACL entry; remove it from your inventory.
Fixed¶
- role:icingaweb2_module_grafana:
graphs.inino longer keeps the graphs of monitoring plugins that were removed or renamed upstream. - role:uptimerobot: Alert contacts past the first 50 are found, so
alert_contactsof a monitor can name them anduptimerobot_alert_contact_infolists all of them. - role:uptimerobot: Port monitors with
sub_typehttps,ftp,smtp,pop3orimapare created instead of rejected by UptimeRobot, a changedsub_typetakes effect on an existing monitor, and a port monitor with asub_typeno longer reports a change on every run. - role:php:
--tags php:inialso deploys the PHP-FPM pools, so a changedphp__ini_memory_limit__*_var,php__ini_max_execution_time__*_varand the like take effect in PHP-FPM, not only on the command line. - role:chrony: Without
chrony__ntp_poolsorchrony__ntp_serversin the inventory, chronyd synchronises withntp.metas.ch, the time server of the Swiss Federal Institute of Metrology, instead of running without a time source. If both are set to[], the role aborts. - role:icingaweb2: PHP gets a
memory_limitof 256M instead of 128M, so the CSV and JSON exports, such as History > Event Overview, handle about twice as many rows before they break off with "Allowed memory size exhausted". Override it withphp__ini_memory_limit__group_var/php__ini_memory_limit__host_var. - role:nextcloud: The README documents the app states correctly.
state: 'present'installs an app but leaves it disabled; usestate: 'enabled'to switch on an app, including the apps the role disables by default, such asactivity,notificationsandsystemtags. - role:icingaweb2_module_grafana: With JWT authentication, the Grafana graphs in IcingaWeb2 no longer switch to the Grafana login after 30 seconds. The token stays valid for 3 days; adjust with
icingaweb2_module_grafana__auth_jwt__expires. - playbook:uptimerobot: The playbook runs as a normal user on the Ansible controller, without
--become. Until now it aborted because it tried to write/var/log/linuxfabrik-lfops.logon the controller, and with--becomeit could not find the API key in~/.uptimerobot. - role:repo_epel: On RHEL 10 hosts with
repo_epel__mirror_urlset, EPEL is installed from the mirror. Until now dnf failed to download the EPEL metadata, which also broke every other dnf call on the host. - role:php: Apache starts after PHP-FPM at boot, so the first PHP requests after a reboot no longer fail.
- role:firewall: With
firewall__fwbuilder_repo_url, a repository without a compiled firewall for the host aborts the run before the role stops any firewall. Until now the role stopped a running firewalld, iptables, nftables or ufw first and left the host without a firewall. - role:acme_sh: On Debian and Ubuntu, certificates are installed with
systemctl reload apache2instead ofsystemctl reload httpd, which does not exist there; certificates installed before keep the old command until they are issued again. - role:mount: A freshly created filesystem is relabelled for SELinux after mounting, so confined services such as Apache httpd can access it without a manual
restorecon. - role:mirror: Repairs the ACL mask of
mirror__base_pathwhen a chmod narrowed it tor-x, which made reposync fail withPermission deniedon every new repository. - role:mirror: Runs on minimal installations such as Rocky 10, where it aborted for lack of
setfacl, since the role installs acl, createrepo and git itself instead of the mirror playbook running the apps role. - role:openvpn_server: The role runs on a minimal RHEL 10 installation, where it aborted for lack of
opensslwhile generating Diffie-Hellman parameters, which OpenVPN 2.7 no longer needs. - role:apache_solr: Passwords no longer show up in the output of a run, and a user without
stateno longer aborts it. - role:apache_solr: The role runs without EPEL on RHEL and no longer restarts Solr on every run.
- role:apache_solr: A role with several permissions takes effect, where Solr discarded it as invalid so far.
- role:apache_solr: Users can log in on hosts without
xxd, such as a minimal RHEL 9, where the role wrote an empty password hash. - role:apache_httpd: On Debian and Ubuntu, the first run against a fresh host no longer fails reloading Apache, since the role points
PidFileto whereapachectllooks; a server started by an earlier version of the role is restarted once. - role:apache_httpd: Apache reloads after the OWASP Core Rule Set is updated, instead of applying the previous rules until its next reload.
- role:apache_httpd: The OWASP Core Rule Set deploys on Debian and Ubuntu, where the run failed until now, and on Ubuntu 22.04, whose ModSecurity 2.9.5 is too old for it, the run aborts with a message saying so.
- playbook:redis, playbook:setup_mastodon: On Debian and Ubuntu, the playbooks no longer abort with "'redis__skip_repo_redis' is undefined" or "'setup_mastodon__skip_repo_redis' is undefined" unless the skip variable is set in the inventory.
- role:grafana_grizzly, role:monitoring_plugins_grafana_dashboards: On Grafana 13.1 and newer, dashboards that the roles add or update stay in their folder, instead of landing in the root, where viewers and the graphs embedded in IcingaWeb2 got "403". A run also moves back the dashboards that earlier runs left in the root.
- role:aide: The AIDE check no longer fails on hosts with fwupd, where it reported
/etc/fwupd/fwupd.confas changed after the first start of the fwupd daemon. - role:aide: The AIDE check no longer fails on hosts with an EFI system partition, where it reported the files below
/boot/efias changed a while after the database was created. - role:system_update: The security lane installs hot-fixes that need a newer package from BaseOS or AppStream, such as the kernel on Rocky 8.3, instead of failing on every run.
- role:system_update: On Fedora 42 and later, where
/usr/local/sbinis a link to/usr/local/bin, the role no longer deletes theupdate-and-rebootscript right after deploying it, so the weekly update runs again. - role:monitoring_plugins: A run against an unchanged host no longer reports a change for the legacy dependency list of the source install.
- roles: Tasks that run on the Ansible controller no longer escalate via sudo when the inventory sets
ansible_become: true, where they failed without passwordless sudo on the controller or ran as root and left root-owned files in/tmp. - plugin:bitwarden_item, module:bitwarden_item: A failed sync of the Bitwarden vault, such as an "HTTP Error 400: Bad Request" or a timeout of
bw serve, is tried again after 10, 30 and 60 seconds instead of aborting the run right away. - role:aide: Before it creates the database, the role also waits for running
dnf-automaticjobs on the Red Hat family and for the update jobs of the system_update role on every platform, not only for the apt jobs on Debian and Ubuntu. An update during the initialisation left files in the database that the first check then reported. - playbook:setup_basic: With
setup_basic__skip_duplicityorsetup_basic__skip_glances, the playbook no longer builds the Python venv of the skipped role, which could abort the run with a pip error on hosts that do not back up with duplicity. - role:kernel_settings:
sunrpc.*settings, such as thesunrpc.tcp_slot_table_entriesthe mariadb_server role sets, survive a reboot. Until now thesunrpcmodule was not loaded again after a reboot on hosts without NFS, so TuneD could not apply the setting and the next run of the role failed intuned-adm verify. - role:repo_baseos: The Rocky Linux
securityrepository works on Rocky 8 releases before 8.5, where dnf failed to download its metadata. - role:monitoring_plugins: The source install deploys the OID lists and MIBs of the
snmpplugin, which until now failed with "No such file or directory" on every host installed this way. - role:bind: A secondary zone with
type: 'slave'is saved to its file again, so the secondary answers it after a restart without waiting for the primary. - role:bind: Reverse lookups for private and special-use addresses, such as
10.0.0.0/8orfd00::/8, are answered locally, as BIND does by default, instead of waiting for the forwarders, which also no longer see the internal addressing. - role:kernel_settings: The role works with fedora.linux_system_roles 2.5.0 and later, which a fresh installation of LFOps pulls in. Until now the run aborted with "kernel_settings_transparent_hugepages must be null, one of always, madvise, never" unless
kernel_settings__transparent_hugepages__*_varandkernel_settings__transparent_hugepages_defrag__*_varwere set. - role:system_update: The AIDE database is only updated after an update if a check right before the update comes out clean, instead of relying on the last scheduled check, so changes made since then are no longer accepted along with the update; a check that cannot run at all is reported in a mail of its own.
- role:fangfrisch:
--tags fangfrisch:stateno longer aborts on an undefined variable. - role:firewall: Hosts in one run with different
firewall__fwbuilder_repo_urlvalues each deploy/etc/fwb.shfrom their own repository, instead of all from the repository of the first host. - role:firewall:
firewall__firewall: 'iptables'no longer aborts when there is no iptables file in the inventory'shost_files, which the README describes as optional. - role:firewall: A host switched away from
fwbuilderoriptablesstops, disables and masks that firewall instead of keeping it running next to the new one, and no longer reports a change on every run. - module:nextcloud_occ_app: An
occ app:listoutput orinstalled_apps_jsonthat is valid JSON but not an object aborts with a clear message instead of a Python traceback. - module:nextcloud_occ_system_config: Setting a key that does not exist yet to an empty value (
value: '') creates it. Until now the module reported no change and left the key missing. - module:uptimerobot_mwindow_info: Monthly maintenance windows on day 1 to 7 of the month are reported with their day numbers instead of weekday names, e.g.
1-15instead ofmon-15. - role:system_update: The daily security lane on Rocky refreshes the AIDE database after installing hot-fixes, like the weekly lane, so the next AIDE check no longer fails on every file a hot-fix touched.
- role:lvm: On Debian and Ubuntu, mounting an LV no longer fails on
restorecon, which only runs where SELinux is enabled. - role:lvm: The role installs the tools for XFS and ext2/3/4, so creating the default XFS file system no longer fails on hosts without
mkfs.xfs, such as those deployed from a Debian cloud image. - role:lvm:
mount_owner,mount_groupandmount_modeapply to the mounted file system from the first run on. Until now they only took effect on the second run, which therefore reported a change. - role:lvm: Removing an LV (
state: absent) no longer aborts with'dict object' has no attribute 'size'. - role:lvm: Removing a VG (
state: absent) no longer aborts withcould not find 'pvs' keywhen the entry lists nopvs. - role:lvm: Shrinking an LV works. It needs
force: truein addition toshrink: true; withshrink: truealone the run aborted. - role:lvm: The role installs
lvm2, so it also works on hosts installed without LVM, such as those deployed from a cloud image. - role:lvm: Creating or resizing a PV no longer fails on RHEL 8 with
SyntaxError: future feature annotations is not defined. - role:network: Hosts without
network_connectionsornetwork_stateno longer run the upstream network role at all, which occasionally hung the play for good after it had finished. - role:kernel_settings: The role no longer aborts on Ubuntu 22.04 with
Verification failed, current system settings differ from the preset profile. - role:tools: The role no longer aborts on Ubuntu with
No package matching 'cloud-utils-growpart' is available. - role:python_venv: The role no longer aborts on Debian and Ubuntu with
Failed to import the required Python library (packaging). - playbook:setup_basic: The play no longer aborts on Debian and Ubuntu with
No package matching 'network-scripts' is availableor'__yum_utils__package' is undefined, since it runs thenetworkandyum_utilsroles on the Red Hat family only. - role:monitoring_plugins: The plugin icons for IcingaWeb2 are no longer missing when the directory
ansible-playbookruns in contains.svgfiles. - role:monitoring_plugins: The source install deploys only the modules of the Linuxfabrik library, as the one-line installer does, removes the documentation and development files earlier runs placed next to them, and removes plugin assets the checked-out version no longer carries.
- role:monitoring_plugins: The source install no longer reports a change on every run once the plugins have run.
- role:monitoring_plugins: The source install no longer clears the setuid bit of the distribution's
check_icmpandcheck_dhcpon every run. - role:monitoring_plugins:
--tags monitoring_plugins:removeno longer aborts on Debian and Ubuntu, and also removes the version lock of the SELinux package, the SELinux policy module, the Debian conffiles and every file a release of the plugins ever installed. - role:monitoring_plugins: The source install sets
nagios_run_sudoand, for Monitoring Plugins releases after 8.0.0, loads the SELinux policy module, so plugins run through sudo under enforcing SELinux on RHEL 8 and 9. - role:monitoring_plugins: The source install of a release before 8.0.0 no longer fails on the missing logging sudoers file.
- role:fail2ban: An empty
fail2ban__jail_portscan_allowed_portsexempts no port, so theportscanjail bans every denied connection attempt instead of none. - role:fail2ban: The
portscanjail no longer bans a server that a local proxy talks to because the firewall logged a late TCP packet or an ICMP error from it, for example the final FIN of a half-closed connection. - role:grafana: The
from_nameofgrafana__smtp_configis used as the sender name of emails, instead of the value ofskip_verify. - module:bitwarden_item: The module works with the Mitogen strategy, where it aborted with
MODULE FAILUREon every run, for example when thegrafanarole stores its service account tokens. - plugin:bitwarden_item, module:bitwarden_item: Running against several hosts in parallel no longer creates duplicates of a Bitwarden item, whether the item is new or has existed for a long time, so the next run no longer aborts with "Found multiple Bitwarden items".
- role:wordpress: The installation no longer aborts at
wp core downloadwhen Ansible connects asrootwithout privilege escalation. - role:wordpress: A second run no longer reports the
wp-config.phpconstants,wordpress__pluginsandwordpress__themeas changed. - role:wordpress: The WXR file in
wordpress__wxr_exportis imported when the role installs WordPress; the import never ran before. - role:wordpress: Ansible's temporary directory for
apacheis/usr/share/httpd/.ansible/tmpinstead of a path with two trailing spaces. - role:apache_httpd: The
wordpressvHost blocks direct calls to the PHP files belowwp-includes/andwp-admin/includes/, whose rules never matched. - role:postfix:
postfix__compatibility_leveltakes effect on Debian and Ubuntu as well, and defaults to the level the distribution ships, so Debian 13 and Ubuntu 26.04 run at3.9instead of3.6(#364). - role:mariadb_server: On RHEL 10 with a
selinux-policy-targetedolder than42.1.18-4.el10_2.3, MariaDB runs confined inmysqld_tagain, so web applications such as WordPress or Nextcloud reach its socket. Until now it ran ininitrc_tthere, and PHP-FPM failed to connect until the SELinux policy was updated and MariaDB restarted. - role:monitoring_plugins: A package install that fails no longer leaves the Monitoring Plugins unlocked, so a later system update cannot move them past
monitoring_plugins__version. The lock that existed before the run is set again. - role:monitoring_plugins: A run against an unchanged host no longer reports changes for the package versionlock (#353).
- role:collabora: A run against an unchanged host no longer reports changes for the coolwsd log file and the ownership of
/etc/coolwsd. - role:collabora: The role runs on RHEL 10, since it no longer installs the distribution's
mythesandhunspelldictionary packages, which Collabora does not need next to its own dictionary packages. Packages already installed are left in place (#373). - playbook:kvm_host: The playbook deploys the EPEL repository, and CRB on Rocky 9 and newer, so it no longer fails to install
genisoimageon RHEL 9 and 10 hosts that did not have EPEL set up already (#375). - playbook:chromium_headless, playbook:icingaweb2_module_pdfexport, playbook:repo_epel: On Rocky 9 and newer, these playbooks enable the CRB repository together with EPEL, like every other playbook that deploys EPEL, since EPEL packages depend on packages from CRB.
- role:repo_icinga: On Fedora the role deploys Icinga's public repository instead of failing on a release package that Icinga no longer publishes (#360).
- role:repo_postgresql: The role no longer aborts on RHEL 10 right after deploying the repository (#370).
- role:repo_collabora_code: The role deploys the repository on RHEL 10 instead of failing on a missing template (#377).
- role:lvm:
growpart: trueworks on minimal installations, where the role failed because nothing installedgrowpart(#365). - role:icinga2_agent, role:icinga2_master: Icinga 2 starts after SSSD at boot as intended, so its early
sudocalls no longer fail withproblem with defaults entries; the ordering pointed at a unit that does not exist and never took effect (#357). - role:grafana: With
grafana__auth_jwt: true, the run no longer aborts atgenerate JWT RSA private keywithCannot detect the required Python library cryptographyon hosts that lack it, because the playbooks deploying Grafana installpython3-cryptographyfirst. - role:clamav, role:sshd:
--tags clamav:configure,--tags clamav:stateand--tags sshd:stateno longer abort on an undefined variable, so a restart skipped withlfops__skip_restart_handlerscan be caught up with--tags <role>:stateas the README describes. - role:php: A playbook that includes PHP, such as
setup_nextcloud, no longer aborts atGet PHP versionwhen it is run with another role's tags, for example--tags apache_httpd, against a host that has no PHP installed yet. - role:kdump:
kdump__service_enabled: trueturns kdump on on RHEL 10 as well instead of leaving it off without an error, and a kdump that is supposed to run fails the run when its service cannot be managed (#359). - role:repo_mariadb: On RHEL 10 the role aborts for MariaDB versions older than 10.11, which MariaDB publishes no RHEL 10 packages for, instead of deploying a repository that answers 404 and breaks every dnf transaction on the host.
- role:repo_epel: The role no longer aborts on RHEL 10, AlmaLinux 10 and CentOS Stream 10.
- role:chrony:
chronydon RHEL 10 no longer logsCould not open keyfileon every start, since the deployedchrony.confloads no key file on any release. - role:nextcloud:
nextcloud-updatesets the Icinga downtime again, taking the API user fromicinga2_master__downtime_api_user(see Added) instead of from thesystem_update__icinga2_api_user_loginremoved in v8.0.0. - role:borg_local, role:schedule_reboot, role:tools: The Icinga downtime around a backup or a reboot is set again when the deploying playbook does not run
icinga2_agentitself, such asbootloader,system_updateortools, and the inventory only sets the mandatoryicinga2_agent__icinga2_master_cn. - role:fail2ban: The
apache-botsearch,apache-fakegooglebot,apache-nohomeandapache-noscriptjail templates can be deployed again. Using one of them aborted the run.
Security¶
- role:openvpn_server: The server negotiates TLS 1.2 only with forward secrecy and checks client certificates against OpenSSL security level 2 (#358).
- role:apache_httpd: The OWASP Core Rule Set archive is checked against a SHA-256 checksum before it is deployed, so a tampered or corrupted download aborts the run.
- role:monitoring_plugins: The source install checks every pinned Python dependency against the checksums in the lockfile instead of installing whatever PyPI serves, and puts the sudoers drop-ins in place only once
visudoaccepts them. - role:github_project_createrepo: The service can only write to the repositories it maintains instead of to everything below
github_project_createrepo__base_path, where it could replace other files such as a repository signing key. The role removes the ACL entries it granted before. - role:kernel_modules: Blocks further rarely used kernel modules by default that unprivileged users can get loaded and that are prone to local privilege escalations, among them
ah6,pppoeandsctp_diagfrom RHSB-2026-011. This stops Bluetooth, L2TP/IPsec, PPPoE, PPTP and IPsec AH; setenabled: truefor the modules a host needs. The role README lists them all. - role:wordpress:
--tags wordpress:exportwrites to/backup/wordpress-export/<instance>, readable byapacheandrootonly, instead of to/tmp. - role:wordpress: The database and admin passwords no longer show up in the process list during the installation.
- role:wordpress: WP-CLI is verified against its published checksum, and an installed WP-CLI that differs from the current release is replaced.
- role:wordpress:
wp-config.php, which holds the database password and the salts, is no longer readable by every local user. - role:apache_httpd: The
wordpressvHost sendsX-Content-Type-Options: nosniffandReferrer-Policy: strict-origin-when-cross-origin. - role:apache_httpd: The
wordpressvHost refuses to run PHP files belowwp-content/uploads, so an upload flaw in a plugin no longer leads to code execution. - role:repo_collabora_code: dnf verifies the signatures of the Collabora packages, as Collabora's own installation instructions do, where the repository file had switched the check off.
v9.0.0 - 2026-09-09¶
Highlights: Valkey gets its own role and playbook instead of being installed under the Redis name, which is what RHEL 10 hosts need now that Red Hat ships no Redis at all; those hosts have to be moved over. On RHEL 8, a MariaDB package upgrade no longer cuts applications on the same host off from their database. Apache no longer loads mod_info, which served the complete configuration including other modules' credentials. A broken PHP-FPM configuration aborts the run instead of taking the service down on the restart. Sudo rules deployed by freeipa_server can carry their commands again. The Bitwarden lookup can be told to abort instead of silently generating a new password, for runs against hosts whose credentials must already exist. The Grafana graph configuration for the Monitoring Plugins is no longer deployed on every ordinary run and has to be requested explicitly by its tag. Apache serves HTTP/2 to every client that offers it over TLS, which in a typical setup is the reverse proxy in front of an application; the hop from that proxy to the backend is unchanged. LibreNMS keeps its RRD updates in RRDCached and writes them out every 30 minutes, taking a large share of the poller's disk I/O off the host.
Breaking Changes¶
- role:icingadb, role:icingaweb2, role:icingaweb2_module_reporting, role:icingaweb2_module_x509, role:mariadb_server: The MariaDB tasks move from
ansible.mysqlto its MariaDB counterpartansible.mariadb, so the deprecation warning printed on every run is gone and the roles keep working onceansible.mysqldrops MariaDB support.ansible-galaxy collection install linuxfabrik.lfopspulls the new collection in as a dependency; a manually maintained collection list has to add it. If you run LFOps in the Execution Environment, pull the current image (podman pull ghcr.io/linuxfabrik/lfops_ee:latest), because an EE ships the collections it was built with and an older one aborts these roles withcouldn't resolve module/action. - role:php: The session cookie is marked
Secure, so browsers only send it back over HTTPS. A site served over plain HTTP can no longer log anyone in, because the browser accepts the cookie and never returns it: setphp__ini_session_cookie_secure__group_var: 'Off'for such a host, orphp_value_session_cookie_secure: 'Off'for the affected pool alone. HTTPS hosts are unaffected, including behind a reverse proxy that terminates TLS, and nobody is logged out by the change: a running session resumes and keeps its existing cookie until the application regenerates the session ID. - role:php: The session cookie carries
SameSite=Laxfrom PHP 7.3 on, where PHP so far emitted no attribute at all and left the decision to the browser. The cookie is no longer sent on cross-site POSTs, in iframes or on XHR, which is what stops a foreign page from acting under a visitor's session. An application whose identity provider returns through a cross-site POST, as SAML HTTP-POST binding and the OIDCform_postresponse mode do, loops on login until it is set back, for that pool alone via the newphp_value_session_cookie_samesite: 'None'andphp_value_session_cookie_secure: 'On'subkeys ofphp__fpm_pools__*_var(browsers requireSecureforNone), or host-wide viaphp__ini_session_cookie_samesite__group_var. An identity provider under the same registrable domain is unaffected. - role:redis:
redis__conf_daemonizeandredis__conf_supervisedare gone; remove them from your inventory. Neither ever reached the running service: a Redis supervised by systemd never daemonizes, and every packaged unit either overrides both on itsExecStartline or depends on thesupervised autothe role deploys. The deployedredis.confkeeps the values it had, so nothing changes on a host that used the defaults. - role:librenms:
librenms__fqdnandlibrenms__config_app_urlare replaced bylibrenms__url, which takes the URL of the instance including the scheme, for examplehttps://librenms.example.com. Set it in place of the two, using the URL your users open in the browser even when Apache httpd on the host serves plain HTTP behind a TLS-terminating proxy. - role:librenms: LibreNMS trusts no reverse proxy any more, where it previously trusted one running on the LibreNMS host itself. It therefore ignores the
X-Forwarded-*headers of such a proxy, and logs, access control and the detected protocol use the proxy's address instead of the client's. Hosts with a proxy in front of LibreNMS list it inlibrenms__config_app_trusted_proxies;['127.0.0.1']restores the previous behaviour. - role:php: The PHP-FPM pool configuration changed for existing hosts. Sessions now live in a per-pool directory (the default
wwwpool moves from/var/lib/php/sessionto/var/lib/php/session/www), so logged-in users are signed out once after the upgrade.memory_limit,max_execution_time,max_input_vars,post_max_size,upload_max_filesize,session.save_handlerandsession.save_pathare now enforced asphp_admin_value, so applications can no longer change them at runtime viaini_set(). A pool that stores its sessions in redis or memcached setsphp_admin_value_session_save_handleraccordingly.soap.wsdl_cache_dirmoves from the shared/var/lib/php/wsdlcacheto a per-pool directory below it. On Debian the pool socket now belongs torootand grants the web server access through a POSIX ACL entry, where it used to be owned by the web server user; anything of your own that checks the socket's ownership rather than connecting to it needs adjusting. Worker processes recycle after 500 requests (pm.max_requests) instead of running indefinitely, and a worker still serving a single request after 60 seconds is killed (request_terminate_timeout, previously off). Hosts with legitimately long-running web requests raisephp__fpm_pool_conf_request_terminate_timeout__group_var. - role:keycloak: Rename
keycloak__statetokeycloak__service_state, the name every other LFOps role uses. The valuereloadedis gone: Keycloak's systemd unit has noExecReload, so a reload never worked; userestartedinstead. - role:keycloak: The role installs the OpenJDK its Keycloak version needs (OpenJDK 17 for Keycloak 24, OpenJDK 21 for 25 and newer) instead of relying on the
appsrole, whichsetup_keycloakno longer runs. Hosts that usedapps__apps__*_varthrough this playbook to install further packages have to run theappsplaybook for them. - playbook:setup_keycloak: All skip variables are named
setup_keycloak__skip_<role>now. Renamekeycloak__skip_kernel_settings,keycloak__skip_policycoreutils,keycloak__skip_repo_mydumper,mariadb_server__skip_pythonandmariadb_server__skip_repo_mariadbaccordingly. - role:php: On RedHat, every host running this role gets the
lfops_php_fpm_slowlogSELinux policy module, which grants thehttpd_tdomain thesys_ptracecapability andptraceon itself. Without it the PHP-FPM slowlog stays empty, because the master is not allowed to ptrace the worker whose backtrace it is supposed to write. The module is deployed regardless of whether the slowlog is switched on, the permissions apply to the wholehttpd_tdomain and therefore to Apache httpd as well, and compiling it installsmakeandselinux-policy-develon the host. Thephpandicingaweb2playbooks run thepolicycoreutilsandselinuxroles for this; set the playbook's__skip_selinuxvariable (for examplephp__skip_selinux: true) to leave the host's policy untouched. - role:mariadb_server: The InnoDB buffer pool grows from 128 MiB to 512 MiB, so a database with more than a trivial amount of data is served from memory instead of from disk. Every host running this role therefore uses roughly 384 MiB more RAM after the next restart of the service.
- role:mariadb_server: The InnoDB redo log grows from 32 MiB to the 96 MiB MariaDB itself ships, so a write-heavy server no longer stalls waiting for a checkpoint on a redo log sized for much smaller workloads. InnoDB resizes the log itself when the service next restarts, also after an unclean shutdown, but the data directory needs 64 MiB more free space for it; check that on hosts that are tight before deploying. Set
mariadb_server__cnf_innodb_log_file_size__group_var: '32M'(or the__host_var) to keep the previous size. - role:mariadb_server:
innodb_snapshot_isolationnow defaults toOFF. Turning it on requires support from the application: a transaction inREPEATABLE READthat modifies a row another transaction changed after its snapshot was taken is aborted withER_CHECKREAD. The application has to catch that error and retry the transaction, otherwise the write fails under concurrent load. To restore the previous behaviour on hosts whose application is known to handle it, setmariadb_server__cnf_innodb_snapshot_isolation__group_var: 'ON'(or the__host_var). - role:collabora:
collabora__coolwsd_ssl_settings_ssl_verificationandcollabora__coolwsd_welcome_enablereach the deployedcoolwsd.xmlagain, and SSL verification of the WOPI host now defaults to strict. Both variables were only wired into a few old templates, so on newer versions the value came from the package instead of from the inventory, and most packages ship verification off. A host whose WOPI host presents a self-signed or otherwise untrusted certificate needscollabora__coolwsd_ssl_settings_ssl_verification: false, otherwise its documents stop loading. - role:apache_httpd:
mod_infois no longer enabled, so/server-infostops serving the complete Apache configuration, including the credentials of other modules. Hosts that need the endpoint re-enable theinfomodule in their inventory viaapache_httpd__mods__group_var/apache_httpd__mods__host_var. - role:monitoring_plugins: A source install now places the notification plugins in
/usr/lib64/nagios/plugins, next to the check plugins, and removes the/usr/lib64/nagios/plugins/notificationsdirectory it used before. This is where the shipped Icinga command definitions and the rpm/deb packages have always expected them. Adjust any command definition of your own that points into thenotificationssubdirectory. - role:redis: RHEL 10 is no longer supported, since Red Hat ships no Redis there. On RHEL 10 the role used to install Valkey under the Redis name, which aborted the run when the configuration file was deployed. Move those hosts to the
valkeyrole: put them into thelfops_valkeyinventory group and rename theirredis__*variables tovalkey__*. All other platforms are unaffected. - role:collabora: Drop support for EOL Collabora 23.05. Upgrade to 24.04 or newer.
- role:icingaweb2_module_grafana: The graph configuration for the Linuxfabrik Monitoring Plugins is only deployed when the role is called with
--tags icingaweb2_module_grafana:monitoring_plugins_graphs, matching theicingaweb2_module_director:baskettag. Run the role with that tag to update/etc/icingaweb2/modules/grafana/graphs.ini. Theicingaweb2_module_grafana__skip_monitoring_plugins_graphs_configvariable is gone; remove it from your inventory.
Added¶
- role:fail2ban: The
apache-404-matomofilter and jail work likeapache-404but for the matomo LogFormat, where the virtual host precedes the client IP in the log line. - role:fail2ban: The
apache-404filter acceptsfail2ban__jail_apache_404_ignoreregex, a list of regular expressions whose matching log lines are excluded from the 404 count, so known missing resources like/favicon.icoor/assets/style.cssno longer trigger a ban. - role:php: The
[global]section of the PHP-FPM configuration can be set from the inventory, so the log level and the reload after repeated worker crashes are configurable; the reload is on by default after ten crashes within a minute. - role:fail2ban: The
apache-404filter and jail ban IPs that cause excessive HTTP 404 errors in the Apache access log, configurable viafail2ban__jail_apache_404_bantime,fail2ban__jail_apache_404_findtimeandfail2ban__jail_apache_404_maxretry. - role:apache_solr: The maximum size of the Java heap can be configured via
apache_solr__heap. - role:apache_solr: The Java Security Manager can be switched off via
apache_solr__security_manager_enabled, for instances that have to follow symlinks pointing outside of Solr's own directories. - role:apache_httpd: The GELF access log carries the request protocol as its own
_http_versionfield, so the share of traffic on HTTP/2 can be graphed per vHost in Graylog. The text log formats already contained it as part of the request line and are unchanged, because fail2ban and the Matomo log importer parse them positionally. - role:librenms:
librenms__scheduler_service_enabledandlibrenms__scheduler_service_statestart, stop or disable the timer of the LibreNMS scheduler on its own. - role:librenms: The
librenms:cron,librenms:logrotateandlibrenms:statetags deploy the scheduled jobs, deploy the logrotate configuration and manage the service state without touching the rest of the installation. - role:librenms: The session cookie is marked as secure on hosts whose
librenms__urlis anhttps://URL, so a browser only sends it over HTTPS. LibreNMS reports the missing flag as a failure in its own validation. Setlibrenms__config_session_secure_cookieto override. - role:librenms: LibreNMS stores its RRD files through RRDCached, which cuts the disk I/O of the poller by roughly a third.
- role:librenms: The
librenms:rrdcachedtag deploys and configures RRDCached without touching the rest of the installation. - role:php: PHP-FPM pools are now fully configurable, each with its own user and group, process-manager tuning, timeouts and
php_admin_valueoverrides. Every pool gets an isolated session directory, its own error and slow logs, and its own socket, so several applications can share a host without sharing a PHP process, a session store or a memory limit. One pool template now serves both distribution families. - role:php: Add
meta/argument_specs.ymldeclaring the user-facing variables, so role-entry validation catches type mismatches and unknown variables, and an explicitvars/Ubuntu.yml. - role:apache_httpd:
apache_httpd__mod_http2_protocolssets the protocols offered server-wide, theconf_protocolsvHost key overrides it for a single vHost, and the remainingapache_httpd__mod_http2_*variables size the HTTP/2 worker pool and its per-connection buffers. - role:keycloak: The Keycloak log file is rotated, with
keycloak__logrotatefor the number of rotations kept and thekeycloak:logrotatetag to deploy the configuration on its own. Until now the log grew unbounded, since Keycloak has no built-in rotation for its file log handler. - role:keycloak: Add
keycloak__limit_nofile,keycloak__transaction_default_timeoutandkeycloak__transaction_setup_timeoutfor values that were hardcoded in the systemd unit and inkeycloak.conf. - role:selinux: A policy module can be defined inline through the
content_tesubkey ofselinux__modules__*_var, instead of pointingsrcat a directory on the Ansible controller. - role:openvpn_server: Add
openvpn_server__service_stateto start, stop, restart or reload the OpenVPN service independently of whether it is enabled at boot. - role:valkey: Add a role and playbook to install and configure Valkey, listening on TCP port 6379 on the loopback interfaces by default. Valkey is taken from the distribution repositories (EPEL on RHEL 8, AppStream on RHEL 9 and 10, the distribution's own repository on Debian 13 and Ubuntu 24.04 / 26.04), and the configuration template matching the installed version is deployed. Debian 12 and Ubuntu 22.04 ship no Valkey and are not supported.
- playbook:setup_icinga2_master, playbook:setup_mastodon, playbook:setup_moodle, playbook:setup_nextcloud: These stacks install Valkey on RHEL 10 and Redis everywhere else, so they can be deployed on RHEL 10 again. Both servers speak the same protocol on the same port, so the applications are configured identically either way. Override
setup_*__skip_redis/setup_*__skip_valkey(setup_icinga2_master__redis__skip_role/setup_icinga2_master__valkey__skip_role) to force a specific server or to run neither. - role:files: A file can opt out of the backup copy that is written before it is overwritten, via the
backupsubkey offiles__files__*_var. - role:collabora: The
collabora:configuretag deployscoolwsd.xmland the logrotate configuration without touching the packages. - role:docker: The address pools docker assigns container network subnets from (
default-address-pools) can be configured. - role:collabora: Add support for Collabora Online CODE 26.04.1, 26.04.2 and 26.04.3, and Collabora Enterprise 24.04.18, 25.04.12 and 26.04.2.
- role:monitoring_plugins: Deploy the bash completion file for source installs.
- role:kvm_vm: VMs can now also be installed from an ISO or install tree instead of a prepared cloud image.
- role:files: The
files:directories,files:filesandfiles:symlinkstags manage one kind of file system entity each, so a single directory or symlink can be deployed without touching the rest. - plugin:bitwarden_item: The lookup can be told not to create secrets, so a lookup that finds no matching item aborts the run instead of silently generating a new password. Set
LFOPS_BITWARDEN_LOOKUP_ITEM_CREATE=false, orcreate = falsein the[bitwarden_item_lookup]section of youransible.cfg; the default is the previous behaviour.
Changed¶
- role:php: A run aborts when a pool's
request_terminate_timeoutis not above itsmax_execution_time, instead of deploying a pool whose longer execution time is capped by PHP-FPM without saying so. Setting either to0still switches that limit off. - role:php: The logrotate configuration for the per-pool PHP-FPM logs on Debian is deployed by the
php:logrotatetag instead ofphp:fpm. - role:redis: Redis also listens on the IPv6 loopback
[::1]:6379, where it previously answered on127.0.0.1only, so clients that resolvelocalhostto::1are no longer refused. Hosts without an IPv6 loopback are unaffected: the address is marked optional, so Redis logs a warning and carries on instead of aborting. - role:apache_httpd: Restarting Apache takes about 5 seconds instead of 13 on a host that holds long-lived connections, such as a proxy for WebSockets, because systemd no longer waits out Apache's own shutdown escalation. Apache refuses new connections for the whole of that wait, so this shortens the outage. The hard stop leaks about three semaphores per restart (
ipcs -s), which a reboot clears; raiseapache_httpd__systemd_timeout_stop_secto trade restart speed back for a longer graceful window. - playbook:setup_librenms: The skip variables of the playbook are all named after the playbook,
setup_librenms__skip_phpfor example, instead of after thelibrenmsrole. - playbook:setup_librenms: The playbook no longer runs the
appsrole, since thelibrenmsrole installsgititself. - role:librenms: The
http_fpingSELinux policy module carries the rules the LibreNMS documentation now lists, so pinging a device from the web interface also works where fping uses an ICMP socket or binds a source address. - role:librenms: PHP GMP is installed, so rates derived from 64-bit interface counters stay exact instead of silently losing precision in float arithmetic.
- role:librenms: The
httpd_can_sendmailSELinux boolean is enabled, andhttpd_can_network_connect_dbin addition when the database is on another host. - role:librenms: The SELinux file context of
/opt/librenms/cacheis set. - role:librenms: ImageMagick is no longer installed, LibreNMS does not use it.
- role:librenms: The
http_fpingSELinux policy module is deployed by theselinuxrole, so a playbook run that skips that role no longer installs it. - role:librenms: The role no longer makes the RRD, log, cache and storage directories group-writable, LibreNMS grants the access it needs itself while installing.
- role:apache_httpd: Restarting Apache no longer takes 90 seconds on a host that holds long-lived connections, such as a proxy for WebSockets. The server now waits 3 seconds for running requests to finish instead of waiting for the last connection to close by itself and being killed by systemd. Apache stops accepting new connections for the whole of that wait, so this shortens the outage rather than extending it. Hosts with legitimately long-running requests raise
apache_httpd__conf_graceful_shutdown_timeout. - role:apache_httpd: HTTP/2 is enabled and is the preferred protocol on every connection that terminates TLS, while a client that does not offer it is still served HTTP/1.1 and cleartext HTTP/2 (h2c) is not offered; on RedHat the
mod_http2package is installed for this. - role:keycloak:
keycloak__https_cipher_suites,keycloak__https_protocols,keycloak__logandkeycloak__proxy_trusted_addressesare YAML lists instead of comma-separated strings. A comma-separated value already in an inventory keeps working, Ansible splits it into the same list. - role:keycloak: The Keycloak tarball is downloaded on the Ansible controller and copied to the target from there, so a target without internet access can be installed. The controller has to reach
github.com. - role:keycloak:
--tags keycloak:configuredeploys the configuration and rebuilds the server, but no longer starts the service or bootstraps the admin account. Use thekeycloaktag for a full run andkeycloak:statefor the service state. - role:selinux: A policy module is only recompiled and reinstalled when its source changed, so a run against an up-to-date host no longer reports a change for every module it manages.
- role:monitoring_plugins: A source install also deploys the
*-logging.sudoerscompanion, which keeps the plugin calls out of the authentication log. Without it every check costs five entries there, and a monitored host runs dozens of checks a minute. A host running sudo-rs, Ubuntu 26.04 for example, does not get the file and loses it again if it had one, because sudo-rs knows none of its settings and warns about each of them on everysudocall by any user. - A service that depends on a kernel setting deployed by the
kernel_settingsrole now starts after TuneD, so the setting is in place before the service reads it. Until now such a service could come up while TuneD was still applying the profile and then run with the old value until its next restart, whilesysctlandtuned-adm verifyalready reported the new one (rolesgraylog_datanode,graylog_server,mariadb_server,mongodb,redis). - A repository file that carries mirror credentials is deployed with mode
0600instead of0644, so an unprivilegeddnforzypperno longer lists those repositories (allrepo_*roles). - role:collabora: A host running a Collabora version the role has no configuration template for aborts with that version and the list of supported ones, instead of failing on a missing file.
- role:collabora: The
localhostWOPI host is an ordinary entry ofcollabora__coolwsd_storage_wopi__*instead of being hard-coded in the template, so it can be dropped withstate: 'absent'like any other host. - role:php: The PHP-FPM configuration is checked with
php-fpm --testbefore the service is restarted, so a broken pool or ini aborts the run with the error message instead of taking PHP-FPM down on the restart.
Fixed¶
- role:php: A run limited to
--tags php:fpmdeploys the pools with the configuredmemory_limit,max_execution_timeandpost_max_sizeagain, instead of writing them empty. php-fpm accepts the empty values without complaint, and asphp_admin_valuethey override whatphp.inisets. - role:nextcloud: Long web requests are no longer killed after 60 seconds, so assembling a large chunked upload completes again. The role raises
max_execution_timeto 3600, but PHP-FPM has terminated a request after 60 seconds since the pool rework, and its limit fired first. - role:monitoring_plugins_grafana_dashboards: The Grafana dashboards are collected in an empty directory on the controller. That directory was reused across runs, so the dashboard of a plugin that upstream renamed or removed kept being deployed, and a downgrade to an older Monitoring Plugins version still rolled out the dashboards of the newer one.
- role:fail2ban: The
apache-404filter no longer produces false positives on thelinuxfabrikiolog format when a later field (such as bytes received%I) happens to contain404. - role:librenms: The Python packages LibreNMS requires are installed, so its own validation no longer reports
command_runnerandpsutilas missing. - role:librenms: An update of LibreNMS that changes the units of its scheduler takes effect, because systemd is told to read them again.
- role:librenms: The poller works on a host whose database is not local, because the Python modules it imports are installed by the role instead of arriving through the MariaDB role.
- role:librenms: A second run of the role updates an existing installation instead of aborting at the git checkout.
- playbook:setup_librenms: A fresh installation no longer aborts while starting PHP-FPM.
- playbook:setup_librenms: The SELinux file contexts for
/opt/librenmsare applied. - role:apache_httpd: Enabling an Apache module restarts httpd instead of reloading it, so the module actually takes effect. A reload loads the module but skips its initialization, which left HTTP/2 configured but silently inactive on RHEL 8 (#339).
- role:kvm_vm: Two VMs created from the same inventory host no longer get the same MAC address, which made the second one fail with
The MAC address ... is in use by another virtual machine. The generated MAC follows the VM name now. Hosts that leavekvm_vm__nameat its default keep the MAC they had; on a host that sets it, a VM created from now on gets a different MAC, so check DHCP reservations and firewall rules keyed on it before recreating such a VM. Running VMs are not touched. - role:keycloak: A run against an unchanged host reports no changes any more. The tarball is only downloaded and extracted when the installed version differs from
keycloak__version, andkc.sh buildonly runs when the installation orkeycloak.confactually changed, which also takes minutes off an ordinary run. - role:php: The PHP-FPM slowlog holds the backtrace of a slow request on RedHat, instead of staying empty while php-fpm logs
failed to ptrace(ATTACH) child <pid>: Operation not permitted (1). - role:openvpn_server: A new server certificate, a changed
server.confor a regenerated Diffie-Hellman file restarts OpenVPN. Until now the files were written to disk while the running service kept its old configuration, so a renewed certificate only took effect at the next reboot. The certificate revocation list and the client configs still apply without a restart, since OpenVPN re-reads them per connection. - role:apache_httpd: Set
apache_httpd__mod_ssl_ssl_use_staplingto off by default because Let's Encrypt does not provide an OCSP URL-endpoint. - plugin:bitwarden_item, module:bitwarden_item: A vault that is not unlocked is reported with the
bw serveendpoint it was read from and the status it actually has, plus the hint thatbw servekeeps the session it was started with. The previous message pointed atbw loginandbw unlock, which do not reach a runningbw serve. - plugin:bitwarden_item: Error messages no longer carry a doubled period in the middle.
- role:rocketchat: The environment file no longer sets
MONGO_OPLOG_URL, which Rocket.Chat has ignored since 5.0.1. A host without a MongoDB replica set also gets a usable environment file again, instead of one whose MongoDB URL and port ended up on the same line. - role:rocketchat: The container image is pulled from Docker Hub directly instead of through
registry.rocket.chat, whose pull rate limit is shared by everyone using it, so image pulls andpodman auto-updateno longer fail withtoomanyrequests. - role:system_update: A requested reboot names the core packages or the running services that ask for it, instead of only listing what the run changed.
- role:system_update: A host with nothing to update no longer sends a "System updated without Reboot" mail on every update day.
- role:system_update: The update mail and the reboot request describe the packages the run just changed instead of those of an earlier run.
- role:system_update: The AIDE database is only refreshed when the update changed packages and the AIDE check was passing beforehand, so a host that was already reporting changes keeps reporting them instead of having them accepted as the new baseline.
- role:system_update: The AIDE database is refreshed after the update rather than before it, on Debian and Ubuntu as well as on RHEL, so the next check no longer flags every file the update touched.
- role:system_update: A failed update on Debian is reported and stops the run, instead of being followed by a success mail or by the reboot of a half-configured host.
- role:schedule_reboot: The role no longer aborts while deploying its reboot helper on Debian 12 and older and on Ubuntu 24.04 and older. Roles that pull it in,
system_updateamong them, were unusable on those releases as well. - role:mariadb_server: On RHEL 8, MariaDB keeps its own SELinux confinement after a package upgrade, by installing
mysql-selinuxthe way the MariaDB packages already do on RHEL 9 and 10. Without it, applications on the same host lose their database connection withPermission deniedas of MariaDB 11.4.13 and 11.8.9. - playbook:icingaweb2, playbook:setup_icinga2_master, role:icingaweb2 update
icingaweb2dependent vars to ensure php.ini valuepost_max_size>upload_max_filesizeby default. - role:monitoring_plugins: A source install installs the dependencies of the Linuxfabrik library, so checks that speak HTTP, MySQL, SMB or WinRM no longer report
Python module "httpx" is not installedand its equivalents. - role:monitoring_plugins: A source install deploys the event plugins, which only the rpm/deb package used to ship.
- role:monitoring_plugins: A source install completes on a minimal installation, which has neither the Python module
ansible.builtin.pipneeds nor an/etc/bash_completion.ddirectory. - role:monitoring_plugins: A source install leaves the plugins, the library and the virtual environment readable and executable for the monitoring user, even when the Ansible controller runs with a hardened umask.
- role:monitoring_plugins: A second source install run against an unchanged host no longer reports changes.
- role:login: Removing a user that had lingering enabled no longer aborts the run.
- role:example: The config-validation handler of the reference role triggers the restart handler it notifies; only the template new roles are copied from was affected, not any role that manages an application.
- role:freeipa_server: Commands and command groups can be assigned to a sudo rule, through the
allow_sudocmdsandallow_sudocmdgroupssubkeys offreeipa_server__sudorules; the formercmdsandcmdgroupsnames never reached FreeIPA and aborted the run withUnsupported parameters. - role:apache_solr:
__apache_solr__java_packagecovers the Java package required by Solr 10. - role:collabora: The WOPI hosts from
collabora__coolwsd_storage_wopi__*reach coolwsd again. Every entry was discarded on load, and access only kept working because coolwsd trusted the first host that happened to connect. Collabora 26.04 drops that fallback, where the result would have been that no document loads at all.
v8.0.0 - 2026-07-31¶
Highlights: Host reboots move to one configurable maintenance window managed by the new schedule_reboot role, so system_update__update_time and the reboot-downtime settings have to be moved in the inventory. dnf_versionlock changes its variable format and no longer unlocks packages that are simply dropped from the inventory. PHP on Debian can be pinned to a declared version instead of drifting with whatever sury promotes, and a fresh installation no longer bounces its services right after starting them. Review the Breaking Changes before updating: php, mariadb_server, apache_httpd and repo_baseos all change defaults.
Breaking Changes¶
- role:dnf_versionlock: Rename
dnf_versionlock__versionlockstodnf_versionlock__versionlocks__group_var/__host_varand change it from a list of strings to a list of dictionaries (name, plus the optionalrawandstatesubkeys). The role no longer rewrites the whole lock list, so locks set elsewhere (for example bymonitoring_plugins) survive, but removing an entry from the inventory no longer unlocks the package: setstate: 'absent'instead. - role:apache_httpd: Role-internal variables are now
__-prefixed. If you copied the SSL/TLS snippet fromEXAMPLES.mdinto a vHostrawblock, renameapache_httpd__openssl_certificate_path,apache_httpd__openssl_privatekey_pathandapache_httpd__openssl_chain_pathto their__-prefixed form, otherwise the vHost fails to render. - role:system_update: Host reboots are now performed at one configurable maintenance window by the new
schedule_rebootrole (see Added). Adjust in your inventory:system_update__update_timetoschedule_reboot__reboot_time__group_var(now a plain time of day, e.g.'04:00'), and anysystem_update__icinga2_*reboot-downtime settings toschedule_reboot__icinga2_*. Also, in most casessystem_update__update_dayshould be used instead ofsystem_update__notify_and_schedule_on_calendar. - role:php: In preparation for the upcoming PHP 8.6,
php__ini_session_cookie_httponlynow defaults toOn, so session cookies are marked HttpOnly and are no longer accessible to JavaScript viadocument.cookie. This matches the hardened session defaults PHP 8.6 ships. Applications that must read the session cookie from JavaScript have to setphp__ini_session_cookie_httponly__group_var: 'Off'(or the__host_var) to restore the previous behaviour. - role:php: The default
php__ini_opcache_blacklist_filenamenow points to the distribution-neutral/etc/opcache.blacklistinstead of/etc/php-zts.d/opcache*.blacklist. The old default pointed at the thread-safe (ZTS) config directory, which the non-ZTS PHP-FPM this role deploys never reads. No file exists at the new path by default, so no scripts are excluded from OPcache unless an admin creates one. - role:apache_httpd: The Matomo log-analytics import script (
import_logs.py) and theapache_httpd:matomotag have been removed and moved to the newmatomo_import_logsrole. Hosts that import their access logs into Matomo, or that pipe their access logs to/usr/local/sbin/import_logs.pyfor realtime tracking, must now also run thematomo_import_logsrole, which deploys the script. ThematomoLogFormat itself stays inapache_httpd. - role:repo_baseos: The Rocky Linux
securityrepository now always points at the upstream mirrorlist, even when a customrepo_baseos__mirror_urlis set, so critical CVE fixes keep coming straight from upstream instead of a potentially lagging mirror. Hosts that previously pulled thesecurityrepository from their custom mirror now reach upstream directly. Setrepo_baseos__security_repo_use_upstream: falseto restore the previous behaviour and have thesecurityrepository followrepo_baseos__mirror_urlagain. - role:mariadb_server: The default for
skip_name_resolveis nowOFFinstead ofON. Hosts that relied on the previous default and grant access by hostname keep working, but connections are now resolved via DNS again. Setmariadb_server__cnf_skip_name_resolve__group_var: 'ON'(or the__host_var) to restore the previous behaviour.
Added¶
- role:glpi_agent: Add optional scheduled database inventory via
glpi_agent__database_inventory_enabledandglpi_agent__database_inventory_login, which runsglpi-agent --partial=databaseas a dedicated read-only database user on a systemd timer instead of letting the always-on daemon connect as root on every cycle.glpi_agent__conf_no_categorydisables arbitrary inventory categories andglpi_agent__database_inventory_on_calendarsets the schedule. - role:php: Add
php__versionto declare which PHP version a Debian host runs, for example'8.4', so an ordinaryapt upgradeno longer migrates the host to a new major PHP version on its own. With the sury repo enabled, the unversioned metapackages follow whatever sury currently declares as its default; declaring a version makes the role install the versioned packages, pin thephp,pharandphar.pharalternatives to it, and purge the stacks of all other versions onphp:update. Leave it empty to keep the previous behaviour. Has no effect on RedHat, where the module stream pins the version at repo level. - playbook:php: Now runs the
repo_suryrole on Debian (skip withphp__skip_repo_sury), since sury is what makes any PHP version other than the distribution's own available in the first place. - role:fail2ban: Add
fail2ban__filters__*_var(combined-var pattern,unique_key="filename") so custom filter definitions can be deployed from the inventory in the same generic shape asfail2ban__jails__*_var. The built-inapache-dosandportscanfilters move intofail2ban__filters__role_varwith no behaviour change, and can now be opted out viastate: 'absent'. - role:postfix: Add
postfix__recipient_canonicals__group_var/__host_varto rewrite recipient addresses via Postfix'srecipient_canonical_maps, mirroring the existing sender canonical rewriting, which is useful for redirecting all mail addressed to a host to a central team mailbox. - all roles: Add
lfops__skip_restart_handlersto deploy configuration changes without restarting the affected services, for example when a bounce has to wait for a maintenance window. Reload handlers still run, since a reload applies the configuration without an outage. Note that the skipped restart is not remembered: a later ordinary run finds the configuration already correct and does not restart either, so the service has to be restarted explicitly (--tags <role>:state --extra-vars '<role>__service_state=restarted'). See the README. - Add a service state variable (for example
chrony__service_state,clamav__clamd_service_stateorphp__fpm_service_state) to start, stop, restart or reload the managed service independently of whether it is enabled at boot; it defaults tostartedwhen the role's matching*_service_enabledistrueand tostoppedotherwise, so existing inventories keep their current behaviour (apache_solr, bind, blocky, chrony, clamav, collabora, coturn, fail2ban, glpi_agent, grafana, graylog_datanode, graylog_server, icinga2_master, icinga_kubernetes, icingadb, influxdb, keepalived, opensearch, php, redis, snmp, squid, vsftpd). - role:duplicity: Add Debian and Ubuntu support (proven on Debian 12, Debian 13, Ubuntu 22.04, Ubuntu 24.04 and Ubuntu 26.04), and install the
gnupgpackage itself so backups also work on minimal installs that ship withoutgpg. - role:python_venv: Add an optional per-venv
pip_constraintskey that pins transitive dependencies through a pip constraints file, without having to list them as direct packages. - role:opensearch: Add
opensearch__path_repoto register file system paths aspath.repoinopensearch.yml, required for file system based snapshot repositories. - role:nextcloud: Add
nextcloud__jobs_timeout_start_secto configure the start-up timeout of thenextcloud-jobs.service, defaulting to10m, for instances where background jobs regularly need longer. - role:icinga2_agent, role:icinga2_master: Deploy a systemd drop-in override ensuring the Icinga 2 service starts after SSSD on hosts where SSSD is installed.
- role:librenms: Add
librenms__config_app_trusted_proxiesandlibrenms__config_app_urlto set theAPP_TRUSTED_PROXIESandAPP_URLvariables in/opt/librenms/.env, needed when running LibreNMS behind a reverse proxy. - role:mariadb_server: Add
mariadb_server__cnf_innodb_flush_neighbors__group_var/__host_varto configure theinnodb_flush_neighborsInnoDB system variable, defaulting to0, which is the recommended value for SSD and NVMe storage. - role:freeipa_server: Add
freeipa_server__limit_groups,freeipa_server__limit_hbacrules,freeipa_server__limit_hostgroups,freeipa_server__limit_pwpolicies,freeipa_server__limit_sudocmdgroups,freeipa_server__limit_sudocmds,freeipa_server__limit_sudorulesandfreeipa_server__limit_usersto manage only specific resources via--extra-vars, which speeds up deployments on servers with many FreeIPA resources. - role:vsftpd: Add
vsftpd__pam_use_userdbto authenticate virtual users viapam_userdbagainst/etc/vsftpd/login.db, so virtual-user logins work instead of failing against the local-user PAM stack the role always rendered. - role:opensearch: Add
opensearch__heapto set the JVM heap size via a drop-in at/etc/opensearch/jvm.options.d/heap.options, defaulting to 50% of system memory capped at 31 GB. - role:trend_micro_v1es: Add a role to install and activate the Trend Vision One Endpoint Security agent (Endpoint Sensor and Server & Workload Protection).
- role:matomo_import_logs: New role that imports Apache access logs into Matomo on a schedule, one systemd timer per site, and ships the Matomo log-analytics import script (
import_logs.py). Thetoken_authis provided via a per-site auth file instead of the command line, since--token-auth,--loginand--passwordare visible in the process list and now log a deprecation warning. The script also supports the Traefik access-log format. - role:glances: Add RHEL 10 / Rocky 10 / Alma 10 support by installing glances into a Python venv via the
python_venvrole, since the package is not available in EPEL 10. RHEL 10 is now marked proven (x) in COMPATIBILITY. - role:graylog_datanode: Add
graylog_datanode__http_publish_urito set the REST API URI the DataNode advertises, needed when the bind address is not directly reachable (multiple interfaces, a NAT gateway, or a0.0.0.0bind address).
Changed¶
- role:php: The
php:updatetag also deploys the PHP-FPM pools and enables and starts the FPM service, because both live under version-specific paths on Debian, so a host that changedphp__versionwould otherwise run the new version with none of its pools and a unit that was never enabled. - role:fail2ban: README documents the
statesubkey of the filter and jail entries as optional (defaults topresent), notes thatrawonly applies to entries using therawtemplate, and states up front that filters and jails are defined in the inventory. - role:nextcloud: Adds Debian and Ubuntu support alongside Red Hat-family systems, marked
(x)inCOMPATIBILITY.mdsince package names are verified on Debian 13 but the role is not yet proven end to end. SELinux relabeling is skipped automatically on hosts where SELinux is disabled. - role:apache_solr, role:blocky, role:fail2ban, role:rsyslog: The service is started after its configuration has been deployed, not before, so on a fresh installation it comes up with the configuration the role just wrote instead of starting on the package defaults and being restarted afterwards.
- role:duplicity: Validate the role variables at start, and align the task tags with the LFOps vocabulary: the
duplicity:scripttag is gone (thedubascript now deploys underduplicity:configure), and the newduplicity:dumptag manages the backup schedule. - role:schedule_reboot: Hosts without an explicit reboot window are assigned a deterministic minute within the 04:00-04:59 window, staggered by hostname, so a fleet no longer reboots in lockstep at exactly 04:00. Pin
schedule_reboot__reboot_time__group_var(or the__host_var) to keep a specific window. - role:monitoring_plugins: A source install deploys the plugins into a self-contained Python virtual environment and provisions a suitable Python by itself, so it works on RHEL 8 where the system Python 3.6 is too old. The Linuxfabrik library is deployed newest straight from GitHub and the third-party dependencies are installed unpinned, so a source install always tracks the newest code for the selected
monitoring_plugins__version. The dependencies the former source install placed into the home directories of root and the icinga user are cleaned up on the next run. - role:icinga2_agent: The
icinga2_agent:updatetag refreshes the apt cache before the upgrade on Debian-family hosts, so it reliably installs the latest package instead of running against a stale cache. - role:mariadb_server: Databases created via
mariadb_server__databaseswithout an explicitcollationorencodinginherit the server default character set and collation (utf8mb4) instead of being pinned to the legacyutf8/utf8_general_ci. Existing databases are unaffected; setcollation/encodingper database to override. - role:collabora: Support Collabora Online CODE 25.04.10, which had no
coolwsd.xmltemplate and therefore aborted the deploy on hosts that had updated to it. - role:clamav: Send notification mails through
sendmail(provided by postfix) instead of themailcommand (mailx), so one invocation works across distributions and delivery no longer depends on mailx being installed. - role:icingadb, role:icingaweb2, role:icingaweb2_module_reporting, role:icingaweb2_module_x509, role:mariadb_server: Move the MariaDB tasks from the deprecated
community.mysqlcollection to its replacementansible.mysql, so the deprecation warnings printed on every run are gone and the roles keep working oncecommunity.mysqlis removed upstream.
Fixed¶
- A configuration change no longer restarts or reloads a service that the very same run had just started, so a fresh installation no longer bounces the service right after starting it, and no longer starts a service that is configured to stay stopped (apache_httpd, apache_solr, apache_tomcat, bind, blocky, chrony, clamav, collabora, coturn, docker, elasticsearch, fail2ban, glpi_agent, grafana, graylog_datanode, graylog_server, icinga2_master, icinga_kubernetes, icingadb, influxdb, keepalived, kibana, logstash, mariadb_server, mongodb, opensearch, php, postfix, postgresql_server, redis, rocketchat, rsyslog, snmp, squid, sshd, systemd_journald, telegraf, vsftpd).
- role:mariadb_server, role:monitoring_plugins, role:php: The update tags refresh the apt cache before upgrading on Debian-family hosts, so they reliably install the latest packages instead of running against a stale cache. RHEL-family hosts are unaffected, since dnf refreshes its metadata on its own.
- role:mastodon: Modules set via
apache_httpd__mods__host_varin the inventory are no longer discarded, because the role used the wrong dependent variable name. - role:postgresql_server: The
grant_optionsubkey ofpostgresql_server__privstakes effect, and the entry'srolesandstatesubkeys are documented. - playbook:php, playbook:redis, playbook:setup_grav, playbook:setup_moodle: These playbooks enable EPEL (and CRB on Rocky 9 and newer) before installing packages from Remi's repository, which depend on it; on RedHat 8 the run previously aborted with
nothing provides libcapstone.so.4 needed by php-opcache. Skippable via<prefix>__skip_repo_epeland<prefix>__skip_repo_baseos. - role:php: A dry run (
--check) against a host that does not have PHP-FPM installed yet no longer aborts, so the role can be previewed before the first real run. - role:icingaweb2, role:icingaweb2_module_fileshipper, role:icingaweb2_module_vspheredb, role:icingaweb2_module_x509, role:nextcloud: On Debian and Ubuntu, PHP extension names are built from the PHP version the
phprole manages, so the unversionedphp-<module>metapackages can no longer pull a second, undeclared PHP runtime onto the host whenever sury promotes a new default. RedHat is unaffected. - role:nextcloud: The IMAP PHP extension installs on PHP 8.4 and newer, where IMAP was removed from PHP core, by installing it from the PECL package instead of the no-longer-existing
php-imap. - role:php: Running the role with a specific tag such as
--tags php:stateon Debian and Ubuntu no longer fails with an undefined PHP version, so roles that build on php and only restart php-fpm work when run with their own tags. - role:nextcloud: The
nextcloud-ldap-show-remnantsscript no longer aborts thenextcloud:crondeploy with'setup_basic__skip_mailto_root' is undefinedwhen the role runs outside thesetup_basicplaybook; report recipients come fromnextcloud__mail_recipients, defaulting to the globalmailto_root__to. - role:nextcloud: Replace ws.linuxfabrik.io with www.linuxfabrik.ch, since ws.linuxfabrik.io is decommissioned.
- role:icingaweb2_module_grafana:
icingaweb2_module_grafana__auth_jwthonours a quoted'false', which previously enabled JWT authentication and deployed the private key anyway; unquotedtrue/falsebehaved correctly before and are unaffected. - role:shared:
lfops__remove_rpmnew_rpmsavehonours an explicit opt-out, so--extra-vars='lfops__remove_rpmnew_rpmsave=false'keeps the.rpmnew,.rpmsave,.dpkg-distand.ucf-distfiles instead of removing them. Leaving the variable unset was, and still is, safe. - role:apache_tomcat:
apache_tomcat__service_statetakes effect instead of being silently ignored in favour ofapache_tomcat__service_enabled; its default isstartedifapache_tomcat__service_enabledistrueandstoppedotherwise, so hosts that never set it are unaffected. - role:freeipa_server: The
pki-tomcatdstart-up timeout configured viafreeipa_server__systemd_timeoutstartsecis in effect, because the role now applies the same value to systemd and to FreeIPA and reloads systemd. On slow machinesipactl start, server upgrades and CA certificate renewals previously failed with a timeout even though the CA was still coming up. - role:duplicity: Swift backups work out of the box on Python 3.10 and newer, since the role pins a modern
oslo.*stack in the venv, which fixes thecollections.Mappingcrash and drops the deprecatednetifacesdependency. As a result the role no longer installs a C compiler or development headers on backup hosts, which removes the build toolchain from production machines. - role:keycloak: Keycloak is no longer restarted a second time right after it was started on a fresh install, and a configuration change no longer starts the service on hosts that pin
keycloak__statetostopped. - role:nextcloud: Set the
text workspace_availableapp config key asbooleaninstead ofstring, since newer Nextcloud enforces the config lexicon and the text app declares the key asValueType::BOOL. - role:system_update: The update and security-update jobs no longer send a failure mail when a mirror hiccups briefly, because repository metadata is refreshed with a few retries before updates are applied.
- role:mod_maxminddb, role:monitoring_plugins: The role no longer aborts at start demanding a variable that has an OS-specific default (
monitoring_plugins__icinga_userrespectivelymod_maxminddb__apache_conf_modules_d), so there is no need to set it in the inventory. - role:monitoring_plugins: A source install no longer aborts on RHEL 8, where the system Python 3.6 is older than the required 3.9; the role installs and uses Python 3.9 automatically.
- role:python_venv: Install
python3-packagingon EL10, which ships Python 3.12 without the stdlibdistutils, so Ansible'spipmodule can create a venv again. - role:icingaweb2_module_vspheredb: Download the module tarball from the canonical
archive/refs/tags/<version>.tar.gzURL, so the pinned release tag is fetched reliably. - role:monitoring_plugins: A source install deploys the sudoers drop-in as
/etc/sudoers.d/linuxfabrik-monitoring-plugins, the same file name the packages use, and both install methods remove the drop-in under the former name, so sudo no longer warns about a duplicateCmnd_Alias. - role:collect_rpmnew_rpmsave: Stop emitting an Ansible deprecation warning on every run, which keeps the role working on Ansible 2.19 and later.
- role:kvm_vm: Use
kvm_vm__connect_urlfor every libvirt operation, so disk resizes (virsh blockresize) and a few other steps no longer ignore the configured connection URL and act on the wrong libvirt.
Security¶
- role:opensearch: The OpenSearch data directory is no longer readable by other local users; its root uses mode
0750instead of2755, matching the OpenSearch package default. - role:monitoring_plugins: A source install leaves the plugins, the bundled library and the dependency venv owned by root instead of the monitoring user, closing a local privilege escalation in which that account could edit a plugin, a library module or the venv interpreter that runs as root via sudo.
v7.0.0 - 2026-06-11¶
Highlights: setup_basic gains three CIS-oriented hardening roles (core_dumps, kernel_modules, login) and the sshd defaults are tightened, which stops sessions that rely on X11 or agent forwarding and can lock out clients offering more than three keys. Reboots move to one windowed mechanism in the new schedule_reboot role. Tags were renamed across a dozen roles and the MinIO roles were removed, so review your --tags invocations and any object-store backup first. RHEL 10 is now proven for the roles setup_basic runs.
Breaking Changes¶
- Internal OS-specific variables are
__-prefixed to mark them as not overridable from inventory. Rename any inventory override ofdnf_versionlock__list_path,dnf_versionlock__packagesor a role's*__icingaweb2_ownervariable to the__-prefixed form; the values are unchanged (dnf_versionlock, icingaweb2_module_businessprocess, icingaweb2_module_company, icingaweb2_module_cube, icingaweb2_module_fileshipper, icingaweb2_module_generictts, icingaweb2_module_incubator, icingaweb2_module_pdfexport, icingaweb2_theme_linuxfabrik). - plugin:combine_lod, role:apache_httpd, role:mariadb_server, role:proxysql, role:selinux: A composite
unique_key(a list of keys) now requires every component to be set on each item, instead of letting one be filled by a downstream default. Set the previously optional component explicitly:virtualhost_porton everyapache_httpdvHost,hoston everymariadb_serveruser/role,porton everyproxysqlserver, andprotoon everyselinuxport. Otherwise the play fails with a clear error. - role:apache_httpd, role:apache_tomcat, role:mastodon, role:postgresql_server: Rename tags to the project-wide naming scheme.
apache_httpd:configbecomesapache_httpd:configure, andapache_tomcat:users,mastodon:users,postgresql_server:usersandpostgresql_server:databaseslose their trailings(...:user,...:database). Adjust any--tags/--skip-tagsinvocations and automation that reference the old tag names. - role:sshd: Ship hardened SSH defaults that change the behaviour of existing installations on the next run: X11 forwarding, agent forwarding and TCP keepalives are now off,
MaxAuthTriesis lowered to3,ClientAliveCountMaxto2, andLogLevelis raised toVERBOSE. Sessions relying on X11 or agent forwarding stop working, and a client offering more than three keys from its SSH agent can be locked out. Restore the previous behaviour where needed via the new variables:sshd__x11_forwarding: true,sshd__allow_agent_forwarding: true,sshd__tcp_keep_alive: true,sshd__max_auth_tries: 6,sshd__client_alive_count_max: 3,sshd__log_level: 'INFO'. Additionally configurable aresshd__allow_tcp_forwardingandsshd__max_sessions. - role:apache_httpd, role:apache_solr, role:freeipa_server, role:grav, role:icingaweb2, role:influxdb, role:mariadb_server, role:mongodb, role:nextcloud, role:opensearch: Align section tags to the controlled vocabulary, which uses plural names for sections that manage multiple objects. The
:usertags become:users, the:databasetags become:databases, andapache_httpd:configbecomesapache_httpd:configure. Adjust any--tags/--skip-tagsinvocations and automation that reference the old tag names. - role:minio_client, role:objectstore_backup: Both roles and their playbooks (
playbooks/minio_client.yml,playbooks/objectstore_backup.yml) have been removed, along with the corresponding role blocks inplaybooks/setup_nextcloud.ymland thesetup_nextcloud__skip_minio_client/setup_nextcloud__skip_objectstore_backupvariables. MinIO Server has been archived as no-longer-maintained since February 2026, and we are moving away from using object storage for critical data. Users relying on these roles must replace the MinIO-based object-store backup with their own solution (e.g.rclone); themcbinary, its config under/etc/mc/, theobjectstore-backupsystemd timer/service, and/usr/local/bin/mc-mirror.share no longer managed by lfops and will remain on existing hosts until removed manually (#241). - role:infomaniak_vm: Always create a managed port for every entry in
infomaniak_vm__networks, even when nofixed_ipis set. Previously only networks with afixed_ipgot a managed port; networks without one relied on OpenStack's auto-created port. To avoid creating unused (but billed) managed ports on VMs provisioned under the old behavior, make sure to manually rename the existing port in OpenStack to match theport_name. Note that this port will not survive VM deletion / detachment, since it was automatically created and therefore is owned by OpenStack, not the user. - role:shared: The Apache httpd user and group are defined once as
__shared__apache_httpd_user/__shared__apache_httpd_groupand loaded into every playbook through a newglobal-variables.ymltask inpre_tasks, instead of being repeated in thevars/of around 20 roles. Running one of those roles ad-hoc outside the bundled playbooks now requires importingshared'sglobal-variables.ymlfirst. On Suse, themonitoring_pluginsweb files use the correct apache groupwwwinstead ofwwwrun. - role:crypto_policy, role:duplicity, role:icingaweb2, role:icingaweb2_module_x509, role:mariadb_server, role:php: The internal package-selection dicts behind the OS-keyed default lookups are no longer overridable from inventory; they were never meant to be. Behaviour is unchanged on supported platforms.
Added¶
- all roles: Role variables are validated at role entry through
meta/argument_specs.yml, so a type mismatch or a missing mandatory variable in the inventory fails immediately with a clear message instead of an obscure error later in the run. - role:schedule_reboot: New role providing a single, windowed reboot mechanism: a request spool (
/run/schedule-reboot/), an ad-hocschedule-rebootcommand, and one actor that performs a single reboot for all pending requests at a configurable window (schedule_reboot__reboot_time__*), setting an Icinga downtime around it. Other roles request a reboot instead of rebooting themselves;system_updateuses it. - role:core_dumps: New role that disables core dumps, which can leak sensitive process memory to disk, following the CIS Benchmark recommendations. Runs as part of
setup_basic. - role:kernel_modules: New role that hardens a host by blocking rarely used or risky kernel modules (FireWire, legacy filesystems, uncommon network protocols) following the CIS Benchmark recommendations, and runs as part of
setup_basic. The defaults stay clear of modules that would break common workloads such as containers, snap and USB storage. - role:login: New role that sets a password-aging policy and a stricter default umask in
/etc/login.defs, applying to newly created accounts and password changes rather than retroactively. - role:chromium_headless: New role providing a hardened, socket-activated headless Chromium backend for tools such as the Icinga Web 2 PDF Export Module, started on the first request and stopped again after an idle timeout so it uses no RAM while unused. Installs
chromium-headlessfrom EPEL instead of Google's proprietary repository. - role:tmux: New role that installs tmux and deploys a system-wide
/etc/tmux.confwith a larger scrollback buffer and mouse support. Selections are copied to the local clipboard over SSH via OSC 52 where the terminal supports it, andprefix + Pdumps a pane's whole scrollback buffer to a file. - role:hostname: Maintains an
/etc/hostsentry mapping the FQDN and short name to the host's primary IPv4 address, configurable viahostname__etc_hosts_ipand disablable withhostname__manage_etc_hosts: false. - role:uptimerobot, plugins/modules/uptimerobot_*: New role and nine custom modules to manage UptimeRobot resources from a playbook:
uptimerobot_monitor,uptimerobot_mwindowanduptimerobot_pspfor CRUD,uptimerobot_alert_contactfor deletion only (UptimeRobot API v2 does not expose creating contacts), plus five read-only info modules. All CRUD modules support--checkand--diffand are idempotent on re-run. Configured viauptimerobot__monitors,uptimerobot__mwindows,uptimerobot__pspsanduptimerobot__alert_contacts; the API key comes from theapi_keyparameter,api_key_file(default~/.uptimerobot) orUPTIMEROBOT_API_KEY. - plugin:platform_select: New filter plugin for selecting a value from a platform-keyed dictionary by OS family, distribution or version.
- role:system_update: Add a security lane for Rocky Linux: a daily timer installs only Rocky Linux security hot-fixes from the dedicated
securityrepository and requests a reboot if needed, performed at the host's maintenance window. Enabled by default, a no-op where thesecurityrepository is not enabled, and turned off withsystem_update__security_enabled: false. - role:repo_baseos: Add the Rocky Linux
securityrepository for critical CVE fixes, enabled by default. Opt out per host or group viarepo_baseos__security_repo_enabled__host_var/__group_var. - role:sshd: Add Debian 13 and Ubuntu 22.04 / 24.04 / 26.04 support and run on Fedora. On Debian and Ubuntu the role manages the correct service unit (
ssh.service) and disables OpenSSH socket activation (ssh.socket), and Red Hat-family releases without a version-specific template fall back to a genericRedHatsshd_configtemplate instead of failing. - role:icinga2_master, role:icingadb, role:icingaweb2, role:icingaweb2_module_reporting, role:icingaweb2_module_x509: Add explicit Ubuntu variable files, making Ubuntu support visible alongside Debian. The Icinga repository, GPG key and package names were verified on Debian 13 and Ubuntu 24.04.
- role:libmaxminddb, role:mod_maxminddb: Run on Debian and Ubuntu in addition to Red Hat-family systems, with the Apache module enabled automatically on Debian and Ubuntu.
- role:monitoring_plugins, role:repo_monitoring_plugins: Add SLES 15 and SLES 16 support, installing the Linuxfabrik Monitoring Plugins from the SUSE channel of
repo.linuxfabrik.chand applying the SUSE-specific package version lock (#245). - role:repo_remi: Add RHEL 10 / Rocky 10 support with a new GPG key, repo templates and module-stream tasks for EL 10.
- role:repo_monitoring_plugins: Add
repo_monitoring_plugins__testing(defaultfalse) to switch from thereleaseto thetestingchannel. On Red Hat-family systems a single/etc/yum.repos.d/linuxfabrik-monitoring-plugins.repois deployed containing both channel sections withenabled=toggled by the variable, so DNF metadata for both can stay cached across switches; on Debian and Ubuntu the-releasesuffix in the apt sources file is replaced with-testing. - role:graylog_server: Make more HTTP, Elasticsearch, processing/output buffer and message journal settings configurable via
graylog_server__http_external_uri,graylog_server__http_enable_cors,graylog_server__elasticsearch_max_total_connections,graylog_server__elasticsearch_max_total_connections_per_route,graylog_server__output_batch_size,graylog_server__processbuffer_processors,graylog_server__outputbuffer_processors,graylog_server__ring_size,graylog_server__inputbuffer_ring_size,graylog_server__message_journal_max_ageandgraylog_server__message_journal_max_size. - role:graylog_datanode: Add
graylog_datanode__raw, plusgraylog_datanode__path_reposandgraylog_datanode__node_search_cache_sizeto configure searchable snapshot locations and the size of the disk-based searchable snapshot cache. - role:graylog_datanode, role:graylog_server: Add template for Graylog 7.1.
- role:mariadb_server: Make
aria_pagecache_buffer_size,key_buffer_sizeandsort_buffer_sizeconfigurable via the correspondingmariadb_server__cnf_*variables, and addmariadb_server__cnf_innodb_snapshot_isolation(MariaDB 10.6+), defaulting to'ON'. - role:elasticsearch: Add optional variables
elasticsearch__cluster_routing_allocation_disk_watermark_flood_stage_frozenand the four corresponding*_max_headroomvariables. - role:kibana: Add
kibana__loggingto make thelogging:block inkibana.ymlfully user-configurable (appenders, loggers, root, rotation). The default preserves the previous behaviour: JSON logs at/var/log/kibana/kibana.log, rotated daily, 14 rotations kept. - role:logstash: Add optional variables
logstash__monitoring_cluster_uuidandlogstash__monitoring_enabled. - role:alternatives: Support managing
subcommands(slaves/followers) and the Red Hat-onlyfamilygrouping, ensure the alternatives tooling is installed, and allow the role to be included without variables as a no-op. - role:at, role:dnf_makecache, role:open_vm_tools, role:qemu_guest_agent: Add service state variables (
at__service_state,dnf_makecache__service_stateand__timer_state,open_vm_tools__service_enabledand__service_state,qemu_guest_agent__service_state) to control the running state independently from boot autostart. Default behaviour is unchanged. - role:infomaniak_vm: Add the
keep_port_on_absentsubkey oninfomaniak_vm__networksentries to preserve the port and its fixed IP when the VM is set toabsent, so the same IP can be re-used, andport_nameto override the managed port's name. - role:mirror: Document the per-repository
newest_onlysubkey onmirror__reposync_reposentries, defaulting totrue. Set it tofalsefor repositories that publish multiple versions in parallel, such as Icinga. - role:redis: Add template for version 8.8.
- playbooks/setup_basic: Add
setup_basic__skip_policycoreutilsto skip thepolicycoreutilsrole, matching the pattern used by the other roles in the playbook.
Changed¶
- all roles: The role READMEs follow one standard format and explain what the underlying software actually is and when an admin would want it, instead of only naming it. Install behaviour, upgrade paths, role scope and previously undocumented variables are spelled out, and tags and variables are bullet lists instead of markdown tables.
- COMPATIBILITY: RHEL 10 is promoted to proven (
x) for the 23 roles thatsetup_basicexercises, Ubuntu 26.04 is added, the EOL Debian 11 and Ubuntu 20.04 columns are dropped, and roles that are expected to work but are untested are marked(x).glancesstays at(x)because the package is missing in EPEL 10. - role:nextcloud: Automatic app updates are enabled by default (
nextcloud__timer_app_update_enabled), and the scheduled update only switches Nextcloud into maintenance mode when an app update is actually pending, so an instance that is already up to date keeps serving requests. The recommended database migrations are applied afterwards, and a failed run no longer leaves the instance stuck in maintenance mode. - role:keycloak: The bootstrap admin credentials no longer stay in
/etc/sysconfig/keycloakafter the first run. The role writes them, waits for Keycloak to consume them on startup, re-renders the sysconfig file without them, and stores a state marker so subsequent runs skip the credential render;keycloak__admin_logincan then be removed from the inventory. For disaster recovery, delete the marker file, re-add the variable and re-run. A-tempsuffix on the initial admin username is recommended so it is obvious which account must be deleted once a permanent admin exists. - role:icinga2_master, role:icingadb: Validate the Icinga 2 configuration before restarting the service, so a faulty config fails the playbook run loudly instead of bouncing the daemon into a broken state and leaving Icinga 2 down.
- role:clamav: Runs on Debian and Ubuntu in addition to Red Hat-family systems, and works on RHEL 10. The role seeds the signature database on first install so the scanner starts reliably, and runs an EICAR self-test (also available via the
clamav:testtag) that confirms detection actually works. - role:acme_sh: Issue ECDSA P-256 certificates by default instead of RSA-4096, for faster TLS handshakes at equivalent security. Certificates previously issued as RSA are reissued as ECDSA on the next run and the superseded RSA certificate is dropped from renewal; set
acme_sh__key_lengthto an RSA value such as4096to keep RSA. - role:mailto_root: Send the verification mails via
sendmail(provided bypostfix) instead of themail(mailx) command, completing the move offmailx, so the role no longer needs themailxpackage installed. - playbooks: Roles that target the whole RHEL family run on any enterprise distribution that is not Fedora, instead of an explicit list of major versions, which adds support for RHEL 10 and future releases without further changes. The CRB repository is now also enabled on Rocky 10, which previously left dependencies such as
python3-virtualenvuninstallable. - role:grafana: Apply the systemd/chkconfig workaround on RHEL 10 as well, not just RHEL 9.
- role:tools: Install the German locale package (
glibc-langpack-de) on RHEL 10 as well, and no longer install tmux; use the dedicatedtmuxrole instead, which ships a configuration with sensible defaults. - role:repo_baseos: The Rocky 8
securityrepository matches Rocky 9 and 10: it adds the disabledsecurity-debuginfoandsecurity-sourcesub-repositories, a 6-hour metadata expiry so emergency hot-fixes are noticed quickly, and the$rltypemirrorlist variable. - role:redis: Bump the default for
net.core.somaxconnfrom1024to4096to match the RHEL 9 and RHEL 10 kernel default and the current Redis upstream recommendation. RHEL 9 and 10 hosts see no effective change; RHEL 8 hosts now get4096. - role:monitoring_plugins:
install_method: 'source'reads the per-Python-LTS lockfile underlockfiles/pyXX/requirements.txtfrom both themonitoring-pluginsandlibrepos, picking the directory that matches the target host's Python, since the previous root-levelrequirements.txtno longer exists upstream. - role:system_update: Change the default of
system_update__update_timeso updates are spread deterministically across 04:00-04:59, with the minute derived frominventory_hostname, instead of all hosts firing at 04:00 sharp. - role:apache_httpd: Bump the Core Rule Set to 4.27.0, and update the two reverse-proxy snippets in
EXAMPLES.mdto useProxyPassinstead ofRewriteRule, which%-decodes the URI pattern and breaks WebDAV apps such as Nextcloud on rename. See the blog post. - role:firewall: Install
nftablestogether withiptablesforfirewall__firewall == "fwbuilder"on all distros, instead of only on Fedora and RHEL 8/9. - role:graylog_server: Update the
server.conftemplates to includetelemetry_enabled = false. - role:network: Scope the
hc-utilsremoval task to Red Hat-family hosts, since Hetzner shipshc-utilsas RPMs only. No behaviour change on either family. - plugin:gpg_key: Refresh the bundled GPG helper library so the module keeps working on current Python and GnuPG releases, and make the
gnupghomeparameter expand~and resolve relative paths as documented. Existing playbooks are unaffected. - role:motd: Update the default value of
motd__legal_notice.
Removed¶
- role:repo_remi: Drop support for RHEL 7 and Fedora 35, both EOL, along with their per-platform task, vars and template trees.
- role:freeipa_client: Remove the dead-code defaults
freeipa_server__config_default_shell,freeipa_server__config_password_expiration_notification,freeipa_server__domainandfreeipa_server__realmfromdefaults/main.yml; they were never read by the role.
Fixed¶
- role:repo_elasticsearch, role:repo_grafana, role:repo_graylog, role:repo_icinga, role:repo_influxdb, role:repo_mariadb, role:repo_mongodb, role:repo_monitoring_plugins, role:repo_mydumper, role:repo_opensearch, role:repo_proxysql, role:repo_redis, role:repo_sury: Refreshing the apt cache is no longer reported as a change on every run.
- roles: Controller-side downloads and git clones delegated to localhost are no longer skipped when the first targeted host happens not to need them, which previously risked leaving later hosts without the downloaded artifact.
- roles: Set
become: falseon tasks delegated to localhost across the collection, so they no longer try to callsudoon the Ansible controller and fail withsudo: a password is requiredwhere passwordless sudo is not set up (#242). - role:repo_remi: Enabling the php, composer and Redis module streams is idempotent, so repeated runs no longer report a change or briefly disable and re-enable the stream.
- role:proxysql:
mysql_serversentries are deduplicated by their actualaddressfield; the merge key referenced a non-existenthostnamefield, so multiple backends sharing a host group and port were silently collapsed into one. - role:repo_influxdb: Prevent the
influxdata-archive-keyringpackage from being installed on both Enterprise Linux and Debian, since it drops a second repo file pointing at upstream that is not managed by LFOps. - role:php: php-fpm workers run with a defined
PATH, which previously was empty and broke PHP code that shells out to system binaries and tripped Nextcloud's "PHP getenv" setup warning. - role:redis: The Redis configuration file is no longer world-readable; it is deployed as
root:rediswith mode0640, so a configured password can no longer be read by other local users. - role:acme_sh: No longer reinstalls every certificate and reloads the web server on every run; certificates are only reinstalled when they were just (re)issued or when the installed file is missing.
- role:keycloak: The role prints a clear instruction when a re-run can no longer obtain a token because the bootstrap admin was manually switched over to a permanent account and the bootstrap marker went missing.
- role:keycloak: Fix ownership under
/opt/keycloak/data/, which the post-install build step left owned byroot:rootso thekeycloakservice user could not write into it; the build now runs as the service user and existing installations are corrected on the next run. - role:keycloak: Fix the transaction timeout silently dropping from 3600s to 300s on Keycloak 26.6.0 and newer, and the MariaDB database encoding defaulting to the deprecated
utf8(utf8mb3) instead ofutf8mb4. - role:mongodb: The role aborts early with a clear message when users are defined while
mongodb__conf_security_authorizationis disabled, instead of failing with a confusing authentication error, and the dump config no longer writes login credentials in that case. - role:kernel_settings: The
systemd_cpu_affinitysetting is actually applied; the value was computed and shown in the debug output but never passed to the underlying system role. - role:icingaweb2_module_pdfexport: PDF export works out of the box, because the headless browser backend the module needs is installed and configured automatically via the new
chromium_headlessrole instead of having to be set up by hand. - role:nextcloud: The
nextcloud-updatescript owns the maintenance mode lifecycle itself instead of expecting callers to enable it beforehand, which disabled the LDAP user provider and made thebefore-updateexport silently omit LDAP users. Callers must drop the manualmaintenance:mode --onstep from their pre-script workflow and rely on--single-transactionfor the DB dump instead. - role:nextcloud: Ensure that the Nextcloud OCC is executable.
- role:graylog_server: Fix the
graylog_server:configure_defaultsrun aborting on Graylog 7.0 and newer withUnable to map property can_be_defaultwhile creating the default index set, by removing the property; Graylog 7.x dropped it and 6.x ignored it. - role:graylog_server: Validate that each
graylog_server__system_inputsentry setsglobal: trueor assigns anode, which was marked mandatory but never enforced. - role:graylog_datanode, role:graylog_server: Validate that the
password_secretis at least 16 characters long. - role:graylog_datanode: Fix the
Conditional result ... was of type 'str'deprecation warning. - role:nodejs: Fix
@nodejs:<stream>install failing withbroken groups or modules, by resetting the module first whennodejs__dnf_module_streamis set and installing the explicit/commonprofile. - role:blocky: The
validate config & restart blocky.servicehandler is notified when the blocky binary changes, so the service is restarted after an update. - role:mariadb_server: Stop writing the deprecated
innodb_buffer_pool_chunk_sizesetting for MariaDB 10.11, 11.4 and 11.8, which ignore it and derive the chunk size frominnodb_buffer_pool_size. The role aborts at the start of the run with a clear error ifinnodb_buffer_pool_chunk_size(on MariaDB 10.11+) orinnodb_file_per_table(on MariaDB 11.0+) is still set in inventory, so an upgrade from 10.6 to 11.x does not silently keep a stale override. - role:mariadb_server: Fix MariaDB starting in the
unconfined_service_tSELinux domain on RHEL 10, which mislabels/var/lib/mysql/mysql.sockand breaksphp-fpmandhttpd_tclients such as Icinga Web 2 login. The role sets themysqld_exec_tfile context persistently viasemanage fcontextandrestorecon, since the previouschconworkaround cannot relabel the binary under EL10's read-only/usrservice sandbox. - role:icinga2_master: Fix the
selinuxrole failing on RHEL 10 withSELinux boolean icinga2_can_connect_all is not defined in persistent policy, by installingnagios-selinuxfrom EPEL first so its%postregisters the types thaticinga2-selinuxreferences. - role:redis: Fix
No package redis available.on RHEL 10, where Red Hat replaced Redis with the compatible Valkey in AppStream and Remi no longer ships Redis for EL10. The role installsvalkeyon EL10 and guards the Redis Stackloadmoduledirectives that do not exist on Valkey; EL8 and EL9 keep installing Redis unchanged and the user-facingredis__conf_*variables stay backwards-compatible. - role:openvpn_server: Fix
invalid selinux contexton RHEL 10 when deployingserver.p12andcrl.pem, by usingetc_tthere since theopenvpn_etc_ttype no longer exists in the RHEL 10 core policy. - role:repo_epel: Fix a malformed RHEL 10
epel.repo, where a missing newline renderedenabled=0username=<login>whenrepo_epel__basic_auth_loginwas set and dnf rejected the file. - role:repo_mariadb: Fix
dnf -y module disable mariadbfailing on RHEL 10, where modularity was removed, by scoping the task and themodule_hotfixesdirective to RHEL 8 and 9. - role:infomaniak_vm: Apply the VM's security group on the
ext-net1port instead of only on the server, since Neutron enforces the port's security groups when a VM boots against a pre-created port, and stop passingsecurity_groupstoopenstack.cloud.server, which failed on internal-network ports withport_security_enabledset tofalse. - role:haveged: Setting
haveged__service_state: 'stopped'no longer produces the invalid systemctl commandstopp, so all four valid values work as expected. - role:influxdb: Always install
curl, which is required to start influxdb but missing as a package dependency. - role:redis: Add the missing paths for running against Debian.
- role:logstash: The default
logstash__java_optssets the JVM heap size to 60% of total memory, capped at 8g. - role:mount: Fix the
whencondition for NFS/CIFS client package installation failing with multiple mounts and when thestatekey is undefined. - execution-environment: Add the missing
sshpasssystem package, required for SSH password-based connections such as--ask-pass. - plugin:nextcloud_occ_app_config: An
arrayconfig value is compared as JSON, so a key whose stored value already matches no longer reports a change and re-runsocc config:app:seton every run. - plugin:bitwarden_item: The module no longer writes to the Bitwarden vault in check mode (
--check), and a run withoutpasswordno longer overwrites an existing item's password. - plugin:sqlite_query: A failed query fails the task instead of reporting success with the error text in
query_result, and aREGEXPquery against a column containing NULL values no longer fails. - plugin:uptimerobot_*: The modules no longer crash when the UptimeRobot API returns a non-list response for a list endpoint.
- plugin:bitwarden_item, plugin:combine_lod, plugin:gpg_key, plugin:nextcloud_occ_app_config, plugin:nextcloud_occ_system_config, plugin:uptimerobot_monitor, plugin:uptimerobot_psp: Fixed the plugin documentation so
ansible-docrenders it again, and corrected thegpg_keydocs, which claimed a separatepython-gnupginstall is required and named the returned key field wrongly. - playbooks/clamav, playbooks/duplicity, playbooks/fangfrisch, playbooks/influxdb, playbooks/mongodb, playbooks/python_venv: Enable
repo_baseos(CRB) andrepo_epelon Rocky 9 and newer before thepython_venvrole, to fixNo match for argument: python3-virtualenv. - playbooks/setup_graylog_datanode, playbooks/setup_graylog_server, playbooks/setup_icinga2_master, playbooks/setup_rocketchat: Extend the
repo_baseosandrepo_epelconditions to Rocky and RHEL 10. - playbooks/freeipa_client, playbooks/freeipa_server: Set
strategy: 'linear'explicitly, so the playbooks work even when the user'sansible.cfgdefaults to a strategy that reuses the target Python interpreter, which otherwise fails withAPI.bootstrap() already called. - role:repo_monitoring_plugins: Add the missing
run_once: trueon the local repo-key download task on Red Hat platforms, so the key is downloaded once per run instead of once per host.
Security¶
- plugin:gpg_key: The cleartext passphrase is no longer included in the module's failure output when key generation fails.
- role:repo_*: HTTP basic auth credentials are only written to the repository config files when a custom mirror URL is set. Previously, setting
lfops__repo_basic_auth_loginwithoutlfops__repo_mirror_urlwrote the credentials into repo files that still pointed at the public vendor mirrors, so the package manager sent them to servers that do not use basic auth. The Icinga repo is intentionally unchanged, since its subscription URL legitimately requires basic auth.
v6.0.1 - 2026-04-07¶
Fixed¶
- ci: Strip badges from README.md before publishing to Galaxy, as external images are not rendered
v6.0.0 - 2026-04-07¶
Breaking Changes¶
- role:nfs_server: Rework
nfs_server__exportsfrom a list of strings to a list of dictionaries with newpath,clients,owner,group, andmodesubkeys - role:kvm_host: Change NAT to be explicitly activated for virtual nets
- role:apache_httpd: Change the default to not install/enable mod_qos by default (it is no longer shipped in EPEL 10)
Added¶
- Add MkDocs-based documentation site, deployed automatically to GitHub Pages via
tools/build-docsand a GitHub Actions workflow - CONTRIBUTING: Document semantic parameter ordering for Ansible modules
- playbooks: Add
example.ymlandsetup_example.ymlplaybooks as development references - role:example: Add complete example role with defaults, handlers, tasks, templates, and vars as a reference for consistent role development
- role:icingaweb2_module_grafana: Add JWT support
- role:grafana: Add JWT support
- Add
playbooks/README.mddocumenting all playbooks with their roles in execution order and available skip variables - role:apache_httpd: Add platform-specific behavior section, wsgi example, and document localhost endpoints in README
- role:apache_httpd: Add skip variables section to README linking to relevant playbooks
- role:mailx: Add skip variables section to README linking to relevant playbooks
- role:policycoreutils: Add skip variables section to README linking to relevant playbooks
- role:yum_utils: Add skip variables section to README linking to relevant playbooks
- plugin:bitwarden_item: Add file-based item cache to reduce
bw serveAPI calls, preventing crashes under load. Cache is stored in$XDG_RUNTIME_DIR(RAM-backed tmpfs) with/tmpfallback. After create/edit operations, the cache is updated inline to avoid expensive full re-syncs, with a 1-second sleep as rate limit to prevent Bitwarden API errors. Convertis_unlockedto a property to fix it never being called. - role:freeipa_server: Add
--diffsupport for all FreeIPA modules and addfreeipa_server:configuretag - role:mariadb_server: Add
mariadb_server__cnf_wsrep_log_conflictsandmariadb_server__cnf_wsrep_retry_autocommitvariables - role:mariadb_server: Add
mariadb_server__cnf_wsrep_gtid_modevariable to configurewsrep_gtid_modefor Galera - role:openvpn_server: Add
openvpn_server:crltag to allow deploying the certificate revocation list independently - role:nextcloud: Add Icinga2 set / unset downtime functionality to
nextcloud-update.j2 - execution-environment: Add mitogen
- role:nfs_client: Add optional
owner,groupandmodesubkeys for mount point directories - role:logstash: Add support for deploying custom grok pattern files to
/etc/logstash/patterns/ - role:mount: Add optional
ownerandgroupsubkeys for mount point directories - role:elasticsearch: Add logrotate config for daily rotation
- role:freeipa_server: Add the ability to specify the systemd unit start timeout
- role:postfix: Add RHEL 10 support
- role:kvm_vm: Add the ability to resize disks
- role:infomaniak_vm: Add the ability to choose the deployment region/datacenter
- role:crypto_policy: Add RHEL 10 support
- role:elastic_agent: Add new role
- role:elastic_agent_fleet_server: Add new role
- role:fail2ban: Make
bantimeconfigurable for the sshd and portscan jails - role:duplicity: Add support for RHEL 10
- role:php: Make
request_slowlog_timeoutandrequest_terminate_timeoutconfigurable - role:graylog_server: Make
http_publish_uriconfigurable; maketrusted_proxiesconfigurable - role:graylog_datanode: Add template for 7.0
- role:graylog_server: Add template for 7.0
- role:lvm: Add new role
- role:logrotate: Add support for RHEL 10
- role:sshd: Add support for RHEL 10
- role:yum_utils: Add support for RHEL 10
- role:repo_epel: Add support for RHEL 10
- role:repo_baseos: Add support for RHEL 10
- role:policycoreutils: Add support for RHEL 10
- role:mailx: Add support for RHEL 10
- role:graylog_server: Make
message_journal_dirconfigurable - playbook:setup_basic: Add lvm role
Changed¶
- ci: Publish pre-releases directly to prod Ansible Galaxy instead of galaxy-dev, since it is unreliable and pulp-ansible excludes pre-release versions from "latest"
- Update pre-commit hooks to latest versions
- Unify CONTRIBUTING and convert from reStructuredText to Markdown
- roles: Add
backup: trueto allansible.builtin.templatetasks to ensure config file backups before overwriting - role:nextcloud: Refactor
nextcloud-update.j2 - role:keycloak: Rework
keycloak.conftemplate to match Keycloak's default config structure - role:apache_httpd: bump Core Rule Set to 4.24.1
- role:repo_remi: Install Composer from
remi-modularrepository - role:icingadb: Enhance
config.ymltemplate - role:apache_httpd: Improve output; bump Core Rule Set to 4.24.0
Fixed¶
- role:apache_httpd: Fix
apache_httpd__mod_security_coreruleset_versiondefault value in README (4.4.0 -> 4.24.1), fix prefork variable names in README (spare_threads->spare_servers), fix various typos ("best practise", "Tipp") - role:mailx: Fix grammar in task name ("make" -> "makes"), sort template module parameters alphabetically
- role:policycoreutils: Fix grammar in task name ("are" -> "is")
- plugin:bitwarden_item: Fix missing
raisein multipart error handling,breakinstead ofcontinuein multi-term lookup,folder_idwrongly typed aslistinstead ofstrin module, notes default mismatch between documentation and code, and wrong "lookup plugin" wording in module documentation - role:mirror: Fix missing
0440permissions on sudoers file - role:login: Rename sudoers file from
lfops_logintolinuxfabrikto match the kickstart configuration; remove the old file automatically - roles: Fix Ansible 2.19 deprecation warning for conditional results of type
intby using| length > 0instead of| length - role:firewall: Fix fwbuilder repo clone being skipped when
run_oncepicks a host withoutfirewall__fwbuilder_repo_url - role:sshd: Validate sshd config with
sshd -tbefore reloading the service - role:nfs_client: Fix systemd not being aware of new or removed NFS mount units
- role:keycloak: Fix issues preventing Keycloak from starting
- role:systemd_unit: Correct the removal of units
- role:bind: Fix incorrect distribution version comparison in named.conf
- role:python_venv: Fix venv path in remove venv task
- role:apache_httpd: Prevent deployment of mods that should be disabled
- role:repo_postgresql: Remove EOL versions, adjust for RHEL 9 & 10
- role:mariadb_server: Fix the root cause of
/run/mariadb/wsrep-start-position: No such file or directoryafter update of MariaDB (10.11.14 -> 10.11.15 or 11.4.8 -> 11.4.9) - role:ansible_init: Install Ansible Collections from requirements.txt since that file contains the correct versions for running against RHEL 8
- role:kibana: Enable log rotation
- role:kibana: Fix
whenstatement - playbook:setup_icinga2_master: Fix syntax; add missing
kernel_settingsfor MariaDB - lookup_plugin:bitwarden: Make it more robust
- role:monitoring_plugins: Fix installation of package against non-RHEL hosts
- role:rocketchat: Fix typo and order of calls in playbook
v5.1.0 - 2026-01-06¶
Added¶
- role:kibana: Add
kibana__rawvariable - role:elasticsearch: Add
elasticsearch__rawvariable - role:apache_httpd: Add nice ErrorDocuments
- role:kibana: Make SSL settings configurable
v5.0.0 - 2025-11-14¶
Breaking Changes¶
- role:elasticsearch_oss: Rename to
elasticsearch, as both the free and subscription versions are now in the same package - role:repo_elasticsearch_oss: Remove, as both the free and subscription versions are now in the same package
Added¶
- role:acme_sh: Add
acme_sh__reload_cmdto allow setting the local reload command globally for all certificates - role:collabora: Add new template versions
- role:elasticsearch:
- Make
node.rolesconfigurable - Add variables for allocation awareness
- Add
elasticsearch__path_datavariable to configure custom data directory - Improve handling of TLS certificates
- Allow creation of clusters
- role:gitlab_ce: Make the
gitlab.rboptions for default project features, email reply-to address, LDAP integration and the upload path configurable - role:graylog_server: Re-add
graylog_server__elasticsearch_hoststo allow setups without Graylog Data Node - role:kibana: Add new role
- role:mariadb_server:
- Add support for version 11.8 (LTS)
- Make
log_slave_updatesconfigurable - Add
mariadb_server__cnf_server_rawvariable - role:podman_containers: Add option to enable the
podman-auto-update.timer - role:postfix: Add
postfix__lookup_tables__*_varto allow easy deployment of lookup tables - role:redis: Add template for version 8.2
- role:selinux:
- Add handling of SELinux modules
- Add capability to run
restorecon - Add
selinux__policyvariable - role:shell: Add
shell__limit_cmdsto limit executed shell commands - playbook:selinux: Add
selinux__skip_policycoreutilsvariable
Fixed¶
- role:acme_sh: Fix certificate paths for Ubuntu and Debian
- role:apache_solr: Automatically install the correct Java version
- role:elasticsearch:
- Prevent undefined variable error
- Fix default of
elasticsearch__path_data - Set
vm.swappinessto 1 - role:firewall: Ensure
firewalldis installed if chosen - role:icinga2_agent: Deploy logrotate config as hotfix for upstream issue (#188)
- role:icinga2_master: Deploy logrotate config as hotfix for upstream issue (#189)
- role:icingaweb2: Fix Icinga username for Debian
- role:keycloak: Install correct Java version, removing the
keycloak__java_package_namevariable - role:kvm_vm: Fix path
- role:mariadb_server: Fix
/run/mariadb/wsrep-start-position: No such file or directoryafter update - role:mastodon: Adjust to breaking changes in
elasticsearchrole - role:monitoring_plugins:
- Also install
libvia source ifmonitoring_plugins__install_method: 'source'is set - Add workaround for pip on Debian & Ubuntu
- role:openvpn_server: Actually remove CCD with
state: 'absent' - role:repo_mariadb: Fix handling of GPG key for Debian & Ubuntu
- role:repo_opensearch: Deploy correct GPG key for selected OpenSearch version
- role:rocketchat: Fix syntax of HealthCmd
- playbook:opensearch: Prevent the whole cluster from restarting at once
- playbook:setup_icinga2_master:
- Fix order
- Add missing injection for MariaDB Python modules
v4.0.0 - 2025-10-03¶
Breaking Changes¶
- role:icinga2_master: Remove support for IDO, as it is deprecated in favor of IcingaDB. The following variables can be removed from the inventory:
icinga2_master__database_enable_haicinga2_master__database_hosticinga2_master__database_loginicinga2_master__database_name- role:icingaweb2_module_monitoring: Remove, as it is deprecated in favor of IcingaDB. All variables starting with
icingaweb2_module_monitoring__can be removed from the inventory. - role:mariadb_server:
- Remove support for EOL version 10.5
- Remove
mariadb_server__cnf_expire_logs_days__group_var/mariadb_server__cnf_expire_logs_days__host_var, usemariadb_server__cnf_binlog_expire_logs_seconds__group_var/mariadb_server__cnf_binlog_expire_logs_seconds__host_varinstead
Added¶
- role:acme_sh: Add support for Debian/Ubuntu
- role:apache_httpd: Add support for Debian/Ubuntu
- role:elasticsearch_oss: Add
elasticsearch_oss__discovery_type,elasticsearch_oss__network_hostvariables; reset JVM tmp directory - role:icingaweb2_module_pdfexport: Add new role
- role:kvm_host: Add support for Ubuntu 24.04
- role:mastodon: Add new role
- role:mongodb: Add RedHat config template for v8.0
- role:moodle: Add
moodle__versionvariable to select the major and minor version - role:postgresql_server: Add
postgresql_server__login_passwordvariable - role:repo_mydumper: Add official repos for Debian-based systems
- role:system_update: Add
metadata_timer_syncoption for cache-only installations - tool:particle: Add new tool
Changed¶
- role:gitlab_ce: Update template to v18.4.0
- role:mariadb_server:
- Create a backup file of the most important config files before applying new versions
- Make ownership of SSL certificate CIS-conform
- role:monitoring_plugins: Remove
monitoring_plugins__skip_notification_plugins__*_varvariables as they are now always installed - role:systemd_journald: Move config file to
/etc/systemd/journald.conf.d/z00-linuxfabrik.conf, improve calculations and default values
Fixed¶
- role:apache_httpd:
- Use platform-specific group for htpasswd files
- Allow unsetting the
CustomLogdirective - role:apache_tomcat: Adjust logrotate config for multiple Tomcat instances
- role:bind:
- Do not run
named-checkzoneagainst forward zones - Remove obsolete options for RHEL 9
- role:duplicity: Use python3.11 to prevent errors when installing latest duplicity
- role:elasticsearch_oss: Move tmpdir to a location with exec permissions specified by CIS hardening
- role:keycloak: Set
keycloak__proxy_trusted_addressesto'127.0.0.1'due to FD leak if using'127.0.0.1,::1' - role:mariadb_server:
- Correct mydumper dependency packages for Debian-based systems
- Fix failing dumps after mydumper update to v0.20.1
- Adjust SELinux settings after upgrades
- Grant
binlog monitorprivilege formariadb-backupuser - role:monitoring_plugins:
- Fix path to old sudoers file
- Fix script execution in CIS-hardened
/tmp - Improve versionlock and install SELinux package on RHEL
- role:nextcloud: Add missing
envmodule - role:repo_opensearch: Fix GPG key
v3.0.0 - 2025-06-13¶
Breaking Changes¶
- role:apache_httpd:
- Change
conf_server_aliasfrom a string to a list - Change default of the
authz_document_rootvHost variable fromRequire localtoRequire all granted. This is a more sensible default, asallowed_file_extensionsis used to restrict the access. - Remove the
authz_file_extensionsvHost variable. Access to listed file extensions is now always allowed. - Fix a bug that allowed access to dotfiles which had extensions listed in
allowed_file_extensions. Make sure this does not break your application, or setallow_accessing_dotfiles: true. - Change default of
apache_httpd__skip_mod_security_corerulesetfromfalsetotrue - role:apache_tomcat:
- Rename
apache_tomcat__skip_managertoapache_tomcat__skip_admin_webapps - Change
apache_tomcat__users__*_varfrom a simple list to a list of dictionaries - role:borg_local: Add new mandatory variable
borg_local__passphrase - role:collabora:
- Change
collabora__coolwsd_storage_wopi__*_varto a list of dictionaries from a list of strings - Change
collabora__language_packages__*_varto a list of dictionaries from a list of strings - Rename
collabora__coolwsd_allowed_languagestocollabora__coolwsd_allowed_languages__*_varand change it to a list of dictionaries from a list of strings - role:fangfrisch: Remove malwarepatrol as it is discontinued (see https://malwareblocklist.org/)
- role:grafana: Change default value for
grafana__serve_from_sub_pathfromtruetofalse - role:graylog_server:
- Remove support for Graylog < 5.0
- Only support Graylog 6.1+ (Graylog Data Node based installations). Currently no more support for dedicated OpenSearch or Elasticsearch.
- Rename
graylog_server__admin_usertograylog_server__root_user - role:icinga_kubernetes: Switch config to v0.3.0 multi-cluster format, remove
icinga_kubernetes__kubeconfig_path - role:icingadb: Split into two roles, one for the IcingaDB daemon and one for IcingaDB Web. Have a look at the variables in the READMEs. Generally it is enough to rename
icingadb__api_user_logintoicingadb_web__api_user_login. - role:icingaweb2_module_director: The
icingaweb2_module_director:baskettag only runs if explicitly called to prevent accidental config overwrites - role:icingaweb2_module_vspheredb: Remove the
vprefix from theicingaweb2_module_vspheredb__versionvariable to be consistent with the othericingaweb2_module_*roles - role:kvm_vm: Change
kvm_vm__boot_uefi(bool) tokvm_vm__boot(string) - role:login: Change default of
remove_other_sshd_authorized_keysfromtruetofalse - role:mailto_root:
- Move most functionality to
role:postfix, remove themailto_root:configureandmailto_root:testmailtags - Change
mailto_root__fromfrom optional to mandatory - Testmail to external addresses now uses sender address (
mailto_root__from) - role:mariadb_client: Remove (use the
appsrole instead) - role:mariadb_server:
- Remove support for EOL versions 10.3 and 10.4
- Remove support for non-LTS versions
- Change default of
mariadb_server__cnf_client_ssl_verify_server_cert__*_varfor versions lower than 10.11 fromtruetofalseto prevent errors when SSL is disabled - module:bitwarden_item, lookup_plugin:bitwarden:
- Remove parameters
password_uppercase,password_lowercase,password_numeric,password_special - Add parameter
password_choice - role:mongodb: Change
mongodb__conf_net_bind_ipfrom a string to a list of strings. For example: ```yaml # old mongodb__conf_net_bind_ip: '0.0.0.0'
# new
mongodb__conf_net_bind_ip:
- '0.0.0.0'
* **role:monitoring_plugins**:
* Remove variables:
* `monitoring_plugins__pip_executable`
* `monitoring_plugins__pip_package`
* `monitoring_plugins__python__modules`
* `monitoring_plugins__windows_variant`
* The `lfops__monitoring_plugins_version` variable (and all the `*.monitoring_plugin.*_version` variables) now only accepts a specific release or the value `dev`. `stable` or `latest` are no longer supported.
* The `lfops__monitoring_plugins_version` variable is now mandatory.
* Rename `monitoring_plugins__linux_variant` to `monitoring_plugins__install_method`:
* `monitoring_plugins__linux_variant: 'python'` becomes `monitoring_plugins__install_method: 'source'`
* Rename `monitoring_plugins__repo_version` to `monitoring_plugins__version`:
* `monitoring_plugins__repo_version: 'latest'` becomes `monitoring_plugins__version: 'dev'`
* Remove the tasks for Nuitka compilation, as the compilation is done by the [Monitoring Plugins GitHub Action](https://github.com/Linuxfabrik/monitoring-plugins/actions/workflows/nuitka-compile.yml) now
* Lock the version of the `monitoring-plugins` package after installing it. Updating the plugins should be done manually along with updating the monitoring system configuration.
* **role:monitoring_plugins_grafana_dashboards**: Change from provisioning to grizzly for the deployment of the dashboards
* **role:mount**: Change `mount__mounts` to `mount__mounts__host_var` / `mount__mounts__group_var`
* **role:nextcloud**:
* Rename `nextcloud__apps_config` to `nextcloud__app_configs__*_var`, add `state` subkey, make more use of the `value` subkey. `--value` is no longer required:yaml
# old
nextcloud__apps_config:
- { key: 'core', value: 'shareapi_default_expire_date --value=yes' }
# new
nextcloud__app_configs__host_var:
- key: 'core shareapi_default_expire_date'
value: 'yes'
state: 'present'
* Rename `nextcloud__apps` to `nextcloud__apps__*_var`, add `state` subkey
* Rename `nextcloud__sysconfig` to `nextcloud__sysconfig__*_var`, add `state` subkey, make more use of the `value` subkey (same as `nextcloud__app_configs__*_var`)
* Remove `nextcloud__proxyconfig`. Use `nextcloud__sysconfig__*_var` instead.
* Implement [notify_push](https://github.com/nextcloud/notify_push). Add the following to your Apache HTTPd config:apacheconf
RewriteRule ^\/push\/ws(.) ws://nextcloud-server:7867/ws$1 [proxy,last]
RewriteRule ^\/push\/(.) http://nextcloud-server:7867/$1 [proxy,last]
ProxyPassReverse /push/ http://nextcloud-server:7867/
``
* Change default ofnextcloud__timer_app_update_enabledfromtruetofalse, as this can sometimes lead to Nextcloud ending up in maintenance mode
* Renamenextcloud__apache_httpd__vhosts_virtualhost_iptonextcloud__vhost_virtualhost_ip* Renamenextcloud__apache_httpd__vhosts_virtualhost_porttonextcloud__vhost_virtualhost_port* **role:opensearch**:
* Change default ofopensearch__plugins_security_disabledfromtruetofalse* For new installations of OpenSearch 2.12 and later, you must define a custom admin password inopensearch__opensearch_initial_admin_password* **role:openssl**: Remove (use theappsrole instead)
* **role:perl**: Remove (use theappsrole instead)
* **role:postfix**: Now completely templates the whole config file. Beware when running against existing hosts.
* **role:postgresql_server**: Rename thenamesubkey ofpostgresql_server__users___vartousernamefor consistency and easier integration of the Bitwarden lookup plugin
* **role:python**: Changepython__modules___varto a list of dictionaries from a list of strings
* **role:redis**:
* Drop support for Redis v5 (end of life)
* Drop support for Redis v6
* Change default ofredis__service_timeout_start_secandredis__service_timeout_stop_secfrom5sto90s* **role:repo_icinga**:
* Removerepo_icinga__use_subscription_urlfor RHEL (and compatibles) as the packages without a subscription are outdated. The variable is now only effective for openSUSE and SLES.
* Renamerepo_icinga__subscription_logintorepo_icinga__basic_auth_loginand add a variable to explicitly use the Icinga Repo Subscription URL (repo_icinga__use_subscription_url). If you haverepo_icinga__subscription_loginset in your inventory, rename it torepo_icinga__basic_auth_loginand setrepo_icinga__use_subscription_url: truefor the same effect.
* **role:repo_mydumper**: Adjust to use https://repo.linuxfabrik.ch/mydumper/ by default. Removerepo_mydumper__baseurl, addrepo_mydumper__mirror_urlinstead.
* **role:rocketchat**:
* Switch deployment method from native installation to Podman container
* Removerocketchat__npm_versionvariable
* Rename and alter:
*rocketchat__application_pathtorocketchat__user_home_directory(new default:'/opt/rocketchat')
*rocketchat__service_enabledtorocketchat__container_enabled*rocketchat__service_statetorocketchat__container_state* Change default ofrocketchat__mongodb_hostto'host.containers.internal'* Remove Rocket.Chat notifications from the default banaction
* **role:selinux**: Changeportssubkey ofselinux__ports__*_vartoport, accepting only a single port or port range, not a list
* **role:sshd**:
* Removesshd__ciphers,sshd__kexandsshd__macsvariables, as these settings are managed bycrypto-policyon RHEL
* Now deploy the complete/etc/ssh/sshd_configas a template
* Remove support for RHEL 7
* **role:system_update**: Removesystem_update__icinga2_mastervariable. Usesystem_update__icinga2_api_urlinstead.
* **role:systemd_journald**: The value forsystemd_journald__conf_system_max_useis now interpreted as a size in bytes. It supports the size specifications possible injournald.conf(e.g.4G). If you want to specify a percentage, use'40%'.
* **role:tar**: Remove (use theappsrole instead)
* **playbook:icinga2_agent**: Change to also include the installation of the [Linuxfabrik Monitoring Plugins](https://github.com/Linuxfabrik/monitoring-plugins). This can be skipped by settingicinga2_agent__skip_monitoring_plugins: true.
* **playbook:setup_icinga2_master**:
* Change default ofsetup_icinga2_master__icingaweb2_module_company__skip_rolefromfalsetotrue* Change the format of the role skip-variables fromplaybook_name_skip_role_nametoplaybook_name__role_name__skip_rolefor clarity and consistency. Have a look at the [README.md](./README.md#skipping-roles-in-a-playbook).
* Addplaybook_name__role_name__skip_role_injectionsvariables to disable or re-enable the role's injections
* Change default ofsetup_icinga2_master__skip_icingaweb2_module_monitoringfromfalsetotrue`
Added¶
- role:nextcloud: Add nextcloud_occ_*_config modules with diff and check mode support
- role:alternatives: Add new role
- role:apache_httpd:
- Add some mods
- Add
skip_allowed_file_extensionsvHost variable - Add
skip_allowed_http_methodsvHost variable - role:apache_solr: Add new role
- role:audit: Add more config variables
- role:bind:
- Add multiple new variables, now allowing a primary-secondary setup
- Add
bind__named_conf_rawvariable - role:blocky: Add new role
- role:borg_local: Add new role
- role:clamav: Add new role
- role:cloud_init: Add task to remove
/etc/cloud/cloud.cfg.rpmsave - role:collect_rpmnew_rpmsave: Add new role
- role:dnf_versionlock: Add new role
- role:duplicity: Add
duplicity__backup_full_if_older_thanvariable - role:fangfrisch: Add new role
- role:firewall: Add
firewall__firewalld_ports__*_varandfirewall__firewalld_services__*_varvariables - role:github_project_createrepo: Add new role
- role:glpi_agent: Add new role
- role:grafana: Add creation of service accounts and their tokens
- role:grafana_grizzly: Add new role
- role:graylog_datanode: Add new role
- role:graylog_server: Add variables and documentation for multi-node setup; add Debian support
- role:icinga2_agent: Add
icinga2_agent:updatetag; addicinga2_agent__validate_certsvariable - role:icinga2_master: Add
icinga2_master__bind_hostvariable - role:icinga_kubernetes: Add new role
- role:icinga_kubernetes_web: Add new role
- role:icingadb: Add new role
- role:icingaweb2_module_businessprocess: Add new role
- role:icingaweb2_module_cube: Add new role
- role:icingaweb2_module_fileshipper: Add new role
- role:icingaweb2_module_generictts: Add new role
- role:icingaweb2_module_jira: Add new role
- role:icingaweb2_module_reporting: Add new role
- role:icingaweb2_module_x509: Add
icingaweb2_module_x509__urlvariable - role:kvm_vm: Add the option to boot the VM with UEFI
- role:logrotate: Add compression
- role:mariadb_server:
- Add
mariadb_server__cnf_wsrep_sst_authandmariadb_server__cnf_wsrep_sst_methodvariables - Add
mariadb_server__cnf_extra_max_connections__*_varandmariadb_server__cnf_extra_port__*_varvariables - Add support for client and server TLS
- Add Galera cluster installation
- Make datadir configurable, including copy of old data to the new location
- Make socket configurable
- role:mirror: Add new role
- role:mongodb:
- Add Debian support
- Add keyfile handling
- Adjust for replica set across members
- Implement user management (fix #89)
- role:moodle: Add new role
- role:mount: Add new role
- role:opensearch: Add Debian support; add variables for cluster configuration
- role:php: Add tag
php:fpm - role:podman_containers: Add new role
- role:proxysql: Add new role
- role:python_venv:
- Allow specifying different certificate store
- Allow specifying the Python executable to be used in the venv
- Add Debian support
- role:repo_baseos: Add AlmaLinux 8 support
- role:repo_epel: Add
repo_epel__epel_cisco_openh264_enabledvariable - role:repo_gitlab_runner: Add new role
- role:repo_graylog: Add Debian support
- role:repo_mongodb: Add Debian support
- role:repo_opensearch: Add Debian support
- role:repo_proxysql: Add new role
- role:repo_redis: Add new role
- role:repo_rpmfusion: Add new role
- role:selinux: Add support for SELinux ports
- role:shell: Add new role; add option to ignore errors during command execution
- role:system_update: Add option
-ytoyum check-update - role:systemd_journald: Add variable
systemd_journald__conf_system_keep_free; makeSystemMaxUseconfigurable - role:systemd_unit: Add support for mount units
- role:tools: Add
tools__prompt_use_fqdnvariable - playbook:setup_basic: Add support for AlmaLinux 8
Changed¶
- role:apache_httpd: Change default of the
conf_custom_logvHost variable from unset to'logs/{{ conf_server_name }}-access.log linuxfabrikio' - role:graylog_server: Remove version defaults from the role
- role:icingaweb2_module_grafana: Change GitHub repo from Mikesch-mp to NETWAYS
- role:mariadb_server: mariadb-dump checks for the mydumper version and sets parameters accordingly
- role:open_vm_tools: Start and enable
vmtoolsd - role:opensearch: Make
opensearch__version*optional
Fixed¶
- role:influxdb: Fix wrong systemd service name, which was preventing InfluxDB dumps from being scheduled
- role:mariadb_server:
- Fix handler when
bind_addressis not localhost - Add installation of missing package for mariabackup Galera SST
- Fix clone-datadir against new Galera cluster
- role:redis: Fix various messages from log, fix v7 template settings, fix various comments and README
v2.0.1 - 2023-02-28¶
Changed¶
- Adjustments for the Ansible Galaxy Release
v2.0.0 - 2023-02-28¶
Breaking Changes¶
- All roles: Rename all injectable variables:
rolename__combined_varnametorolename__varname__combined_varrolename__dependent_varnametorolename__varname__dependent_varrolename__group_varnametorolename__varname__group_varrolename__host_varnametorolename__varname__host_varrolename__role_varnametorolename__varname__role_var- role:acme_sh:
- Add
namesubkey toacme_sh__certificates - Move
acme_sh__reload_cmdto a subkey ofacme_sh__certificates - role:chrony: Fix wrong variable prefix: adjust
chrony_server__tochrony__ - role:collabora: Rename rolename and vars from
collabora_codetocollabora - role:duplicity:
- Rename
duplicity__public_master_long_keyidtoduplicity__gpg_encrypt_master_key - Rename
duplicity__public_master_keytoduplicity__gpg_encrypt_master_key_block - Change the format of
duplicity__backup_sources__host_var - role:fail2ban: Adjust subkeys of
fail2ban__jails__group_var/fail2ban__jails__host_var - role:git: Add and later remove in favor of a more general
appsrole - role:hostname:
- Rename
hostname__domain_nametohostname__domain_part - Rename
hostname__hostnametohostname__full_hostname - role:icinga2_agent:
- Add new mandatory variable
icinga2_agent__icinga2_master_cn - Make
icinga2_agent__icinga2_master_hostoptional - Most users can replace all instances of
icinga2_agent__icinga2_master_hostwithicinga2_agent__icinga2_master_cn - role:infomaniak_vm:
- Rename
infomaniak_vm__passwordtoinfomaniak_vm__api_password - Rename
infomaniak_vm__project_idtoinfomaniak_vm__api_project_id - Rename
infomaniak_vm__usernametoinfomaniak_vm__api_username - Rename
infomaniak_vm__volume_sizetoinfomaniak_vm__separate_boot_volume_size - role:java: Remove, better substituted by the
appsrole - role:kernel_settings: Make
kernel_settings__variables injection-capable viakernel_settings__host_*,kernel_settings__group_*andkernel_settings__dependent_* - role:libselinux_python: Rename the role to
policycoreutils - role:login: Change logic and rename
login__usersto two combined variableslogin__users__group_var(define users in group vars) andlogin__users__host_var(define users in host vars) - role:mariadb_server:
- Rename
mariadb_server__admin_logintomariadb_server__admin_user - Move
mariadb_server__admin_hosttomariadb_server__admin_user["host"] - Rename
mariadb_server__dump_logintomariadb_server__dump_user - Move
mariadb_server__dump_user_*to subkeys inmariadb_server__dump_user - role:monitoring_plugins: Rename
monitoring_plugins__deploy_notification_pluginstomonitoring_plugins__skip_notification_pluginsand flip the logic - role:php: Make more variables injectable, therefore the variables have a new name
- role:stig: Move to a new GitHub repo (temporarily)
- role:system_update: Rename variables (note: old and new names appear identical in the original CHANGELOG, likely a documentation error):
system_update__mail_recipients_new_configfiles=>system_update__mail_recipients_new_configfilessystem_update__mail_recipients_updates=>system_update__mail_recipients_updatessystem_update__mail_from=>system_update__mail_fromsystem_update__mail_subject_prefix=>system_update__mail_subject_prefixsystem_update__notify_and_schedule_on_calendar=>system_update__notify_and_schedule_on_calendar- playbook:basic_setup: Rename to
setup_basicto be consistent with the other setup playbooks. Removeauditandcrypto_policyroles for now.
Added¶
- This CHANGELOG
- role:acme_sh: Add new role
- role:ansible_init: Add new role
- role:apache_httpd: Add new role
- role:apache_tomcat: Add new role
- role:apps: Add new role
- role:at: Add new role
- role:audit: Add new role
- role:bind: Add new role
- role:chrony: Add new role
- role:cloud_init: Add new role
- role:cockpit: Add new role
- role:collabora: Add new role
- role:coturn: Add new role
- role:crypto_policy: Add new role
- role:dnf_makecache: Add new role
- role:docker: Add new role
- role:elasticsearch_oss: Add new role
- role:exoscale_vm: Add new role
- role:fail2ban: Add new role
- role:firewall: Add new role
- role:freeipa_client: Add new role
- role:freeipa_server: Add new role
- role:glances: Add new role
- role:grafana: Add new role
- role:grav: Add new role
- role:graylog_server: Add new role
- role:haveged: Add new role
- role:hetzner_vm: Add new role
- role:hostname: Add new role
- role:icinga2_agent: Add new role
- role:icinga2_master: Add new role
- role:icingaweb2: Add new role
- role:icingaweb2_module_company: Add new role
- role:icingaweb2_module_director: Add new role
- role:icingaweb2_module_doc: Add new role
- role:icingaweb2_module_grafana: Add new role
- role:icingaweb2_module_incubator: Add new role
- role:icingaweb2_module_monitoring: Add new role
- role:icingaweb2_module_vspheredb: Add new role
- role:influxdb: Add new role
- role:infomaniak_vm: Add new role
- role:kdump: Add new role
- role:keepalived: Add new role
- role:kernel_settings: Add new role
- role:keycloak: Add new role
- role:kvm_host: Add new role
- role:kvm_vm: Add new role
- role:libmaxminddb: Add new role
- role:librenms: Add new role
- role:libreoffice: Add new role
- role:login: Add new role
- role:mailto_root: Add new role
- role:mariadb_client: Add new role
- role:mariadb_server: Add new role
- role:maxmind_geoip: Add new role
- role:minio_client: Add new role
- role:mod_maxminddb: Add new role
- role:mongodb: Add new role
- role:motd: Add new role
- role:network: Add new role; add functionality to configure network connections
- role:nextcloud: Add new role
- role:nfs_client: Add new role
- role:nfs_server: Add new role
- role:nodejs: Add new role
- role:objectstore_backup: Add new role
- role:open_vm_tools: Add new role
- role:openssl: Add new role
- role:openvpn_server: Add new role
- role:perl: Add new role
- role:php: Add new role
- role:policycoreutils: Add new role
- role:postgresql_server: Add new role
- role:qemu_guest_agent: Add new role
- role:redis: Add new role
- role:repo_baseos: Add new role
- role:repo_collabora: Add new role
- role:repo_collabora_code: Add new role
- role:repo_debian_base: Add new role
- role:repo_docker: Add new role
- role:repo_elasticsearch_oss: Add new role
- role:repo_gitlab_ce: Add new role
- role:repo_grafana: Add new role
- role:repo_icinga: Add new role
- role:repo_influxdb: Add new role
- role:repo_mariadb: Add new role
- role:repo_mongodb: Add new role
- role:repo_monitoring_plugins: Add new role
- role:repo_mydumper: Add new role
- role:repo_postgresql: Add new role
- role:repo_remi: Add new role
- role:repo_sury: Add new role
- role:rocketchat: Add new role
- role:rsyslog: Add new role
- role:snmp: Add new role
- role:sshd: Add new role
- role:stig: Add new role
- role:system_update: Add new role
- role:systemd_journald: Add new role
- role:systemd_unit: Add new role
- role:tar: Add new role
- role:telegraf: Add new role
- role:timezone: Add new role
- role:unattended_upgrades: Add new role
- role:wordpress: Add new role
- role:yum_utils: Add new role
Changed¶
- module_util:bitwarden: Switch to the Bitwarden client API, as it is more reliable than using the command line tool directly
- role:acme_sh: Automatically update acme.sh (fix #74)
- role:apache_tomcat: Use the correct Java version depending on Tomcat version (fix #82)
- role:duplicity: Implement massive-parallel backups
- role:hetzner_vm: Improve handling of IP addresses (new Hetzner features) (fix #72); manage the provider firewall (fix #71)
- role:login: Add a switch to be aggressive or not (fix #65)
- role:mariadb_server: Implement mydumper / adapt to the LFOps standards (fix #56)
- role:mongodb: Implement dumping / user management (fix #78)
- role:python: On RHEL 8+, don't install
python3. Instead installpython38orpython39explicitly (fix #62) - role:tools: Show distro in prompt (fix #47)
Fixed¶
- role:audit: Fix wrong README (fix #51, fix #58)
- role:crypto_policy: Fix wrong README (fix #52, fix #76)
- role:icinga2_agent: On Debian, user
nagiosdoes not exist when certs folder is created (fix #77) - role:icinga2_master: Fix missing option name in
icinga2_master/tasks/main.yml(fix #105) - role:monitoring_plugins: Fix "deploy" vs "skip" logic (fix #103)
- role:repo_graylog: Fix
repo_graylog__mirror_urlnever actually being used (fix #94) - role:sshd: Fix
ModuleNotFoundError: No module named 'seobject'(fix #53) - playbook:basic_setup: Fix
Failed to set locale, defaulting to C.UTF-8(fix #55) - Do not use
become: truein all playbooks (fix #66) - Deploy nft in basic-setup or the fwbuilder role (fix #61)
- role:freeipa_server: Fix
In unattended mode you need to provide at least -r, -p and -a options(fix #83)
v1.0.1 - 2022-03-17¶
Changed¶
- Adjust tags for Ansible Galaxy
v1.0.0 - 2022-03-17¶
Added¶
- role:duplicity: Add new role
- role:monitoring_plugins: Add new role
- role:python_venv: Add new role
- role:repo_epel: Add new role
- module:bitwarden_item: Add new module
- module:gpg_key: Add new module
- lookup_plugin:bitwarden: Add new lookup plugin
- module_util:bitwarden: Add new module util
- module_util:gnupg: Add new module util