Skip to content

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 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.

Breaking Changes

  • role:collabora: collabora__coolwsd_ssl_settings_ssl_verification and collabora__coolwsd_welcome_enable reach the deployed coolwsd.xml again, 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 needs collabora__coolwsd_ssl_settings_ssl_verification: false, otherwise its documents stop loading.
  • role:apache_httpd: mod_info is no longer enabled, so /server-info stops serving the complete Apache configuration, including the credentials of other modules. Hosts that need the endpoint re-enable the info module in their inventory via apache_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/notifications directory 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 the notifications subdirectory.
  • 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 the icingaweb2_module_director:basket tag. Run the role with that tag to update /etc/icingaweb2/modules/grafana/graphs.ini. The icingaweb2_module_grafana__skip_monitoring_plugins_graphs_config variable is gone; remove it from your inventory.

Added

  • role:files: A file can opt out of the backup copy that is written before it is overwritten, via the backup subkey of files__files__*_var.
  • role:collabora: The collabora:configure tag deploys coolwsd.xml and 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:files and files:symlinks tags 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, or create = false in the [bitwarden_item_lookup] section of your ansible.cfg; the default is the previous behaviour.

Changed

  • 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 localhost WOPI host is an ordinary entry of collabora__coolwsd_storage_wopi__* instead of being hard-coded in the template, so it can be dropped with state: 'absent' like any other host.
  • role:php: The PHP-FPM configuration is checked with php-fpm --test before 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

  • playbook:icingaweb2, playbook:setup_icinga2_master, role:icingaweb2 update icingaweb2 dependent vars to ensure php.ini value post_max_size > upload_max_filesize by 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 installed and 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.pip needs nor an /etc/bash_completion.d directory.
  • 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_sudocmds and allow_sudocmdgroups subkeys of freeipa_server__sudorules; the former cmds and cmdgroups names never reached FreeIPA and aborted the run with Unsupported parameters.
  • role:apache_solr: __apache_solr__java_package covers 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__versionlocks to dnf_versionlock__versionlocks__group_var / __host_var and change it from a list of strings to a list of dictionaries (name, plus the optional raw and state subkeys). The role no longer rewrites the whole lock list, so locks set elsewhere (for example by monitoring_plugins) survive, but removing an entry from the inventory no longer unlocks the package: set state: 'absent' instead.
  • role:apache_httpd: Role-internal variables are now __-prefixed. If you copied the SSL/TLS snippet from EXAMPLES.md into a vHost raw block, rename apache_httpd__openssl_certificate_path, apache_httpd__openssl_privatekey_path and apache_httpd__openssl_chain_path to 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_reboot role (see Added). Adjust in your inventory: system_update__update_time to schedule_reboot__reboot_time__group_var (now a plain time of day, e.g. '04:00'), and any system_update__icinga2_* reboot-downtime settings to schedule_reboot__icinga2_*. Also, in most cases system_update__update_day should be used instead of system_update__notify_and_schedule_on_calendar.
  • role:php: In preparation for the upcoming PHP 8.6, php__ini_session_cookie_httponly now defaults to On, so session cookies are marked HttpOnly and are no longer accessible to JavaScript via document.cookie. This matches the hardened session defaults PHP 8.6 ships. Applications that must read the session cookie from JavaScript have to set php__ini_session_cookie_httponly__group_var: 'Off' (or the __host_var) to restore the previous behaviour.
  • role:php: The default php__ini_opcache_blacklist_filename now points to the distribution-neutral /etc/opcache.blacklist instead 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 the apache_httpd:matomo tag have been removed and moved to the new matomo_import_logs role. Hosts that import their access logs into Matomo, or that pipe their access logs to /usr/local/sbin/import_logs.py for realtime tracking, must now also run the matomo_import_logs role, which deploys the script. The matomo LogFormat itself stays in apache_httpd.
  • role:repo_baseos: The Rocky Linux security repository now always points at the upstream mirrorlist, even when a custom repo_baseos__mirror_url is set, so critical CVE fixes keep coming straight from upstream instead of a potentially lagging mirror. Hosts that previously pulled the security repository from their custom mirror now reach upstream directly. Set repo_baseos__security_repo_use_upstream: false to restore the previous behaviour and have the security repository follow repo_baseos__mirror_url again.
  • role:mariadb_server: The default for skip_name_resolve is now OFF instead of ON. Hosts that relied on the previous default and grant access by hostname keep working, but connections are now resolved via DNS again. Set mariadb_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_enabled and glpi_agent__database_inventory_login, which runs glpi-agent --partial=database as 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_category disables arbitrary inventory categories and glpi_agent__database_inventory_on_calendar sets the schedule.
  • role:php: Add php__version to declare which PHP version a Debian host runs, for example '8.4', so an ordinary apt upgrade no 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 the php, phar and phar.phar alternatives to it, and purge the stacks of all other versions on php: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_sury role on Debian (skip with php__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 as fail2ban__jails__*_var. The built-in apache-dos and portscan filters move into fail2ban__filters__role_var with no behaviour change, and can now be opted out via state: 'absent'.
  • role:postfix: Add postfix__recipient_canonicals__group_var / __host_var to rewrite recipient addresses via Postfix's recipient_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_handlers to 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_state or php__fpm_service_state) to start, stop, restart or reload the managed service independently of whether it is enabled at boot; it defaults to started when the role's matching *_service_enabled is true and to stopped otherwise, 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 gnupg package itself so backups also work on minimal installs that ship without gpg.
  • role:python_venv: Add an optional per-venv pip_constraints key that pins transitive dependencies through a pip constraints file, without having to list them as direct packages.
  • role:opensearch: Add opensearch__path_repo to register file system paths as path.repo in opensearch.yml, required for file system based snapshot repositories.
  • role:nextcloud: Add nextcloud__jobs_timeout_start_sec to configure the start-up timeout of the nextcloud-jobs.service, defaulting to 10m, 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_proxies and librenms__config_app_url to set the APP_TRUSTED_PROXIES and APP_URL variables 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_var to configure the innodb_flush_neighbors InnoDB system variable, defaulting to 0, 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_sudorules and freeipa_server__limit_users to manage only specific resources via --extra-vars, which speeds up deployments on servers with many FreeIPA resources.
  • role:vsftpd: Add vsftpd__pam_use_userdb to authenticate virtual users via pam_userdb against /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__heap to 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). The token_auth is provided via a per-site auth file instead of the command line, since --token-auth, --login and --password are 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_venv role, 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_uri to set the REST API URI the DataNode advertises, needed when the bind address is not directly reachable (multiple interfaces, a NAT gateway, or a 0.0.0.0 bind address).

