diff --git a/README.md b/README.md index 580aa40..062a55c 100644 --- a/README.md +++ b/README.md @@ -1,121 +1,71 @@ -Role Name -========= +# ansible-role-apache -A role that installs and configures the apache web server +Installs and configures Apache httpd on Debian and Ubuntu and on EL 8 and 9. +The EL side comes from the separate `httpd` role of the old library, absorbed +here. -Role Variables --------------- +## Variable names -The most important variables are listed below: +There is one namespace, `apache_*`. The absorbed role used `httpd_*` and those +names are gone: a playbook that still sets them has no effect. The rename is +mechanical, `httpd_x` becomes `apache_x`, with four exceptions: -``` yaml -apache_service_enabled: True -apache_user: www-data -apache_pkg_state: latest -apache_group: '{{ apache_user }}' -apache_from_ppa: False -apache_ppa_repo: 'ppa:ondrej/apache2' +| old | new | +|----------------------------|------------------------------| +| `httpd_main_packages` | `apache_packages` | +| `httpd_ssl_enabled` | `apache_ssl_modules_enabled` | +| `httpd_modules` | see *Modules* below | +| `httpd_additional_modules` | see *Modules* below | -apache_listen_ports: - - 80 - - '{{ apache_ssl_port }}' +Distribution differences live inside the defaults, the convention already used +by `ansible-role-postgresql`, so every value stays a default and a playbook can +still override it. -# Possible choices: event, prefork (the old ones), worker (the threaded version), itm -apache_mpm_mode: worker +| | deb | EL | +|--------------------|---------------------------|-----------------------| +| packages | `apache2`, `apache2-utils`| `httpd`, `httpd-tools`| +| mod_ssl | part of `apache2` | separate package | +| service | `apache2` | `httpd` | +| config directory | `/etc/apache2` | `/etc/httpd` | +| user, group | `www-data` | `apache` | +| main config file | left to the package | fully templated | -apache_packages: - - apache2 - - apache2-utils - - libapache2-mod-xsendfile - - unzip - - zip +## Configuration model -apache_modules_packages: - - 'apache2-mpm-{{ apache_mpm_mode }}' +The two families do not configure Apache the same way, and the role does not +pretend otherwise. -# Only one can be present at the same time. It needs to be listed as the last one -apache_worker_modules: -# - { name: 'mpm_itm', state: 'absent' } - - { name: 'mpm_event', state: 'absent' } - - { name: 'mpm_prefork', state: 'absent' } - - { name: 'mpm_{{ apache_mpm_mode }}', state: 'present' } +On deb the packaged `apache2.conf` is left alone: the role manages `ports.conf`, +removes the default virtualhost and enables modules with `a2enmod`. -# apache RPAF is needed to obtain the real client addresses when behind a reverse proxy -apache_rpaf_install: False +On EL the whole `httpd.conf` is templated, because that is where the tuning and +the document root layout live. This is what the `apache_timeout`, +`apache_keepalive_*`, `apache_startservers`, `apache_maxclients`, +`apache_min_spare`, `apache_max_spare`, `apache_threads_per_child`, +`apache_serverlimit` and `apache_max_requests_per_child` variables feed, and they +have no effect on deb. -apache_default_modules: - - headers - - rewrite - - expires - - xsendfile +## Modules -apache_ssl_modules_enabled: True -apache_ssl_port: 443 -apache_ssl_modules: - - ssl - - socache_shmcb -apache_http_proxy_modules_enabled: False -apache_http_proxy_modules: - - proxy - - proxy_ajp - - proxy_http +On deb, modules are enabled with `apache2_module`, from `apache_default_modules`, +`apache_additional_modules_list`, `apache_ssl_modules` and +`apache_http_proxy_modules`. -apache_status_module: True -apache_status_location: '/server-status' -apache_status_allowed_hosts: - - 127.0.0.1/8 +On EL none of that applies. The `apache2_module` Ansible module requires the +`a2enmod` and `a2dismod` binaries, which the EL httpd package does not ship, so +the `httpd_modules` list of the absorbed role could never be applied there. What +EL needs is the MPM selection, written to `conf.modules.d/00-mpm.conf` from +`apache_mpm_mode`, while the individual `LoadModule` lines come from the +distribution's own `conf.modules.d`. `apache_el_extra_modules` adds the ones the +distribution does not load by default: -apache_info_module: True -apache_info_location: '/server-info' -apache_info_allowed_hosts: - - 127.0.0.1/8 - -apache_basic_auth: False -apache_basic_auth_single_file: True -apache_basic_auth_dir: /etc/apache2/auth -apache_basic_auth_file: '{{ apache_basic_auth_dir }}/htpasswd' - -apache_basic_auth_modules: - - auth_basic - - authn_file - - authz_user - -# Put them in a vault file. auth_file is optional. Not used when apache_basic_auth_single_file is true -apache_basic_users: - - { username:'', password:'', state:'present,absent', auth_file:'path_to_file' } - -# -apache_additional_packages: False -apache_additional_packages_list: -# - libapache2-mod-uwsgi -# - ... -# -# Set this variable to load the modules you need -apache_additional_modules: False -apache_additional_modules_list: [] -# - -# - - -apache_letsencrypt_managed: True -apache_letsencrypt_proxy_modules: - - proxy - - proxy_http - -apache_letsencrypt_proxy_conf: - - letsencrypt-proxy.conf +```yaml +apache_el_extra_modules: + - { identifier: 'jk_module', file: 'mod_jk.so' } ``` -Dependencies ------------- +## Handlers -None - -License -------- - -EUPL-1.2 - -Author Information ------------------- - -Andrea Dell'Amico, +`apache2 reload` and `apache2 restart` act on the right service on both +families. `httpd reload` and `httpd restart` exist as well, with the same +behaviour, for the roles that come from the absorbed one and notify those names. diff --git a/defaults/main.yml b/defaults/main.yml index 231756a..84ee745 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,6 +1,6 @@ --- apache_service_enabled: True -apache_user: www-data +apache_user: '{% if ansible_distribution_file_variety == "Debian" %}www-data{% else %}apache{% endif %}' apache_pkg_state: present apache_group: '{{ apache_user }}' apache_from_ppa: False @@ -13,12 +13,24 @@ apache_listen_ports: # Possible choices: event, prefork (the old ones), worker (the threaded version), itm apache_mpm_mode: worker -apache_packages: +apache_packages: "{{ apache_deb_packages if ansible_distribution_file_variety == 'Debian' else apache_el_packages }}" +apache_deb_packages: - apache2 - apache2-utils - libapache2-mod-xsendfile - unzip - zip +apache_el_packages: + - httpd + - httpd-tools +# EL only: mod_ssl is a separate package, on deb it is part of apache2 +apache_ssl_packages: + - mod_ssl + +apache_service_name: '{% if ansible_distribution_file_variety == "Debian" %}apache2{% else %}httpd{% endif %}' +apache_base_conf_dir: '{% if ansible_distribution_file_variety == "Debian" %}/etc/apache2{% else %}/etc/httpd{% endif %}' +apache_base_document_root: '{% if ansible_distribution_file_variety == "Debian" %}/var/www{% else %}/var/www{% endif %}' +apache_document_root: '{{ apache_base_document_root }}/html' apache_modules_packages: - 'apache2-mpm-{{ apache_mpm_mode }}' @@ -62,7 +74,7 @@ apache_info_allowed_hosts: apache_basic_auth: False apache_basic_auth_single_file: True -apache_basic_auth_dir: /etc/apache2/auth +apache_basic_auth_dir: '{{ apache_base_conf_dir }}/auth' apache_basic_auth_file: '{{ apache_basic_auth_dir }}/htpasswd' apache_basic_auth_modules: @@ -91,3 +103,52 @@ apache_letsencrypt_proxy_modules: apache_letsencrypt_proxy_conf: - letsencrypt-proxy.conf + +# +# EL only settings. They come from the httpd role this one absorbs, renamed from +# httpd_* to apache_*: on EL the whole httpd.conf is templated, while on deb the +# packaged apache2.conf is left alone and only ports.conf and the modules are +# managed. +# +apache_server_admin: root@localhost +apache_base_document_root_override: 'None' +apache_base_document_root_access: 'denied' +apache_document_root_options: 'Indexes FollowSymLinks' +apache_document_root_override: 'None' +apache_document_root_access: 'granted' + +apache_cgi_enabled: False +apache_sendfile_enabled: 'on' +apache_mmap_enabled: 'on' +apache_use_canonicalname: 'off' +# The httpd role this one absorbs used OS. Prod is the safer value, but changing +# it here would be a silent change for every host that inherits the default. +apache_servertokens: 'OS' +apache_hostname_lookups: 'off' +apache_default_charset: 'UTF-8' +apache_languages: + - en + - it + +apache_timeout: 60 +apache_keepalive_enabled: True +apache_keepalive_timeout: 5 +apache_keepalive_requests: 100 + +# MPM tuning, used by the EL httpd.conf template +apache_startservers: 8 +apache_maxclients: 300 +apache_min_spare: 25 +apache_max_spare: 75 +apache_max_requests_per_child: 0 +apache_threads_per_child: 25 +apache_serverlimit: 256 + +# Modules on EL are not managed with a2enmod: the apache2_module Ansible module +# requires the a2enmod and a2dismod binaries, which the EL httpd package does not +# ship, so the module list of the old role could never be applied there. What EL +# actually needs is the MPM selection, written into conf.modules.d/00-mpm.conf, +# plus an optional file for modules the distribution does not load by default. +# Every entry is emitted as: LoadModule modules/ +apache_el_extra_modules: [] +# - { identifier: 'jk_module', file: 'mod_jk.so' } 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/meta/main.yml b/meta/main.yml index fddbfd8..162682f 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,26 +1,29 @@ +--- galaxy_info: - author: Andrea Dell'Amico - description: Systems Architect + author: adellam + description: Apache httpd installation and configuration, on deb and EL systems company: ISTI-CNR - - issue_tracker_url: https://redmine-s2i2s.isti.cnr.it/projects/provisioning - + namespace: adellam + role_name: apache license: EUPL 1.2+ - - min_ansible_version: 2.8 - - # To view available platforms and versions (or releases), visit: - # https://galaxy.ansible.com/api/v1/platforms/ - # + min_ansible_version: "2.9" platforms: - name: Ubuntu versions: - - bionic - + - focal + - jammy + - noble + - name: Debian + versions: + - bullseye + - bookworm + - name: EL + versions: + - "8" + - "9" galaxy_tags: - apache - httpd + - web dependencies: [] - - 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 diff --git a/templates/00-mpm.conf.j2 b/templates/00-mpm.conf.j2 new file mode 100644 index 0000000..eae5aca --- /dev/null +++ b/templates/00-mpm.conf.j2 @@ -0,0 +1 @@ +LoadModule mpm_{{ apache_mpm_mode }}_module modules/mod_mpm_{{ apache_mpm_mode }}.so diff --git a/templates/httpd.conf.j2 b/templates/httpd.conf.j2 new file mode 100644 index 0000000..653536c --- /dev/null +++ b/templates/httpd.conf.j2 @@ -0,0 +1,395 @@ +# +# This is the main Apache HTTP server configuration file. It contains the +# configuration directives that give the server its instructions. +# See for detailed information. +# In particular, see +# +# for a discussion of each configuration directive. +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# +# Configuration and logfile names: If the filenames you specify for many +# of the server's control files begin with "/" (or "drive:/" for Win32), the +# server will use that explicit path. If the filenames do *not* begin +# with "/", the value of ServerRoot is prepended -- so 'log/access_log' +# with ServerRoot set to '/www' will be interpreted by the +# server as '/www/log/access_log', where as '/log/access_log' will be +# interpreted as '/log/access_log'. + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# Do not add a slash at the end of the directory path. If you point +# ServerRoot at a non-local disk, be sure to specify a local disk on the +# Mutex directive, if file-based mutexes are used. If you wish to share the +# same ServerRoot for multiple httpd daemons, you will need to change at +# least PidFile. +# +ServerRoot "{{ apache_base_conf_dir }}" + +# +# Listen: Allows you to bind Apache to specific IP addresses and/or +# ports, instead of the default. See also the +# directive. +# +# Change this to Listen on specific IP addresses as shown below to +# prevent Apache from glomming onto all bound IP addresses. +# +#Listen 12.34.56.78:80 +{% for port in apache_listen_ports %} +Listen {{ port }} +{% endfor %} + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Statically compiled modules (those listed by `httpd -l') do not need +# to be loaded here. +# +# Example: +# LoadModule foo_module modules/mod_foo.so +# +Include conf.modules.d/*.conf + +# +# If you wish httpd to run as a different user or group, you must run +# httpd as root initially and it will switch. +# +# User/Group: The name (or #number) of the user/group to run httpd as. +# It is usually good practice to create a dedicated user and group for +# running httpd, as with most system services. +# +User {{ apache_user }} +Group {{ apache_group }} + +# 'Main' server configuration +# +# The directives in this section set up the values used by the 'main' +# server, which responds to any requests that aren't handled by a +# definition. These values also provide defaults for +# any containers you may define later in the file. +# +# All of these directives may appear inside containers, +# in which case these default settings will be overridden for the +# virtual host being defined. +# + +# +# ServerAdmin: Your address, where problems with the server should be +# e-mailed. This address appears on some server-generated pages, such +# as error documents. e.g. admin@your-domain.com +# +ServerAdmin {{ apache_server_admin }} + +# +# ServerName gives the name and port that the server uses to identify itself. +# This can often be determined automatically, but we recommend you specify +# it explicitly to prevent problems during startup. +# +# If your host doesn't have a registered DNS name, enter its IP address here. +# +#ServerName www.example.com:80 + +# +# Deny access to the entirety of your server's filesystem. You must +# explicitly permit access to web content directories in other +# blocks below. +# + + AllowOverride none + Require all denied + + +# +# Note that from this point forward you must specifically allow +# particular features to be enabled - so if something's not working as +# you might expect, make sure that you have specifically enabled it +# below. +# + +# +# DocumentRoot: The directory out of which you will serve your +# documents. By default, all requests are taken from this directory, but +# symbolic links and aliases may be used to point to other locations. +# +DocumentRoot "{{ apache_document_root }}" + +# +# Regulate access to the main root directories +# + + AllowOverride {{ apache_base_document_root_override }} + # Allow open access: + Require all granted + + +# Further relax access to the default document root: + + # + # Possible values for the Options directive are "None", "All", + # or any combination of: + # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews + # + # Note that "MultiViews" must be named *explicitly* --- "Options All" + # doesn't give it to you. + # + # The Options directive is both complicated and important. Please see + # http://httpd.apache.org/docs/2.4/mod/core.html#options + # for more information. + # + Options {{ apache_document_root_options }} + + # + # AllowOverride controls what directives may be placed in .htaccess files. + # It can be "All", "None", or any combination of the keywords: + # Options FileInfo AuthConfig Limit + # + AllowOverride {{ apache_document_root_override }} + + # + # Controls who can get stuff from this server. + # + Require all {{ apache_document_root_access }} + + +# +# DirectoryIndex: sets the file that Apache will serve if a directory +# is requested. +# + + DirectoryIndex index.html + + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Require all denied + + +# +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog "logs/error_log" + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + + + # + # The following directives define some format nicknames for use with + # a CustomLog directive (see below). + # + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b" common + + + # You need to enable mod_logio.c to use %I and %O + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + # + # The location and format of the access logfile (Common Logfile Format). + # If you do not define any access logfiles within a + # container, they will be logged here. Contrariwise, if you *do* + # define per- access logfiles, transactions will be + # logged therein and *not* in this file. + # + #CustomLog "logs/access_log" common + + # + # If you prefer a logfile with access, agent, and referer information + # (Combined Logfile Format) you can use the following directive. + # + CustomLog "logs/access_log" combined + + +{% if apache_cgi_enabled %} + + # + # Redirect: Allows you to tell clients about documents that used to + # exist in your server's namespace, but do not anymore. The client + # will make a new request for the document at its new location. + # Example: + # Redirect permanent /foo http://www.example.com/bar + + # + # Alias: Maps web paths into filesystem paths and is used to + # access content that does not live under the DocumentRoot. + # Example: + # Alias /webpath /full/filesystem/path + # + # If you include a trailing / on /webpath then the server will + # require it to be present in the URL. You will also likely + # need to provide a section to allow access to + # the filesystem path. + + # + # ScriptAlias: This controls which directories contain server scripts. + # ScriptAliases are essentially the same as Aliases, except that + # documents in the target directory are treated as applications and + # run by the server when requested rather than as documents sent to the + # client. The same rules about trailing "/" apply to ScriptAlias + # directives as to Alias. + # + ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" + + + +# +# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased +# CGI directory exists, if you have that configured. +# + + AllowOverride None + Options None + Require all granted + +{% endif %} + + # + # TypesConfig points to the file containing the list of mappings from + # filename extension to MIME-type. + # + TypesConfig /etc/mime.types + + # + # AddType allows you to add to or override the MIME configuration + # file specified in TypesConfig for specific file types. + # + #AddType application/x-gzip .tgz + # + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + # + #AddEncoding x-compress .Z + #AddEncoding x-gzip .gz .tgz + # + # If the AddEncoding directives above are commented-out, then you + # probably should define those extensions to indicate media types: + # + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + + # + # AddHandler allows you to map certain file extensions to "handlers": + # actions unrelated to filetype. These can be either built into the server + # or added with the Action directive (see below) + # + # To use CGI scripts outside of ScriptAliased directories: + # (You will also need to add "ExecCGI" to the "Options" directive.) + # + #AddHandler cgi-script .cgi + + # For type maps (negotiated resources): + #AddHandler type-map var + + # + # Filters allow you to process content before it is sent to the client. + # + # To parse .shtml files for server-side includes (SSI): + # (You will also need to add "Includes" to the "Options" directive.) + # + AddType text/html .shtml + AddOutputFilter INCLUDES .shtml + + +# +# Specify a default charset for all content served; this enables +# interpretation of all content as UTF-8 by default. To use the +# default browser choice (ISO-8859-1), or to allow the META tags +# in HTML content to override this choice, comment out this +# directive: +# +AddDefaultCharset UTF-8 + + + # + # The mod_mime_magic module allows the server to use various hints from the + # contents of the file itself to determine its type. The MIMEMagicFile + # directive tells the module where the hint definitions are located. + # + MIMEMagicFile conf/magic + + +# +# Customizable error responses come in three flavors: +# 1) plain text 2) local redirects 3) external redirects +# +# Some examples: +#ErrorDocument 500 "The server made a boo boo." +#ErrorDocument 404 /missing.html +#ErrorDocument 404 "/cgi-bin/missing_handler.pl" +#ErrorDocument 402 http://www.example.com/subscription_info.html +# + +# +# EnableMMAP and EnableSendfile: On systems that support it, +# memory-mapping or the sendfile syscall may be used to deliver +# files. This usually improves server performance, but must +# be turned off when serving from networked-mounted +# filesystems or if support for these functions is otherwise +# broken on your system. +# Defaults if commented: EnableMMAP On, EnableSendfile Off +# +EnableMMAP {{ apache_mmap_enabled }} +EnableSendfile {{ apache_mmap_enabled }} + +ServerTokens {{ apache_servertokens }} +UseCanonicalName {{ apache_use_canonicalname }} +HostnameLookups {{ apache_hostname_lookups }} +AddDefaultCharset {{ apache_default_charset}} +{% for lang in apache_languages %} +AddLanguage {{ lang }} .{{ lang }} +{% endfor %} +Timeout {{ apache_timeout }} + +{% if apache_keepalive_enabled %} +KeepAlive On +MaxKeepAliveRequests {{ apache_keepalive_requests }} +KeepAliveTimeout {{ apache_keepalive_timeout }} +{% else %} +KeepAlive Off +{% endif %} + +{% if apache_mpm_mode == 'prefork' %} + +StartServers {{ apache_startservers }} +MinSpareServers {{ apache_min_spare }} +MaxSpareServers {{ apache_max_spare }} +ServerLimit {{ apache_serverlimit }} +MaxClients {{ apache_maxclients }} +MaxRequestsPerChild {{ apache_max_requests_per_child }} + +{% endif %} + +{% if apache_mpm_mode == 'worker' %} + +StartServers {{ apache_startservers }} +MaxClients {{ apache_maxclients }} +MinSpareThreads {{ apache_min_spare }} +MaxSpareThreads {{ apache_max_spare }} +ThreadsPerChild {{ apache_threads_per_child }} +MaxRequestsPerChild {{ apache_max_requests_per_child }} + +{% endif %} + +# Supplemental configuration +# +# Load config files in the "/etc/httpd/conf.d" directory, if any. +IncludeOptional conf.d/*.conf