├── .ansible-lint ├── .github ├── FUNDING.yml └── workflows │ ├── ci.yml │ ├── release.yml │ └── stale.yml ├── .gitignore ├── .yamllint ├── LICENSE ├── README.md ├── defaults └── main.yml ├── handlers └── main.yml ├── meta └── main.yml ├── molecule └── default │ ├── converge.yml │ └── molecule.yml ├── tasks ├── configure-Debian.yml ├── configure-RedHat.yml ├── configure-Solaris.yml ├── configure-Suse.yml ├── main.yml ├── setup-Debian.yml ├── setup-RedHat.yml ├── setup-Solaris.yml └── setup-Suse.yml ├── templates └── vhosts.conf.j2 └── vars ├── AmazonLinux.yml ├── Debian.yml ├── RedHat.yml ├── Solaris.yml ├── Suse.yml ├── apache-22.yml └── apache-24.yml /.ansible-lint: -------------------------------------------------------------------------------- 1 | skip_list: 2 | - 'yaml' 3 | - 'role-name' 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | --- 3 | github: geerlingguy 4 | patreon: geerlingguy 5 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 'on': 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | schedule: 9 | - cron: "0 5 * * 0" 10 | 11 | defaults: 12 | run: 13 | working-directory: 'geerlingguy.apache' 14 | 15 | jobs: 16 | 17 | lint: 18 | name: Lint 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Check out the codebase. 22 | uses: actions/checkout@v4 23 | with: 24 | path: 'geerlingguy.apache' 25 | 26 | - name: Set up Python 3. 27 | uses: actions/setup-python@v5 28 | with: 29 | python-version: '3.x' 30 | 31 | - name: Install test dependencies. 32 | run: pip3 install yamllint 33 | 34 | - name: Lint code. 35 | run: | 36 | yamllint . 37 | 38 | molecule: 39 | name: Molecule 40 | runs-on: ubuntu-latest 41 | strategy: 42 | matrix: 43 | distro: 44 | - rockylinux9 45 | - ubuntu2204 46 | - debian11 47 | - debian12 48 | 49 | steps: 50 | - name: Check out the codebase. 51 | uses: actions/checkout@v4 52 | with: 53 | path: 'geerlingguy.apache' 54 | 55 | - name: Set up Python 3. 56 | uses: actions/setup-python@v5 57 | with: 58 | python-version: '3.x' 59 | 60 | - name: Install test dependencies. 61 | run: pip3 install ansible molecule molecule-plugins[docker] docker 62 | 63 | - name: Run Molecule tests. 64 | run: molecule test 65 | env: 66 | PY_COLORS: '1' 67 | ANSIBLE_FORCE_COLOR: '1' 68 | MOLECULE_DISTRO: ${{ matrix.distro }} 69 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This workflow requires a GALAXY_API_KEY secret present in the GitHub 3 | # repository or organization. 4 | # 5 | # See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy 6 | # See: https://github.com/ansible/galaxy/issues/46 7 | 8 | name: Release 9 | 'on': 10 | push: 11 | tags: 12 | - '*' 13 | 14 | defaults: 15 | run: 16 | working-directory: 'geerlingguy.apache' 17 | 18 | jobs: 19 | 20 | release: 21 | name: Release 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Check out the codebase. 25 | uses: actions/checkout@v4 26 | with: 27 | path: 'geerlingguy.apache' 28 | 29 | - name: Set up Python 3. 30 | uses: actions/setup-python@v5 31 | with: 32 | python-version: '3.x' 33 | 34 | - name: Install Ansible. 35 | run: pip3 install ansible-core 36 | 37 | - name: Trigger a new import on Galaxy. 38 | run: >- 39 | ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} 40 | $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) 41 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Close inactive issues 3 | 'on': 4 | schedule: 5 | - cron: "55 18 * * 1" # semi-random time 6 | 7 | jobs: 8 | close-issues: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | issues: write 12 | pull-requests: write 13 | steps: 14 | - uses: actions/stale@v8 15 | with: 16 | days-before-stale: 120 17 | days-before-close: 60 18 | exempt-issue-labels: bug,pinned,security,planned 19 | exempt-pr-labels: bug,pinned,security,planned 20 | stale-issue-label: "stale" 21 | stale-pr-label: "stale" 22 | stale-issue-message: | 23 | This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! 24 | 25 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. 26 | close-issue-message: | 27 | This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. 28 | stale-pr-message: | 29 | This pr has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! 30 | 31 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. 32 | close-pr-message: | 33 | This pr has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. 34 | repo-token: ${{ secrets.GITHUB_TOKEN }} 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | */__pycache__ 3 | *.pyc 4 | .cache 5 | 6 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | line-length: 6 | max: 120 7 | level: warning 8 | 9 | ignore: | 10 | .github/workflows/stale.yml 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Jeff Geerling 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ansible Role: Apache 2.x 2 | 3 | [![CI](https://github.com/geerlingguy/ansible-role-apache/actions/workflows/ci.yml/badge.svg)](https://github.com/geerlingguy/ansible-role-apache/actions/workflows/ci.yml) 4 | 5 | An Ansible Role that installs Apache 2.x on RHEL/CentOS, Debian/Ubuntu, SLES and Solaris. 6 | 7 | ## Requirements 8 | 9 | If you are using SSL/TLS, you will need to provide your own certificate and key files. You can generate a self-signed certificate with a command like `openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout example.key -out example.crt`. 10 | 11 | If you are using Apache with PHP, I recommend using the `geerlingguy.php` role to install PHP, and you can either use mod_php (by adding the proper package, e.g. `libapache2-mod-php5` for Ubuntu, to `php_packages`), or by also using `geerlingguy.apache-php-fpm` to connect Apache to PHP via FPM. See that role's README for more info. 12 | 13 | ## Role Variables 14 | 15 | Available variables are listed below, along with default values (see `defaults/main.yml`): 16 | 17 | ```yaml 18 | apache_enablerepo: "" 19 | ``` 20 | 21 | The repository to use when installing Apache (only used on RHEL/CentOS systems). If you'd like later versions of Apache than are available in the OS's core repositories, use a repository like EPEL (which can be installed with the `geerlingguy.repo-epel` role). 22 | 23 | ```yaml 24 | apache_listen_ip: "*" 25 | apache_listen_port: 80 26 | apache_listen_port_ssl: 443 27 | ``` 28 | 29 | The IP address and ports on which apache should be listening. Useful if you have another service (like a reverse proxy) listening on port 80 or 443 and need to change the defaults. 30 | 31 | ```yaml 32 | apache_create_vhosts: true 33 | apache_vhosts_filename: "vhosts.conf" 34 | apache_vhosts_template: "vhosts.conf.j2" 35 | ``` 36 | 37 | If set to true, a vhosts file, managed by this role's variables (see below), will be created and placed in the Apache configuration folder. If set to false, you can place your own vhosts file into Apache's configuration folder and skip the convenient (but more basic) one added by this role. You can also override the template used and set a path to your own template, if you need to further customize the layout of your VirtualHosts. 38 | 39 | ```yaml 40 | apache_remove_default_vhost: false 41 | ``` 42 | 43 | On Debian/Ubuntu, a default virtualhost is included in Apache's configuration. Set this to `true` to remove that default virtualhost configuration file. 44 | 45 | ```yaml 46 | apache_global_vhost_settings: | 47 | DirectoryIndex index.php index.html 48 | # Add other global settings on subsequent lines. 49 | ``` 50 | 51 | You can add or override global Apache configuration settings in the role-provided vhosts file (assuming `apache_create_vhosts` is true) using this variable. By default it only sets the DirectoryIndex configuration. 52 | 53 | ```yaml 54 | apache_vhosts: 55 | # Additional optional properties: 'serveradmin, serveralias, extra_parameters'. 56 | - servername: "local.dev" 57 | documentroot: "/var/www/html" 58 | ``` 59 | 60 | Add a set of properties per virtualhost, including `servername` (required), `documentroot` (required), `allow_override` (optional: defaults to the value of `apache_allow_override`), `options` (optional: defaults to the value of `apache_options`), `serveradmin` (optional), `serveralias` (optional) and `extra_parameters` (optional: you can add whatever additional configuration lines you'd like in here). 61 | 62 | Here's an example using `extra_parameters` to add a RewriteRule to redirect all requests to the `www.` site: 63 | 64 | ```yaml 65 | - servername: "www.local.dev" 66 | serveralias: "local.dev" 67 | documentroot: "/var/www/html" 68 | extra_parameters: | 69 | RewriteCond %{HTTP_HOST} !^www\. [NC] 70 | RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 71 | ``` 72 | 73 | The `|` denotes a multiline scalar block in YAML, so newlines are preserved in the resulting configuration file output. 74 | 75 | ```yaml 76 | apache_vhosts_ssl: [] 77 | ``` 78 | 79 | No SSL vhosts are configured by default, but you can add them using the same pattern as `apache_vhosts`, with a few additional directives, like the following example: 80 | 81 | ```yaml 82 | apache_vhosts_ssl: 83 | - servername: "local.dev" 84 | documentroot: "/var/www/html" 85 | certificate_file: "/home/vagrant/example.crt" 86 | certificate_key_file: "/home/vagrant/example.key" 87 | certificate_chain_file: "/path/to/certificate_chain.crt" 88 | extra_parameters: | 89 | RewriteCond %{HTTP_HOST} !^www\. [NC] 90 | RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 91 | ``` 92 | 93 | Other SSL directives can be managed with other SSL-related role variables. 94 | 95 | ```yaml 96 | apache_ssl_no_log: true 97 | ``` 98 | 99 | Whether to print SSL-related task output to the console when running the playbook. 100 | 101 | ```yaml 102 | apache_ssl_protocol: "All -SSLv2 -SSLv3" 103 | apache_ssl_cipher_suite: "AES256+EECDH:AES256+EDH" 104 | ``` 105 | 106 | The SSL protocols and cipher suites that are used/allowed when clients make secure connections to your server. These are secure/sane defaults, but for maximum security, performand, and/or compatibility, you may need to adjust these settings. 107 | 108 | ```yaml 109 | apache_allow_override: "All" 110 | apache_options: "-Indexes +FollowSymLinks" 111 | ``` 112 | 113 | The default values for the `AllowOverride` and `Options` directives for the `documentroot` directory of each vhost. A vhost can overwrite these values by specifying `allow_override` or `options`. 114 | 115 | ```yaml 116 | apache_mods_enabled: 117 | - rewrite 118 | - ssl 119 | apache_mods_disabled: [] 120 | ``` 121 | 122 | Which Apache mods to enable or disable (these will be symlinked into the appropriate location). See the `mods-available` directory inside the apache configuration directory (`/etc/apache2/mods-available` on Debian/Ubuntu) for all the available mods. 123 | 124 | ```yaml 125 | apache_packages: 126 | - [platform-specific] 127 | ``` 128 | 129 | The list of packages to be installed. This defaults to a set of platform-specific packages for RedHat or Debian-based systems (see `vars/RedHat.yml` and `vars/Debian.yml` for the default values). 130 | 131 | ```yaml 132 | apache_state: started 133 | ``` 134 | 135 | Set initial Apache daemon state to be enforced when this role is run. This should generally remain `started`, but you can set it to `stopped` if you need to fix the Apache config during a playbook run or otherwise would not like Apache started at the time this role is run. 136 | 137 | ```yaml 138 | apache_enabled: yes 139 | ``` 140 | 141 | Set the Apache service boot time status. This should generally remain `yes`, but you can set it to `no` if you need to run Ansible while leaving the service disabled. 142 | 143 | ```yaml 144 | apache_packages_state: present 145 | ``` 146 | 147 | If you have enabled any additional repositories such as _ondrej/apache2_, [geerlingguy.repo-epel](https://github.com/geerlingguy/ansible-role-repo-epel), or [geerlingguy.repo-remi](https://github.com/geerlingguy/ansible-role-repo-remi), you may want an easy way to upgrade versions. You can set this to `latest` (combined with `apache_enablerepo` on RHEL) and can directly upgrade to a different Apache version from a different repo (instead of uninstalling and reinstalling Apache). 148 | 149 | ```yaml 150 | apache_ignore_missing_ssl_certificate: true 151 | ``` 152 | 153 | If you would like to only create SSL vhosts when the vhost certificate is present (e.g. when using Let’s Encrypt), set `apache_ignore_missing_ssl_certificate` to `false`. When doing this, you might need to run your playbook more than once so all the vhosts are configured (if another part of the playbook generates the SSL certificates). 154 | 155 | ## .htaccess-based Basic Authorization 156 | 157 | If you require Basic Auth support, you can add it either through a custom template, or by adding `extra_parameters` to a VirtualHost configuration, like so: 158 | 159 | ```yaml 160 | extra_parameters: | 161 | 162 | Require valid-user 163 | AuthType Basic 164 | AuthName "Please authenticate" 165 | AuthUserFile /var/www/password-protected-directory/.htpasswd 166 | 167 | ``` 168 | 169 | To password protect everything within a VirtualHost directive, use the `Location` block instead of `Directory`: 170 | 171 | ``` 172 | 173 | Require valid-user 174 | .... 175 | 176 | ``` 177 | 178 | You would need to generate/upload your own `.htpasswd` file in your own playbook. There may be other roles that support this functionality in a more integrated way. 179 | 180 | ## Dependencies 181 | 182 | None. 183 | 184 | ## Example Playbook 185 | 186 | ```yaml 187 | - hosts: webservers 188 | vars_files: 189 | - vars/main.yml 190 | roles: 191 | - { role: geerlingguy.apache } 192 | ``` 193 | 194 | *Inside `vars/main.yml`*: 195 | 196 | ```yaml 197 | apache_listen_port: 8080 198 | apache_vhosts: 199 | - {servername: "example.com", documentroot: "/var/www/vhosts/example_com"} 200 | ``` 201 | 202 | ## License 203 | 204 | MIT / BSD 205 | 206 | ## Author Information 207 | 208 | This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). 209 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apache_enablerepo: "" 3 | 4 | apache_listen_ip: "*" 5 | apache_listen_port: 80 6 | apache_listen_port_ssl: 443 7 | 8 | apache_create_vhosts: true 9 | apache_vhosts_filename: "vhosts.conf" 10 | apache_vhosts_template: "vhosts.conf.j2" 11 | 12 | # On Debian/Ubuntu, a default virtualhost is included in Apache's configuration. 13 | # Set this to `true` to remove that default. 14 | apache_remove_default_vhost: false 15 | 16 | apache_global_vhost_settings: | 17 | DirectoryIndex index.php index.html 18 | 19 | apache_vhosts: 20 | # Additional properties: 21 | # 'serveradmin, serveralias, allow_override, options, extra_parameters'. 22 | - servername: "local.dev" 23 | documentroot: "/var/www/html" 24 | 25 | apache_allow_override: "All" 26 | apache_options: "-Indexes +FollowSymLinks" 27 | 28 | apache_vhosts_ssl: [] 29 | # Additional properties: 30 | # 'serveradmin, serveralias, allow_override, options, extra_parameters'. 31 | # - servername: "local.dev", 32 | # documentroot: "/var/www/html", 33 | # certificate_file: "/path/to/certificate.crt", 34 | # certificate_key_file: "/path/to/certificate.key", 35 | # # Optional. 36 | # certificate_chain_file: "/path/to/certificate_chain.crt" 37 | 38 | apache_ignore_missing_ssl_certificate: true 39 | 40 | apache_ssl_no_log: true 41 | apache_ssl_protocol: "All -SSLv2 -SSLv3" 42 | apache_ssl_cipher_suite: "AES256+EECDH:AES256+EDH" 43 | 44 | # Only used on Debian/Ubuntu/Redhat. 45 | apache_mods_enabled: 46 | - rewrite 47 | - ssl 48 | apache_mods_disabled: [] 49 | 50 | # Set initial apache state. Recommended values: `started` or `stopped` 51 | apache_state: started 52 | 53 | # Set initial apache service status. Recommended values: `true` or `false` 54 | apache_enabled: true 55 | 56 | # Set apache state when configuration changes are made. Recommended values: 57 | # `restarted` or `reloaded` 58 | apache_restart_state: restarted 59 | 60 | # Apache package state; use `present` to make sure it's installed, or `latest` 61 | # if you want to upgrade or switch versions using a new repo. 62 | apache_packages_state: present 63 | -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart apache 3 | service: 4 | name: "{{ apache_service }}" 5 | state: "{{ apache_restart_state }}" 6 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: [] 3 | 4 | galaxy_info: 5 | role_name: apache 6 | author: geerlingguy 7 | description: Apache 2.x for Linux. 8 | company: "Midwestern Mac, LLC" 9 | license: "license (BSD, MIT)" 10 | min_ansible_version: 2.10 11 | platforms: 12 | - name: Fedora 13 | versions: 14 | - all 15 | - name: Amazon 16 | versions: 17 | - all 18 | - name: Debian 19 | versions: 20 | - all 21 | - name: Ubuntu 22 | versions: 23 | - trusty 24 | - xenial 25 | - bionic 26 | - name: Solaris 27 | versions: 28 | - 11.3 29 | galaxy_tags: 30 | - web 31 | - apache 32 | - webserver 33 | - html 34 | - httpd 35 | 36 | allow_duplicates: true 37 | -------------------------------------------------------------------------------- /molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | #become: true 5 | 6 | vars: 7 | apache_listen_port_ssl: 443 8 | apache_create_vhosts: true 9 | apache_vhosts_filename: "vhosts.conf" 10 | apache_vhosts: 11 | - servername: "example.com" 12 | documentroot: "/var/www/vhosts/example_com" 13 | 14 | pre_tasks: 15 | - name: Update apt cache. 16 | apt: update_cache=yes cache_valid_time=600 17 | when: ansible_os_family == 'Debian' 18 | changed_when: false 19 | 20 | roles: 21 | - role: geerlingguy.apache 22 | -------------------------------------------------------------------------------- /molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | role_name_check: 1 3 | dependency: 4 | name: galaxy 5 | options: 6 | ignore-errors: true 7 | driver: 8 | name: docker 9 | platforms: 10 | - name: instance 11 | image: "geerlingguy/docker-${MOLECULE_DISTRO:-rockylinux9}-ansible:latest" 12 | command: ${MOLECULE_DOCKER_COMMAND:-""} 13 | volumes: 14 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 15 | cgroupns_mode: host 16 | privileged: true 17 | pre_build_image: true 18 | provisioner: 19 | name: ansible 20 | playbooks: 21 | converge: ${MOLECULE_PLAYBOOK:-converge.yml} 22 | -------------------------------------------------------------------------------- /tasks/configure-Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure Apache. 3 | lineinfile: 4 | dest: "{{ apache_server_root }}/ports.conf" 5 | regexp: "{{ item.regexp }}" 6 | line: "{{ item.line }}" 7 | state: present 8 | mode: 0644 9 | with_items: "{{ apache_ports_configuration_items }}" 10 | notify: restart apache 11 | 12 | - name: Enable Apache mods. 13 | file: 14 | src: "{{ apache_server_root }}/mods-available/{{ item }}.load" 15 | dest: "{{ apache_server_root }}/mods-enabled/{{ item }}.load" 16 | state: link 17 | mode: 0644 18 | with_items: "{{ apache_mods_enabled }}" 19 | notify: restart apache 20 | 21 | - name: Disable Apache mods. 22 | file: 23 | path: "{{ apache_server_root }}/mods-enabled/{{ item }}.load" 24 | state: absent 25 | with_items: "{{ apache_mods_disabled }}" 26 | notify: restart apache 27 | 28 | - name: Check whether certificates defined in vhosts exist. 29 | stat: "path={{ item.certificate_file }}" 30 | register: apache_ssl_certificates 31 | with_items: "{{ apache_vhosts_ssl }}" 32 | no_log: "{{ apache_ssl_no_log }}" 33 | 34 | - name: Add apache vhosts configuration. 35 | template: 36 | src: "{{ apache_vhosts_template }}" 37 | dest: "{{ apache_conf_path }}/sites-available/{{ apache_vhosts_filename }}" 38 | owner: root 39 | group: root 40 | mode: 0644 41 | notify: restart apache 42 | when: apache_create_vhosts | bool 43 | 44 | - name: Add vhost symlink in sites-enabled. 45 | file: 46 | src: "{{ apache_conf_path }}/sites-available/{{ apache_vhosts_filename }}" 47 | dest: "{{ apache_conf_path }}/sites-enabled/{{ apache_vhosts_filename }}" 48 | state: link 49 | mode: 0644 50 | force: "{{ ansible_check_mode }}" 51 | notify: restart apache 52 | when: apache_create_vhosts | bool 53 | 54 | - name: Remove default vhost in sites-enabled. 55 | file: 56 | path: "{{ apache_conf_path }}/sites-enabled/{{ apache_default_vhost_filename }}" 57 | state: absent 58 | notify: restart apache 59 | when: apache_remove_default_vhost 60 | -------------------------------------------------------------------------------- /tasks/configure-RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure Apache. 3 | lineinfile: 4 | dest: "{{ apache_server_root }}/conf/{{ apache_daemon }}.conf" 5 | regexp: "{{ item.regexp }}" 6 | line: "{{ item.line }}" 7 | state: present 8 | mode: 0644 9 | with_items: "{{ apache_ports_configuration_items }}" 10 | notify: restart apache 11 | 12 | - name: Check whether certificates defined in vhosts exist. 13 | stat: path={{ item.certificate_file }} 14 | register: apache_ssl_certificates 15 | with_items: "{{ apache_vhosts_ssl }}" 16 | no_log: "{{ apache_ssl_no_log }}" 17 | 18 | - name: Enable Apache mods. 19 | copy: 20 | dest: "{{ apache_server_root }}/conf.modules.d/99-ansible-{{ item }}.conf" 21 | content: | 22 | LoadModule {{ item }}_module modules/mod_{{ item }}.so 23 | mode: 0644 24 | with_items: "{{ apache_mods_enabled }}" 25 | notify: restart apache 26 | 27 | - name: Disable Apache mods 28 | file: 29 | path: "{{ apache_server_root }}/conf.modules.d/99-ansible-{{ item }}.conf" 30 | state: absent 31 | with_items: "{{ apache_mods_disabled }}" 32 | notify: restart apache 33 | 34 | - name: Add apache vhosts configuration. 35 | template: 36 | src: "{{ apache_vhosts_template }}" 37 | dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}" 38 | owner: root 39 | group: root 40 | mode: 0644 41 | notify: restart apache 42 | when: apache_create_vhosts | bool 43 | 44 | - name: Check if localhost cert exists (RHEL 8 and later). 45 | stat: 46 | path: /etc/pki/tls/certs/localhost.crt 47 | register: localhost_cert 48 | when: ansible_distribution_major_version | int >= 8 49 | 50 | - name: Ensure httpd certs are installed (RHEL 8 and later). 51 | command: /usr/libexec/httpd-ssl-gencerts 52 | when: 53 | - ansible_distribution_major_version | int >= 8 54 | - not localhost_cert.stat.exists 55 | -------------------------------------------------------------------------------- /tasks/configure-Solaris.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure Apache. 3 | lineinfile: 4 | dest: "{{ apache_server_root }}/{{ apache_daemon }}.conf" 5 | regexp: "{{ item.regexp }}" 6 | line: "{{ item.line }}" 7 | state: present 8 | mode: 0644 9 | with_items: "{{ apache_ports_configuration_items }}" 10 | notify: restart apache 11 | 12 | - name: Add apache vhosts configuration. 13 | template: 14 | src: "{{ apache_vhosts_template }}" 15 | dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}" 16 | owner: root 17 | group: root 18 | mode: 0644 19 | notify: restart apache 20 | when: apache_create_vhosts | bool 21 | -------------------------------------------------------------------------------- /tasks/configure-Suse.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure Apache. 3 | lineinfile: 4 | dest: "{{ apache_server_root }}/listen.conf" 5 | regexp: "{{ item.regexp }}" 6 | line: "{{ item.line }}" 7 | state: present 8 | mode: 0644 9 | with_items: "{{ apache_ports_configuration_items }}" 10 | notify: restart apache 11 | 12 | - name: Check whether certificates defined in vhosts exist. 13 | stat: path={{ item.certificate_file }} 14 | register: apache_ssl_certificates 15 | with_items: "{{ apache_vhosts_ssl }}" 16 | no_log: "{{ apache_ssl_no_log }}" 17 | 18 | - name: Add apache vhosts configuration. 19 | template: 20 | src: "{{ apache_vhosts_template }}" 21 | dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}" 22 | owner: root 23 | group: root 24 | mode: 0644 25 | notify: restart apache 26 | when: apache_create_vhosts | bool 27 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Include variables and define needed variables. 3 | - name: Include OS-specific variables. 4 | include_vars: "{{ ansible_os_family }}.yml" 5 | 6 | - name: Include variables for Amazon Linux. 7 | include_vars: "AmazonLinux.yml" 8 | when: 9 | - ansible_distribution == "Amazon" 10 | - ansible_distribution_major_version == "NA" 11 | 12 | - name: Define apache_packages. 13 | set_fact: 14 | apache_packages: "{{ __apache_packages | list }}" 15 | when: apache_packages is not defined 16 | 17 | # Setup/install tasks. 18 | - include_tasks: "setup-{{ ansible_os_family }}.yml" 19 | 20 | # Figure out what version of Apache is installed. 21 | - name: Get installed version of Apache. 22 | command: "{{ apache_daemon_path }}{{ apache_daemon }} -v" 23 | changed_when: false 24 | check_mode: false 25 | register: _apache_version 26 | 27 | - name: Create apache_version variable. 28 | set_fact: 29 | apache_version: "{{ _apache_version.stdout.split()[2].split('/')[1] }}" 30 | 31 | - name: Include Apache 2.2 variables. 32 | include_vars: apache-22.yml 33 | when: "apache_version.split('.')[1] == '2'" 34 | 35 | - name: Include Apache 2.4 variables. 36 | include_vars: apache-24.yml 37 | when: "apache_version.split('.')[1] == '4'" 38 | 39 | # Configure Apache. 40 | - name: Configure Apache. 41 | include_tasks: "configure-{{ ansible_os_family }}.yml" 42 | 43 | - name: Ensure Apache has selected state and enabled on boot. 44 | service: 45 | name: "{{ apache_service }}" 46 | state: "{{ apache_state }}" 47 | enabled: "{{ apache_enabled }}" 48 | -------------------------------------------------------------------------------- /tasks/setup-Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Update apt cache. 3 | apt: update_cache=yes cache_valid_time=3600 4 | 5 | - name: Ensure Apache is installed on Debian. 6 | apt: "name={{ apache_packages }} state={{ apache_packages_state }}" 7 | -------------------------------------------------------------------------------- /tasks/setup-RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure Apache is installed on RHEL. 3 | package: 4 | name: "{{ apache_packages }}" 5 | state: "{{ apache_packages_state }}" 6 | enablerepo: "{{ apache_enablerepo | default(omit, true) }}" 7 | -------------------------------------------------------------------------------- /tasks/setup-Solaris.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure Apache is installed on Solaris. 3 | pkg5: 4 | name: "{{ apache_packages }}" 5 | state: "{{ apache_packages_state }}" 6 | -------------------------------------------------------------------------------- /tasks/setup-Suse.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure Apache is installed on Suse. 3 | zypper: 4 | name: "{{ apache_packages }}" 5 | state: "{{ apache_packages_state }}" 6 | -------------------------------------------------------------------------------- /templates/vhosts.conf.j2: -------------------------------------------------------------------------------- 1 | {{ apache_global_vhost_settings }} 2 | 3 | {# Set up VirtualHosts #} 4 | {% for vhost in apache_vhosts %} 5 | 6 | ServerName {{ vhost.servername }} 7 | {% if vhost.serveralias is defined %} 8 | ServerAlias {{ vhost.serveralias }} 9 | {% endif %} 10 | {% if vhost.documentroot is defined %} 11 | DocumentRoot "{{ vhost.documentroot }}" 12 | {% endif %} 13 | 14 | {% if vhost.serveradmin is defined %} 15 | ServerAdmin {{ vhost.serveradmin }} 16 | {% endif %} 17 | {% if vhost.documentroot is defined %} 18 | 19 | AllowOverride {{ vhost.allow_override | default(apache_allow_override) }} 20 | Options {{ vhost.options | default(apache_options) }} 21 | {% if apache_vhosts_version == "2.2" %} 22 | Order allow,deny 23 | Allow from all 24 | {% else %} 25 | Require all granted 26 | {% endif %} 27 | 28 | {% endif %} 29 | {% if vhost.extra_parameters is defined %} 30 | {{ vhost.extra_parameters | indent(width=2, first=True) }} 31 | {% endif %} 32 | 33 | 34 | {% endfor %} 35 | 36 | {# Set up SSL VirtualHosts #} 37 | {% for vhost in apache_vhosts_ssl %} 38 | {% if apache_ignore_missing_ssl_certificate or apache_ssl_certificates.results[loop.index0].stat.exists %} 39 | 40 | ServerName {{ vhost.servername }} 41 | {% if vhost.serveralias is defined %} 42 | ServerAlias {{ vhost.serveralias }} 43 | {% endif %} 44 | {% if vhost.documentroot is defined %} 45 | DocumentRoot "{{ vhost.documentroot }}" 46 | {% endif %} 47 | 48 | SSLEngine on 49 | SSLCipherSuite {{ apache_ssl_cipher_suite }} 50 | SSLProtocol {{ apache_ssl_protocol }} 51 | SSLHonorCipherOrder On 52 | {% if apache_vhosts_version == "2.4" %} 53 | SSLCompression off 54 | {% endif %} 55 | SSLCertificateFile {{ vhost.certificate_file }} 56 | SSLCertificateKeyFile {{ vhost.certificate_key_file }} 57 | {% if vhost.certificate_chain_file is defined %} 58 | SSLCertificateChainFile {{ vhost.certificate_chain_file }} 59 | {% endif %} 60 | 61 | {% if vhost.serveradmin is defined %} 62 | ServerAdmin {{ vhost.serveradmin }} 63 | {% endif %} 64 | {% if vhost.documentroot is defined %} 65 | 66 | AllowOverride {{ vhost.allow_override | default(apache_allow_override) }} 67 | Options {{ vhost.options | default(apache_options) }} 68 | {% if apache_vhosts_version == "2.2" %} 69 | Order allow,deny 70 | Allow from all 71 | {% else %} 72 | Require all granted 73 | {% endif %} 74 | 75 | {% endif %} 76 | {% if vhost.extra_parameters is defined %} 77 | {{ vhost.extra_parameters | indent(width=2, first=True) }} 78 | {% endif %} 79 | 80 | 81 | {% endif %} 82 | {% endfor %} 83 | -------------------------------------------------------------------------------- /vars/AmazonLinux.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apache_service: httpd 3 | apache_daemon: httpd 4 | apache_daemon_path: /usr/sbin/ 5 | apache_server_root: /etc/httpd 6 | apache_conf_path: /etc/httpd/conf.d 7 | 8 | apache_vhosts_version: "2.4" 9 | 10 | __apache_packages: 11 | - httpd24 12 | - httpd24-devel 13 | - mod24_ssl 14 | - openssh 15 | 16 | apache_ports_configuration_items: 17 | - regexp: "^Listen " 18 | line: "Listen {{ apache_listen_port }}" 19 | -------------------------------------------------------------------------------- /vars/Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apache_service: apache2 3 | apache_daemon: apache2 4 | apache_daemon_path: /usr/sbin/ 5 | apache_server_root: /etc/apache2 6 | apache_conf_path: /etc/apache2 7 | 8 | __apache_packages: 9 | - apache2 10 | - apache2-utils 11 | 12 | apache_ports_configuration_items: 13 | - regexp: "^Listen " 14 | line: "Listen {{ apache_listen_port }}" 15 | -------------------------------------------------------------------------------- /vars/RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apache_service: httpd 3 | apache_daemon: httpd 4 | apache_daemon_path: /usr/sbin/ 5 | apache_server_root: /etc/httpd 6 | apache_conf_path: /etc/httpd/conf.d 7 | 8 | apache_vhosts_version: "2.2" 9 | 10 | __apache_packages: 11 | - httpd 12 | - httpd-devel 13 | - mod_ssl 14 | - openssh 15 | 16 | apache_ports_configuration_items: 17 | - regexp: "^Listen " 18 | line: "Listen {{ apache_listen_port }}" 19 | - regexp: "^#?NameVirtualHost " 20 | line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" 21 | -------------------------------------------------------------------------------- /vars/Solaris.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apache_service: apache24 3 | apache_daemon: httpd 4 | apache_daemon_path: /usr/apache2/2.4/bin/ 5 | apache_server_root: /etc/apache2/2.4/ 6 | apache_conf_path: /etc/apache2/2.4/conf.d 7 | 8 | apache_vhosts_version: "2.2" 9 | 10 | __apache_packages: 11 | - web/server/apache-24 12 | - web/server/apache-24/module/apache-ssl 13 | - web/server/apache-24/module/apache-security 14 | 15 | apache_ports_configuration_items: 16 | - regexp: "^Listen " 17 | line: "Listen {{ apache_listen_port }}" 18 | - regexp: "^#?NameVirtualHost " 19 | line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" 20 | -------------------------------------------------------------------------------- /vars/Suse.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apache_service: apache2 3 | apache_daemon: httpd2 4 | apache_daemon_path: /usr/sbin/ 5 | apache_server_root: /etc/apache2 6 | apache_conf_path: /etc/apache2/conf.d 7 | 8 | apache_vhosts_version: "2.2" 9 | 10 | __apache_packages: 11 | - apache2 12 | - openssh 13 | 14 | apache_ports_configuration_items: 15 | - regexp: "^Listen " 16 | line: "Listen {{ apache_listen_port }}" 17 | - regexp: "^#?NameVirtualHost " 18 | line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" 19 | -------------------------------------------------------------------------------- /vars/apache-22.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apache_vhosts_version: "2.2" 3 | apache_default_vhost_filename: 000-default 4 | apache_ports_configuration_items: 5 | - { 6 | regexp: "^Listen ", 7 | line: "Listen {{ apache_listen_port }}" 8 | } 9 | - { 10 | regexp: "^#?NameVirtualHost ", 11 | line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" 12 | } 13 | -------------------------------------------------------------------------------- /vars/apache-24.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apache_vhosts_version: "2.4" 3 | apache_default_vhost_filename: 000-default.conf 4 | apache_ports_configuration_items: 5 | - { 6 | regexp: "^Listen ", 7 | line: "Listen {{ (apache_listen_ip == '*') | ternary('', apache_listen_ip + ':') }}{{ apache_listen_port }}" 8 | } 9 | --------------------------------------------------------------------------------