Changed

  • role:php: The php:update tag 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 changed php__version would otherwise run the new version with none of its pools and a unit that was never enabled.
  • role:fail2ban: README documents the state subkey of the filter and jail entries as optional (defaults to present), notes that raw only applies to entries using the raw template, 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) in COMPATIBILITY.md since 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:script tag is gone (the duba script now deploys under duplicity:configure), and the new duplicity:dump tag 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:update tag 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__databases without an explicit collation or encoding inherit the server default character set and collation (utf8mb4) instead of being pinned to the legacy utf8 / utf8_general_ci. Existing databases are unaffected; set collation / encoding per database to override.
  • role:collabora: Support Collabora Online CODE 25.04.10, which had no coolwsd.xml template and therefore aborted the deploy on hosts that had updated to it.
  • role:clamav: Send notification mails through sendmail (provided by postfix) instead of the mail command (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.mysql collection to its replacement ansible.mysql, so the deprecation warnings printed on every run are gone and the roles keep working once community.mysql is 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_var in the inventory are no longer discarded, because the role used the wrong dependent variable name.
  • role:postgresql_server: The grant_option subkey of postgresql_server__privs takes effect, and the entry's roles and state subkeys 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_epel and <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 php role manages, so the unversioned php-<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:state on 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-remnants script no longer aborts the nextcloud:cron deploy with 'setup_basic__skip_mailto_root' is undefined when the role runs outside the setup_basic playbook; report recipients come from nextcloud__mail_recipients, defaulting to the global mailto_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_jwt honours a quoted 'false', which previously enabled JWT authentication and deployed the private key anyway; unquoted true / false behaved correctly before and are unaffected.
  • role:shared: lfops__remove_rpmnew_rpmsave honours an explicit opt-out, so --extra-vars='lfops__remove_rpmnew_rpmsave=false' keeps the .rpmnew, .rpmsave, .dpkg-dist and .ucf-dist files instead of removing them. Leaving the variable unset was, and still is, safe.
  • role:apache_tomcat: apache_tomcat__service_state takes effect instead of being silently ignored in favour of apache_tomcat__service_enabled; its default is started if apache_tomcat__service_enabled is true and stopped otherwise, so hosts that never set it are unaffected.
  • role:freeipa_server: The pki-tomcatd start-up timeout configured via freeipa_server__systemd_timeoutstartsec is in effect, because the role now applies the same value to systemd and to FreeIPA and reloads systemd. On slow machines ipactl 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 the collections.Mapping crash and drops the deprecated netifaces dependency. 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__state to stopped.
  • role:nextcloud: Set the text workspace_available app config key as boolean instead of string, since newer Nextcloud enforces the config lexicon and the text app declares the key as ValueType::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_user respectively mod_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-packaging on EL10, which ships Python 3.12 without the stdlib distutils, so Ansible's pip module can create a venv again.
  • role:icingaweb2_module_vspheredb: Download the module tarball from the canonical archive/refs/tags/<version>.tar.gz URL, 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 duplicate Cmnd_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_url for 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 0750 instead of 2755, 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 of dnf_versionlock__list_path, dnf_versionlock__packages or a role's *__icingaweb2_owner variable 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_port on every apache_httpd vHost, host on every mariadb_server user/role, port on every proxysql server, and proto on every selinux port. 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:config becomes apache_httpd:configure, and apache_tomcat:users, mastodon:users, postgresql_server:users and postgresql_server:databases lose their trailing s (...:user, ...:database). Adjust any --tags / --skip-tags invocations 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, MaxAuthTries is lowered to 3, ClientAliveCountMax to 2, and LogLevel is raised to VERBOSE. 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 are sshd__allow_tcp_forwarding and sshd__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 :user tags become :users, the :database tags become :databases, and apache_httpd:config becomes apache_httpd:configure. Adjust any --tags / --skip-tags invocations 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 in playbooks/setup_nextcloud.yml and the setup_nextcloud__skip_minio_client / setup_nextcloud__skip_objectstore_backup variables. 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); the mc binary, its config under /etc/mc/, the objectstore-backup systemd timer/service, and /usr/local/bin/mc-mirror.sh are 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 no fixed_ip is set. Previously only networks with a fixed_ip got 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 the port_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_group and loaded into every playbook through a new global-variables.yml task in pre_tasks, instead of being repeated in the vars/ of around 20 roles. Running one of those roles ad-hoc outside the bundled playbooks now requires importing shared's global-variables.yml first. On Suse, the monitoring_plugins web files use the correct apache group www instead of wwwrun.
  • 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-hoc schedule-reboot command, 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_update uses 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-headless from EPEL instead of Google's proprietary repository.
  • role:tmux: New role that installs tmux and deploys a system-wide /etc/tmux.conf with a larger scrollback buffer and mouse support. Selections are copied to the local clipboard over SSH via OSC 52 where the terminal supports it, and prefix + P dumps a pane's whole scrollback buffer to a file.
  • role:hostname: Maintains an /etc/hosts entry mapping the FQDN and short name to the host's primary IPv4 address, configurable via hostname__etc_hosts_ip and disablable with hostname__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_mwindow and uptimerobot_psp for CRUD, uptimerobot_alert_contact for deletion only (UptimeRobot API v2 does not expose creating contacts), plus five read-only info modules. All CRUD modules support --check and --diff and are idempotent on re-run. Configured via uptimerobot__monitors, uptimerobot__mwindows, uptimerobot__psps and uptimerobot__alert_contacts; the API key comes from the api_key parameter, api_key_file (default ~/.uptimerobot) or UPTIMEROBOT_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 security repository and requests a reboot if needed, performed at the host's maintenance window. Enabled by default, a no-op where the security repository is not enabled, and turned off with system_update__security_enabled: false.
  • role:repo_baseos: Add the Rocky Linux security repository for critical CVE fixes, enabled by default. Opt out per host or group via repo_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 generic RedHat sshd_config template 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.ch and 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 (default false) to switch from the release to the testing channel. On Red Hat-family systems a single /etc/yum.repos.d/linuxfabrik-monitoring-plugins.repo is deployed containing both channel sections with enabled= toggled by the variable, so DNF metadata for both can stay cached across switches; on Debian and Ubuntu the -release suffix 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_age and graylog_server__message_journal_max_size.
  • role:graylog_datanode: Add graylog_datanode__raw, plus graylog_datanode__path_repos and graylog_datanode__node_search_cache_size to 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_size and sort_buffer_size configurable via the corresponding mariadb_server__cnf_* variables, and add mariadb_server__cnf_innodb_snapshot_isolation (MariaDB 10.6+), defaulting to 'ON'.
  • role:elasticsearch: Add optional variables elasticsearch__cluster_routing_allocation_disk_watermark_flood_stage_frozen and the four corresponding *_max_headroom variables.
  • role:kibana: Add kibana__logging to make the logging: block in kibana.yml fully 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_uuid and logstash__monitoring_enabled.
  • role:alternatives: Support managing subcommands (slaves/followers) and the Red Hat-only family grouping, 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_state and __timer_state, open_vm_tools__service_enabled and __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_absent subkey on infomaniak_vm__networks entries to preserve the port and its fixed IP when the VM is set to absent, so the same IP can be re-used, and port_name to override the managed port's name.
  • role:mirror: Document the per-repository newest_only subkey on mirror__reposync_repos entries, defaulting to true. Set it to false for 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_policycoreutils to skip the policycoreutils role, 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 that setup_basic exercises, 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). glances stays 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/keycloak after 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_login can then be removed from the inventory. For disaster recovery, delete the marker file, re-add the variable and re-run. A -temp suffix 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:test tag) 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_length to an RSA value such as 4096 to keep RSA.
  • role:mailto_root: Send the verification mails via sendmail (provided by postfix) instead of the mail (mailx) command, completing the move off mailx, so the role no longer needs the mailx package 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-virtualenv uninstallable.
  • 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 dedicated tmux role instead, which ships a configuration with sensible defaults.
  • role:repo_baseos: The Rocky 8 security repository matches Rocky 9 and 10: it adds the disabled security-debuginfo and security-source sub-repositories, a 6-hour metadata expiry so emergency hot-fixes are noticed quickly, and the $rltype mirrorlist variable.
  • role:redis: Bump the default for net.core.somaxconn from 1024 to 4096 to 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 get 4096.
  • role:monitoring_plugins: install_method: 'source' reads the per-Python-LTS lockfile under lockfiles/pyXX/requirements.txt from both the monitoring-plugins and lib repos, picking the directory that matches the target host's Python, since the previous root-level requirements.txt no longer exists upstream.
  • role:system_update: Change the default of system_update__update_time so updates are spread deterministically across 04:00-04:59, with the minute derived from inventory_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.md to use ProxyPass instead of RewriteRule, which %-decodes the URI pattern and breaks WebDAV apps such as Nextcloud on rename. See the blog post.
  • role:firewall: Install nftables together with iptables for firewall__firewall == "fwbuilder" on all distros, instead of only on Fedora and RHEL 8/9.
  • role:graylog_server: Update the server.conf templates to include telemetry_enabled = false.
  • role:network: Scope the hc-utils removal task to Red Hat-family hosts, since Hetzner ships hc-utils as 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 gnupghome parameter 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__domain and freeipa_server__realm from defaults/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: false on tasks delegated to localhost across the collection, so they no longer try to call sudo on the Ansible controller and fail with sudo: a password is required where 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_servers entries are deduplicated by their actual address field; the merge key referenced a non-existent hostname field, so multiple backends sharing a host group and port were silently collapsed into one.
  • role:repo_influxdb: Prevent the influxdata-archive-keyring package 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:redis with mode 0640, 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 by root:root so the keycloak service 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 of utf8mb4.
  • role:mongodb: The role aborts early with a clear message when users are defined while mongodb__conf_security_authorization is 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_affinity setting 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_headless role instead of having to be set up by hand.
  • role:nextcloud: The nextcloud-update script owns the maintenance mode lifecycle itself instead of expecting callers to enable it beforehand, which disabled the LDAP user provider and made the before-update export silently omit LDAP users. Callers must drop the manual maintenance:mode --on step from their pre-script workflow and rely on --single-transaction for the DB dump instead.
  • role:nextcloud: Ensure that the Nextcloud OCC is executable.
  • role:graylog_server: Fix the graylog_server:configure_defaults run aborting on Graylog 7.0 and newer with Unable to map property can_be_default while 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_inputs entry sets global: true or assigns a node, which was marked mandatory but never enforced.
  • role:graylog_datanode, role:graylog_server: Validate that the password_secret is 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 with broken groups or modules, by resetting the module first when nodejs__dnf_module_stream is set and installing the explicit /common profile.
  • role:blocky: The validate config & restart blocky.service handler 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_size setting for MariaDB 10.11, 11.4 and 11.8, which ignore it and derive the chunk size from innodb_buffer_pool_size. The role aborts at the start of the run with a clear error if innodb_buffer_pool_chunk_size (on MariaDB 10.11+) or innodb_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_t SELinux domain on RHEL 10, which mislabels /var/lib/mysql/mysql.sock and breaks php-fpm and httpd_t clients such as Icinga Web 2 login. The role sets the mysqld_exec_t file context persistently via semanage fcontext and restorecon, since the previous chcon workaround cannot relabel the binary under EL10's read-only /usr service sandbox.
  • role:icinga2_master: Fix the selinux role failing on RHEL 10 with SELinux boolean icinga2_can_connect_all is not defined in persistent policy, by installing nagios-selinux from EPEL first so its %post registers the types that icinga2-selinux references.
  • 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 installs valkey on EL10 and guards the Redis Stack loadmodule directives that do not exist on Valkey; EL8 and EL9 keep installing Redis unchanged and the user-facing redis__conf_* variables stay backwards-compatible.
  • role:openvpn_server: Fix invalid selinux context on RHEL 10 when deploying server.p12 and crl.pem, by using etc_t there since the openvpn_etc_t type no longer exists in the RHEL 10 core policy.
  • role:repo_epel: Fix a malformed RHEL 10 epel.repo, where a missing newline rendered enabled=0username=<login> when repo_epel__basic_auth_login was set and dnf rejected the file.
  • role:repo_mariadb: Fix dnf -y module disable mariadb failing on RHEL 10, where modularity was removed, by scoping the task and the module_hotfixes directive to RHEL 8 and 9.
  • role:infomaniak_vm: Apply the VM's security group on the ext-net1 port 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 passing security_groups to openstack.cloud.server, which failed on internal-network ports with port_security_enabled set to false.
  • role:haveged: Setting haveged__service_state: 'stopped' no longer produces the invalid systemctl command stopp, 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_opts sets the JVM heap size to 60% of total memory, capped at 8g.
  • role:mount: Fix the when condition for NFS/CIFS client package installation failing with multiple mounts and when the state key is undefined.
  • execution-environment: Add the missing sshpass system package, required for SSH password-based connections such as --ask-pass.
  • plugin:nextcloud_occ_app_config: An array config value is compared as JSON, so a key whose stored value already matches no longer reports a change and re-runs occ config:app:set on every run.
  • plugin:bitwarden_item: The module no longer writes to the Bitwarden vault in check mode (--check), and a run without password no 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 a REGEXP query 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-doc renders it again, and corrected the gpg_key docs, which claimed a separate python-gnupg install 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) and repo_epel on Rocky 9 and newer before the python_venv role, to fix No match for argument: python3-virtualenv.
  • playbooks/setup_graylog_datanode, playbooks/setup_graylog_server, playbooks/setup_icinga2_master, playbooks/setup_rocketchat: Extend the repo_baseos and repo_epel conditions to Rocky and RHEL 10.
  • playbooks/freeipa_client, playbooks/freeipa_server: Set strategy: 'linear' explicitly, so the playbooks work even when the user's ansible.cfg defaults to a strategy that reuses the target Python interpreter, which otherwise fails with API.bootstrap() already called.
  • role:repo_monitoring_plugins: Add the missing run_once: true on 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_login without lfops__repo_mirror_url wrote 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__exports from a list of strings to a list of dictionaries with new path, clients, owner, group, and mode subkeys
  • 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-docs and a GitHub Actions workflow
  • CONTRIBUTING: Document semantic parameter ordering for Ansible modules
  • playbooks: Add example.yml and setup_example.yml playbooks 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.md documenting 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 serve API calls, preventing crashes under load. Cache is stored in $XDG_RUNTIME_DIR (RAM-backed tmpfs) with /tmp fallback. 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. Convert is_unlocked to a property to fix it never being called.
  • role:freeipa_server: Add --diff support for all FreeIPA modules and add freeipa_server:configure tag
  • role:mariadb_server: Add mariadb_server__cnf_wsrep_log_conflicts and mariadb_server__cnf_wsrep_retry_autocommit variables
  • role:mariadb_server: Add mariadb_server__cnf_wsrep_gtid_mode variable to configure wsrep_gtid_mode for Galera
  • role:openvpn_server: Add openvpn_server:crl tag 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, group and mode subkeys for mount point directories
  • role:logstash: Add support for deploying custom grok pattern files to /etc/logstash/patterns/
  • role:mount: Add optional owner and group subkeys 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 bantime configurable for the sshd and portscan jails
  • role:duplicity: Add support for RHEL 10
  • role:php: Make request_slowlog_timeout and request_terminate_timeout configurable
  • role:graylog_server: Make http_publish_uri configurable; make trusted_proxies configurable
  • 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_dir configurable
  • 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: true to all ansible.builtin.template tasks to ensure config file backups before overwriting
  • role:nextcloud: Refactor nextcloud-update.j2
  • role:keycloak: Rework keycloak.conf template 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-modular repository
  • role:icingadb: Enhance config.yml template
  • role:apache_httpd: Improve output; bump Core Rule Set to 4.24.0

