From 03bf17004d6a43f4cbe492da1cb128e45e4cc672 Mon Sep 17 00:00:00 2001 From: Andrea Dell'Amico Date: Fri, 4 Sep 2026 19:54:37 +0000 Subject: [PATCH] tasks: split the deb and EL branches The whole httpd.conf is templated on EL and left to the package on deb, which is how each family expects it: on deb the role manages ports.conf, the default virtualhost and a2enmod. Modules on EL are not managed with apache2_module. That Ansible module requires the a2enmod and a2dismod binaries and EL ships neither, so the module list of the absorbed role could never be applied there. The role now writes the MPM selection into conf.modules.d/00-mpm.conf and leaves the individual LoadModule lines to the distribution, with apache_el_extra_modules for what the distribution does not load by default. The letsencrypt hook is named after the service, apache2 or httpd, so the acme client reloads the right one. The httpd reload and httpd restart handlers are kept alongside the apache2 ones for the roles that notify those names. python-passlib becomes python3-passlib: the python2 package is gone from every supported release. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018sTDubHhviDWKZLtAtZXTW --- handlers/main.yml | 19 ++- tasks/apache-basic-auth.yml | 2 +- tasks/apache-config-deb.yml | 22 ++++ tasks/apache-config-el.yml | 23 ++++ tasks/apache-letsencrypt.yml | 113 ++++++++++++------ ...che-modules.yml => apache-modules-deb.yml} | 4 +- tasks/apache-modules-el.yml | 28 +++++ tasks/apache-packages.yml | 47 ++++++++ tasks/apache-service.yml | 16 +++ tasks/apache.yml | 44 ------- tasks/main.yml | 35 +++++- 11 files changed, 264 insertions(+), 89 deletions(-) create mode 100644 tasks/apache-config-deb.yml create mode 100644 tasks/apache-config-el.yml rename tasks/{apache-modules.yml => apache-modules-deb.yml} (90%) create mode 100644 tasks/apache-modules-el.yml create mode 100644 tasks/apache-packages.yml create mode 100644 tasks/apache-service.yml delete mode 100644 tasks/apache.yml diff --git a/handlers/main.yml b/handlers/main.yml index a4fd00a..f0a68bc 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,7 +1,22 @@ --- - name: apache2 reload - service: name=apache2 state=reloaded + ansible.builtin.service: + name: '{{ apache_service_name }}' + state: reloaded - name: apache2 restart - service: name=apache2 state=restarted + ansible.builtin.service: + name: '{{ apache_service_name }}' + state: restarted +# Kept for the playbooks and roles that come from the EL only httpd role and +# notify these names. Same action, different vocabulary. +- name: httpd reload + ansible.builtin.service: + name: '{{ apache_service_name }}' + state: reloaded + +- name: httpd restart + ansible.builtin.service: + name: '{{ apache_service_name }}' + state: restarted diff --git a/tasks/apache-basic-auth.yml b/tasks/apache-basic-auth.yml index 246438c..2ba28a0 100644 --- a/tasks/apache-basic-auth.yml +++ b/tasks/apache-basic-auth.yml @@ -7,7 +7,7 @@ notify: apache2 reload - name: Install the python-passlib library - apt: pkg=python-passlib state=present + apt: pkg=python3-passlib state=present when: ansible_distribution_file_variety == "Debian" tags: [ 'apache', 'apache_basic_auth' ] diff --git a/tasks/apache-config-deb.yml b/tasks/apache-config-deb.yml new file mode 100644 index 0000000..f896276 --- /dev/null +++ b/tasks/apache-config-deb.yml @@ -0,0 +1,22 @@ +--- +# On deb systems the packaged apache2.conf is left alone: only the listening +# ports and the default virtualhost are managed. +- name: apache-config-deb | Install the ports conf file + ansible.builtin.template: + src: ports.conf + dest: '{{ apache_base_conf_dir }}/ports.conf' + owner: root + group: root + mode: '0444' + notify: apache2 reload + tags: [ 'apache', 'apache_conf' ] + +- name: apache-config-deb | Remove the default virtualhost file + ansible.builtin.file: + dest: '{{ apache_base_conf_dir }}/sites-enabled/{{ item }}' + state: absent + with_items: + - 000-default + - 000-default.conf + notify: apache2 reload + tags: [ 'apache', 'apache_conf' ] diff --git a/tasks/apache-config-el.yml b/tasks/apache-config-el.yml new file mode 100644 index 0000000..5585269 --- /dev/null +++ b/tasks/apache-config-el.yml @@ -0,0 +1,23 @@ +--- +# On EL the whole httpd.conf is templated: the packaged one carries the tuning +# and the document root layout, so there is nothing equivalent to ports.conf to +# manage separately. +- name: apache-config-el | Install the main httpd configuration file + ansible.builtin.template: + src: httpd.conf.j2 + dest: '{{ apache_base_conf_dir }}/conf/httpd.conf' + owner: root + group: root + mode: '0444' + notify: apache2 reload + tags: [ 'apache', 'apache_conf' ] + +- name: apache-config-el | Set the MPM mode + ansible.builtin.template: + src: 00-mpm.conf.j2 + dest: '{{ apache_base_conf_dir }}/conf.modules.d/00-mpm.conf' + owner: root + group: root + mode: '0444' + notify: apache2 restart + tags: [ 'apache', 'apache_conf', 'apache_mods' ] diff --git a/tasks/apache-letsencrypt.yml b/tasks/apache-letsencrypt.yml index 4b1d662..d624908 100644 --- a/tasks/apache-letsencrypt.yml +++ b/tasks/apache-letsencrypt.yml @@ -1,43 +1,86 @@ --- -- block: - - name: Enable the proxy modules needed by letsencrypt - apache2_module: name={{ item }} state=present - with_items: '{{ apache_letsencrypt_proxy_modules }}' - ignore_errors: True - notify: apache2 reload - - - name: Install the apache letsencrypt directives on trusty - template: src={{ item }}.j2 dest=/etc/apache2/conf-available/{{ item }} owner=root group=root mode=0644 - with_items: '{{ apache_letsencrypt_proxy_conf }}' - ignore_errors: True - notify: apache2 reload - - - name: Enable the apache letsencrypt directives on trusty - file: src=/etc/apache2/conf-available/{{ item }} dest=/etc/apache2/conf-enabled/{{ item }} state=link - with_items: '{{ apache_letsencrypt_proxy_conf }}' - ignore_errors: True - notify: apache2 reload - - - name: Create the acme hooks directory if it does not yet exist - file: dest={{ letsencrypt_acme_services_scripts_dir }} state=directory owner=root group=root - - - name: Install a letsencrypt hook for apache - copy: src=apache-letsencrypt-acme.sh dest={{ letsencrypt_acme_services_scripts_dir }}/apache2 owner=root group=root mode=4555 - - when: - - letsencrypt_acme_install is defined and letsencrypt_acme_install - - apache_letsencrypt_managed +# The acme hook is named after the service, because that is the name the client +# uses to reload it: apache2 on deb, httpd on EL. +- name: apache-letsencrypt | Managed + when: apache_letsencrypt_managed tags: [ 'apache', 'letsencrypt' ] + block: + - name: apache-letsencrypt | Enable the proxy modules needed by letsencrypt, deb systems + community.general.apache2_module: + name: '{{ item }}' + state: present + with_items: '{{ apache_letsencrypt_proxy_modules }}' + when: ansible_distribution_file_variety == "Debian" + notify: apache2 reload -- block: - - name: Disable the letsencrypt conf - file: dest=/etc/apache2/conf-enabled/letsencrypt-proxy.conf state=absent - ignore_errors: True - notify: apache2 reload + - name: apache-letsencrypt | Install the letsencrypt directives, deb systems + ansible.builtin.template: + src: '{{ item }}.j2' + dest: '{{ apache_base_conf_dir }}/conf-available/{{ item }}' + owner: root + group: root + mode: '0644' + with_items: '{{ apache_letsencrypt_proxy_conf }}' + when: ansible_distribution_file_variety == "Debian" + notify: apache2 reload - - name: Remove the letsencrypt hook for apache - file: path={{ letsencrypt_acme_services_scripts_dir }}/apache2 state=absent + - name: apache-letsencrypt | Enable the letsencrypt directives, deb systems + ansible.builtin.file: + src: '{{ apache_base_conf_dir }}/conf-available/{{ item }}' + dest: '{{ apache_base_conf_dir }}/conf-enabled/{{ item }}' + state: link + with_items: '{{ apache_letsencrypt_proxy_conf }}' + when: ansible_distribution_file_variety == "Debian" + notify: apache2 reload + # EL has no conf-available and conf-enabled: everything under conf.d is read, + # and the 00- prefix puts these directives before the virtualhosts. + - name: apache-letsencrypt | Install the letsencrypt directives, EL systems + ansible.builtin.template: + src: '{{ item }}.j2' + dest: '{{ apache_base_conf_dir }}/conf.d/00-{{ item }}' + owner: root + group: root + mode: '0644' + with_items: '{{ apache_letsencrypt_proxy_conf }}' + when: ansible_distribution_file_variety == "RedHat" + notify: apache2 reload + + - name: apache-letsencrypt | Create the acme hooks directory if it does not yet exist + ansible.builtin.file: + dest: '{{ letsencrypt_acme_services_scripts_dir }}' + state: directory + owner: root + group: root + mode: '0755' + + - name: apache-letsencrypt | Install the letsencrypt hook + ansible.builtin.copy: + src: apache-letsencrypt-acme.sh + dest: '{{ letsencrypt_acme_services_scripts_dir }}/{{ apache_service_name }}' + owner: root + group: root + mode: '4555' + +- name: apache-letsencrypt | Not managed when: not apache_letsencrypt_managed tags: [ 'apache', 'letsencrypt' ] + block: + - name: apache-letsencrypt | Disable the letsencrypt conf, deb systems + ansible.builtin.file: + dest: '{{ apache_base_conf_dir }}/conf-enabled/letsencrypt-proxy.conf' + state: absent + when: ansible_distribution_file_variety == "Debian" + notify: apache2 reload + - name: apache-letsencrypt | Remove the letsencrypt conf, EL systems + ansible.builtin.file: + dest: '{{ apache_base_conf_dir }}/conf.d/00-letsencrypt-proxy.conf' + state: absent + when: ansible_distribution_file_variety == "RedHat" + notify: apache2 reload + + - name: apache-letsencrypt | Remove the letsencrypt hook + ansible.builtin.file: + path: '{{ letsencrypt_acme_services_scripts_dir }}/{{ apache_service_name }}' + state: absent diff --git a/tasks/apache-modules.yml b/tasks/apache-modules-deb.yml similarity index 90% rename from tasks/apache-modules.yml rename to tasks/apache-modules-deb.yml index 2efc7de..120e28e 100644 --- a/tasks/apache-modules.yml +++ b/tasks/apache-modules-deb.yml @@ -56,7 +56,7 @@ tags: [ 'apache', 'apache_mods', 'apache_status' ] - name: Configure the apache status module - template: src={{ item }}.j2 dest=/etc/apache2/mods-available/{{ item }} owner=root group=root mode=0644 + template: src={{ item }}.j2 dest={{ apache_base_conf_dir }}/mods-available/{{ item }} owner=root group=root mode=0644 with_items: status.conf when: apache_status_module notify: apache2 reload @@ -70,7 +70,7 @@ tags: [ 'apache', 'apache_mods', 'apache_info' ] - name: Configure the apache info module - template: src={{ item }}.j2 dest=/etc/apache2/mods-available/{{ item }} owner=root group=root mode=0644 + template: src={{ item }}.j2 dest={{ apache_base_conf_dir }}/mods-available/{{ item }} owner=root group=root mode=0644 with_items: info.conf when: apache_info_module notify: apache2 reload diff --git a/tasks/apache-modules-el.yml b/tasks/apache-modules-el.yml new file mode 100644 index 0000000..2c44e1b --- /dev/null +++ b/tasks/apache-modules-el.yml @@ -0,0 +1,28 @@ +--- +# a2enmod does not exist on EL, and the apache2_module Ansible module requires +# both a2enmod and a2dismod: the module list of the httpd role this one absorbs +# could never be applied there. On EL the distribution loads its modules from +# conf.modules.d, the MPM is selected by apache-config-el.yml, and this file only +# adds the ones the distribution does not load by default. +- name: apache-modules-el | Load the extra modules, if any + ansible.builtin.copy: + content: | + # {{ ansible_managed }} + {% for mod in apache_el_extra_modules %} + LoadModule {{ mod.identifier }} modules/{{ mod.file }} + {% endfor %} + dest: '{{ apache_base_conf_dir }}/conf.modules.d/50-ansible-extra.conf' + owner: root + group: root + mode: '0444' + when: apache_el_extra_modules | length > 0 + notify: apache2 restart + tags: [ 'apache', 'apache_mods' ] + +- name: apache-modules-el | Remove the extra modules file when the list is empty + ansible.builtin.file: + dest: '{{ apache_base_conf_dir }}/conf.modules.d/50-ansible-extra.conf' + state: absent + when: apache_el_extra_modules | length == 0 + notify: apache2 restart + tags: [ 'apache', 'apache_mods' ] diff --git a/tasks/apache-packages.yml b/tasks/apache-packages.yml new file mode 100644 index 0000000..5a6b90d --- /dev/null +++ b/tasks/apache-packages.yml @@ -0,0 +1,47 @@ +--- +- name: apache-packages | Deb systems + when: ansible_distribution_file_variety == "Debian" + tags: [ 'apache', 'apache_main_packages' ] + block: + - name: apache-packages | Install the apache packages + ansible.builtin.apt: + pkg: '{{ apache_packages }}' + state: '{{ apache_pkg_state }}' + cache_valid_time: 3600 + + - name: apache-packages | Install the apache modules packages + ansible.builtin.apt: + pkg: '{{ apache_modules_packages }}' + state: '{{ apache_pkg_state }}' + cache_valid_time: 3600 + when: + - not apache_from_ppa + - ansible_distribution_version is version_compare('16.04', '<=') + + - name: apache-packages | Install the apache additional packages, if any + ansible.builtin.apt: + pkg: '{{ apache_additional_packages_list }}' + state: '{{ apache_pkg_state }}' + cache_valid_time: 3600 + when: apache_additional_packages_list | length > 0 + +- name: apache-packages | EL systems + when: ansible_distribution_file_variety == "RedHat" + tags: [ 'apache', 'apache_main_packages' ] + block: + - name: apache-packages | Install the httpd packages + ansible.builtin.yum: + name: '{{ apache_packages }}' + state: '{{ apache_pkg_state }}' + + - name: apache-packages | Install mod_ssl + ansible.builtin.yum: + name: '{{ apache_ssl_packages }}' + state: '{{ apache_pkg_state }}' + when: apache_ssl_modules_enabled + + - name: apache-packages | Install the apache additional packages, if any + ansible.builtin.yum: + name: '{{ apache_additional_packages_list }}' + state: '{{ apache_pkg_state }}' + when: apache_additional_packages_list | length > 0 diff --git a/tasks/apache-service.yml b/tasks/apache-service.yml new file mode 100644 index 0000000..4ec7d5c --- /dev/null +++ b/tasks/apache-service.yml @@ -0,0 +1,16 @@ +--- +- name: apache-service | Ensure that the apache service is enabled and started + ansible.builtin.service: + name: '{{ apache_service_name }}' + state: started + enabled: yes + when: apache_service_enabled + tags: apache + +- name: apache-service | Ensure that the apache service is stopped and disabled + ansible.builtin.service: + name: '{{ apache_service_name }}' + state: stopped + enabled: no + when: not apache_service_enabled + tags: apache diff --git a/tasks/apache.yml b/tasks/apache.yml deleted file mode 100644 index 4bdabc9..0000000 --- a/tasks/apache.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- -- name: Manage the apache packages on Ubuntu or Debian - block: - - name: Install the apache packages - apt: pkg={{ apache_packages }} state={{ apache_pkg_state }} cache_valid_time=3600 - tags: [ 'apache', 'apache_main_packages' ] - - - name: Install the apache modules packages - apt: pkg={{ apache_modules_packages }} state={{ apache_pkg_state }} cache_valid_time=3600 - when: - - not apache_from_ppa - - ansible_distribution_version is version_compare('16.04', '<=') - tags: [ 'apache', 'apache_additional_packages' ] - - - name: Install the apache additional packages, if any - apt: pkg={{ apache_additional_packages_list }} state={{ apache_pkg_state }} cache_valid_time=3600 - tags: [ 'apache', 'apache_additional_packages' ] - - - name: Install the ports conf file - template: src=ports.conf dest=/etc/apache2/ports.conf - notify: apache2 reload - tags: [ 'apache', 'apache_conf' ] - - - name: Remove the default virtualhost file - file: dest=/etc/apache2/sites-enabled/{{ item }} state=absent - with_items: - - 000-default - - 000-default.conf - notify: apache2 reload - - when: ansible_distribution_file_variety == "Debian" - tags: apache - -- name: Ensure that the apache service is enabled and started - service: name=apache2 state=started enabled=yes - when: apache_service_enabled - ignore_errors: True - tags: apache - -- name: Ensure that the apache service is disabled and stopped if we do not want it running - service: name=apache2 state=stopped enabled=no - when: not apache_service_enabled - ignore_errors: True - tags: apache diff --git a/tasks/main.yml b/tasks/main.yml index d9446a6..837cb58 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,9 +1,34 @@ --- -- import_tasks: apache-ppa.yml +- name: Apache PPA on deb systems + ansible.builtin.import_tasks: apache-ppa.yml when: ansible_distribution_file_variety == "Debian" -- import_tasks: apache.yml -- import_tasks: apache-modules.yml -- import_tasks: apache-basic-auth.yml + +- name: Apache packages + ansible.builtin.import_tasks: apache-packages.yml + +- name: Apache configuration on deb systems + ansible.builtin.import_tasks: apache-config-deb.yml + when: ansible_distribution_file_variety == "Debian" + +- name: Apache configuration on EL systems + ansible.builtin.import_tasks: apache-config-el.yml + when: ansible_distribution_file_variety == "RedHat" + +- name: Apache modules on deb systems + ansible.builtin.import_tasks: apache-modules-deb.yml + when: ansible_distribution_file_variety == "Debian" + +- name: Apache modules on EL systems + ansible.builtin.import_tasks: apache-modules-el.yml + when: ansible_distribution_file_variety == "RedHat" + +- name: Apache basic auth + ansible.builtin.import_tasks: apache-basic-auth.yml when: apache_basic_auth -- import_tasks: apache-letsencrypt.yml + +- name: Apache letsencrypt hooks + ansible.builtin.import_tasks: apache-letsencrypt.yml when: letsencrypt_acme_install is defined and letsencrypt_acme_install + +- name: Apache service + ansible.builtin.import_tasks: apache-service.yml