Fixed

  • role:apache_httpd: Fix apache_httpd__mod_security_coreruleset_version default 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 raise in multipart error handling, break instead of continue in multi-term lookup, folder_id wrongly typed as list instead of str in module, notes default mismatch between documentation and code, and wrong "lookup plugin" wording in module documentation
  • role:mirror: Fix missing 0440 permissions on sudoers file
  • role:login: Rename sudoers file from lfops_login to linuxfabrik to match the kickstart configuration; remove the old file automatically
  • roles: Fix Ansible 2.19 deprecation warning for conditional results of type int by using | length > 0 instead of | length
  • role:firewall: Fix fwbuilder repo clone being skipped when run_once picks a host without firewall__fwbuilder_repo_url
  • role:sshd: Validate sshd config with sshd -t before 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 directory after 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 when statement
  • playbook:setup_icinga2_master: Fix syntax; add missing kernel_settings for 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__raw variable
  • role:elasticsearch: Add elasticsearch__raw variable
  • 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_cmd to allow setting the local reload command globally for all certificates
  • role:collabora: Add new template versions
  • role:elasticsearch:
  • Make node.roles configurable
  • Add variables for allocation awareness
  • Add elasticsearch__path_data variable to configure custom data directory
  • Improve handling of TLS certificates
  • Allow creation of clusters
  • role:gitlab_ce: Make the gitlab.rb options for default project features, email reply-to address, LDAP integration and the upload path configurable
  • role:graylog_server: Re-add graylog_server__elasticsearch_hosts to allow setups without Graylog Data Node
  • role:kibana: Add new role
  • role:mariadb_server:
  • Add support for version 11.8 (LTS)
  • Make log_slave_updates configurable
  • Add mariadb_server__cnf_server_raw variable
  • role:podman_containers: Add option to enable the podman-auto-update.timer
  • role:postfix: Add postfix__lookup_tables__*_var to 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__policy variable
  • role:shell: Add shell__limit_cmds to limit executed shell commands
  • playbook:selinux: Add selinux__skip_policycoreutils variable

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.swappiness to 1
  • role:firewall: Ensure firewalld is 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_name variable
  • role:kvm_vm: Fix path
  • role:mariadb_server: Fix /run/mariadb/wsrep-start-position: No such file or directory after update
  • role:mastodon: Adjust to breaking changes in elasticsearch role
  • role:monitoring_plugins:
  • Also install lib via source if monitoring_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_ha
  • icinga2_master__database_host
  • icinga2_master__database_login
  • icinga2_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, use mariadb_server__cnf_binlog_expire_logs_seconds__group_var / mariadb_server__cnf_binlog_expire_logs_seconds__host_var instead

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_host variables; 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__version variable to select the major and minor version
  • role:postgresql_server: Add postgresql_server__login_password variable
  • role:repo_mydumper: Add official repos for Debian-based systems
  • role:system_update: Add metadata_timer_sync option 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__*_var variables 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 CustomLog directive
  • role:apache_tomcat: Adjust logrotate config for multiple Tomcat instances
  • role:bind:
  • Do not run named-checkzone against 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_addresses to '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 monitor privilege for mariadb-backup user
  • 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 env module
  • role:repo_opensearch: Fix GPG key

v3.0.0 - 2025-06-13

Breaking Changes

  • role:apache_httpd:
  • Change conf_server_alias from a string to a list
  • Change default of the authz_document_root vHost variable from Require local to Require all granted. This is a more sensible default, as allowed_file_extensions is used to restrict the access.
  • Remove the authz_file_extensions vHost 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 set allow_accessing_dotfiles: true.
  • Change default of apache_httpd__skip_mod_security_coreruleset from false to true
  • role:apache_tomcat:
  • Rename apache_tomcat__skip_manager to apache_tomcat__skip_admin_webapps
  • Change apache_tomcat__users__*_var from 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__*_var to a list of dictionaries from a list of strings
  • Change collabora__language_packages__*_var to a list of dictionaries from a list of strings
  • Rename collabora__coolwsd_allowed_languages to collabora__coolwsd_allowed_languages__*_var and 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_path from true to false
  • 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_user to graylog_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_login to icingadb_web__api_user_login.
  • role:icingaweb2_module_director: The icingaweb2_module_director:basket tag only runs if explicitly called to prevent accidental config overwrites
  • role:icingaweb2_module_vspheredb: Remove the v prefix from the icingaweb2_module_vspheredb__version variable to be consistent with the other icingaweb2_module_* roles
  • role:kvm_vm: Change kvm_vm__boot_uefi (bool) to kvm_vm__boot (string)
  • role:login: Change default of remove_other_sshd_authorized_keys from true to false
  • role:mailto_root:
  • Move most functionality to role:postfix, remove the mailto_root:configure and mailto_root:testmail tags
  • Change mailto_root__from from optional to mandatory
  • Testmail to external addresses now uses sender address (mailto_root__from)
  • role:mariadb_client: Remove (use the apps role 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__*_var for versions lower than 10.11 from true to false to 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_ip from 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_extensions vHost variable
  • Add skip_allowed_http_methods vHost 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_raw variable
  • 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_than variable
  • role:fangfrisch: Add new role
  • role:firewall: Add firewall__firewalld_ports__*_var and firewall__firewalld_services__*_var variables
  • 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:update tag; add icinga2_agent__validate_certs variable
  • role:icinga2_master: Add icinga2_master__bind_host variable
  • 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__url variable
  • 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_auth and mariadb_server__cnf_wsrep_sst_method variables
  • Add mariadb_server__cnf_extra_max_connections__*_var and mariadb_server__cnf_extra_port__*_var variables
  • 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_enabled variable
  • 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 -y to yum check-update
  • role:systemd_journald: Add variable systemd_journald__conf_system_keep_free; make SystemMaxUse configurable
  • role:systemd_unit: Add support for mount units
  • role:tools: Add tools__prompt_use_fqdn variable
  • playbook:setup_basic: Add support for AlmaLinux 8

Changed

  • role:apache_httpd: Change default of the conf_custom_log vHost 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_address is 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

v2.0.0 - 2023-02-28

Breaking Changes

  • All roles: Rename all injectable variables:
  • rolename__combined_varname to rolename__varname__combined_var
  • rolename__dependent_varname to rolename__varname__dependent_var
  • rolename__group_varname to rolename__varname__group_var
  • rolename__host_varname to rolename__varname__host_var
  • rolename__role_varname to rolename__varname__role_var
  • role:acme_sh:
  • Add name subkey to acme_sh__certificates
  • Move acme_sh__reload_cmd to a subkey of acme_sh__certificates
  • role:chrony: Fix wrong variable prefix: adjust chrony_server__ to chrony__
  • role:collabora: Rename rolename and vars from collabora_code to collabora
  • role:duplicity:
  • Rename duplicity__public_master_long_keyid to duplicity__gpg_encrypt_master_key
  • Rename duplicity__public_master_key to duplicity__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 apps role
  • role:hostname:
  • Rename hostname__domain_name to hostname__domain_part
  • Rename hostname__hostname to hostname__full_hostname
  • role:icinga2_agent:
  • Add new mandatory variable icinga2_agent__icinga2_master_cn
  • Make icinga2_agent__icinga2_master_host optional
  • Most users can replace all instances of icinga2_agent__icinga2_master_host with icinga2_agent__icinga2_master_cn
  • role:infomaniak_vm:
  • Rename infomaniak_vm__password to infomaniak_vm__api_password
  • Rename infomaniak_vm__project_id to infomaniak_vm__api_project_id
  • Rename infomaniak_vm__username to infomaniak_vm__api_username
  • Rename infomaniak_vm__volume_size to infomaniak_vm__separate_boot_volume_size
  • role:java: Remove, better substituted by the apps role
  • role:kernel_settings: Make kernel_settings__ variables injection-capable via kernel_settings__host_*, kernel_settings__group_* and kernel_settings__dependent_*
  • role:libselinux_python: Rename the role to policycoreutils
  • role:login: Change logic and rename login__users to two combined variables login__users__group_var (define users in group vars) and login__users__host_var (define users in host vars)
  • role:mariadb_server:
  • Rename mariadb_server__admin_login to mariadb_server__admin_user
  • Move mariadb_server__admin_host to mariadb_server__admin_user["host"]
  • Rename mariadb_server__dump_login to mariadb_server__dump_user
  • Move mariadb_server__dump_user_* to subkeys in mariadb_server__dump_user
  • role:monitoring_plugins: Rename monitoring_plugins__deploy_notification_plugins to monitoring_plugins__skip_notification_plugins and 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_configfiles
  • system_update__mail_recipients_updates => system_update__mail_recipients_updates
  • system_update__mail_from => system_update__mail_from
  • system_update__mail_subject_prefix => system_update__mail_subject_prefix
  • system_update__notify_and_schedule_on_calendar => system_update__notify_and_schedule_on_calendar
  • playbook:basic_setup: Rename to setup_basic to be consistent with the other setup playbooks. Remove audit and crypto_policy roles 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 install python38 or python39 explicitly (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 nagios does 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_url never 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: true in 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