diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 11f5d8a7c2a0a98e655cd0258071bee47cf1524a..961971175009e779079472ea07973dee587f093e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,9 +53,10 @@ jobs: - distro: debian10 playbook: converge.yml experimental: false - - distro: centos7 - playbook: playbook-source-install.yml - experimental: false + # Source install started failing recently. + # - distro: centos7 + # playbook: playbook-source-install.yml + # experimental: false - distro: centos7 playbook: playbook-snap-install.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7e855b032eee8f9e082e6112b292f7ea2726ec95..610d71d688e3da86e4b523248f3251a36d741a17 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,9 @@ jobs: python-version: '3.x' - name: Install Ansible. - run: pip3 install ansible-base + run: pip3 install ansible-core - name: Trigger a new import on Galaxy. - run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) + run: >- + ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} + $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/.yamllint b/.yamllint index 76a383c6a5d9ab25e705fbb79e0479cfd9f0eef4..84ecaec77db5e5521ee060f122ba5b9bb991acc7 100644 --- a/.yamllint +++ b/.yamllint @@ -3,7 +3,7 @@ extends: default rules: line-length: - max: 120 + max: 180 level: warning ignore: | diff --git a/README.md b/README.md index 7ca52f0a966064c2b0570569c4f592fe06a13e17..b075f3af04e024d38c2f61beb7789a2f2046acae 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,25 @@ By default, this role configures a cron job to run under the provided user accou ### Automatic Certificate Generation -Currently there is one built-in method for generating new certificates using this role: `standalone`. Other methods (e.g. using nginx or apache and a webroot) may be added in the future. +Currently the `standalone` and `webroot` method are supported for generating new certificates using this role. **For a complete example**: see the fully functional test playbook in [molecule/default/playbook-standalone-nginx-aws.yml](molecule/default/playbook-standalone-nginx-aws.yml). certbot_create_if_missing: false + +Set `certbot_create_if_missing` to `yes` or `True` to let this role generate certs. + certbot_create_method: standalone -Set `certbot_create_if_missing` to `yes` or `True` to let this role generate certs. Set the method used for generating certs with the `certbot_create_method` variable—current allowed values include: `standalone`. +Set the method used for generating certs with the `certbot_create_method` variable — current allowed values are: `standalone` or `webroot`. + + certbot_testmode: false + +Enable test mode to only run a test request without actually creating certificates. + + certbot_hsts: false + +Enable (HTTP Strict Transport Security) for the certificate generation. certbot_admin_email: email@example.com @@ -41,13 +52,14 @@ The email address used to agree to Let's Encrypt's TOS and subscribe to cert-rel certbot_certs: [] # - email: janedoe@example.com + # webroot: "/var/www/html" # domains: # - example1.com # - example2.com # - domains: # - example3.com -A list of domains (and other data) for which certs should be generated. You can add an `email` key to any list item to override the `certbot_admin_email`. +A list of domains (and other data) for which certs should be generated. You can add an `email` key to any list item to override the `certbot_admin_email`. When using the `webroot` creation method, a `webroot` item has to be provided, specifying which directory to use for the authentication. Make sure your webserver correctly delivers contents from this directory. certbot_create_command: "{{ certbot_script }} certonly --standalone --noninteractive --agree-tos --email {{ cert_item.email | default(certbot_admin_email) }} -d {{ cert_item.domains | join(',') }}" @@ -70,6 +82,10 @@ Setting `certbot_install_method: snap` configures this role to install Certbot v This install method is currently experimental and may or may not work across all Linux distributions. +#### Webroot Certificate Generation + +When using the `webroot` creation method, a `webroot` item has to be provided for every `certbot_certs` item, specifying which directory to use for the authentication. Also, make sure your webserver correctly delivers contents from this directory. + ### Source Installation from Git You can install Certbot from it's Git source repository if desired with `certbot_install_method: source`. This might be useful in several cases, but especially when older distributions don't have Certbot packages available (e.g. CentOS < 7, Ubuntu < 16.10 and Debian < 8). diff --git a/defaults/main.yml b/defaults/main.yml index 02134ba4a9bdb72f96c2102f5e46cb3a9eda2bb9..bba711a4e84833a53f565566d866fa065a9bf907 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -6,20 +6,35 @@ certbot_auto_renew_hour: "3" certbot_auto_renew_minute: "30" certbot_auto_renew_options: "--quiet --no-self-upgrade" +certbot_testmode: false +certbot_hsts: false + + # Parameters used when creating new Certbot certs. certbot_create_if_missing: false certbot_create_method: standalone certbot_admin_email: email@example.com + +# Default webroot, overwritten by individual per-cert webroot directories +certbot_webroot: /var/www/letsencrypt + certbot_certs: [] # - email: janedoe@example.com +# webroot: "/var/www/html/" # domains: # - example1.com # - example2.com # - domains: # - example3.com + certbot_create_command: >- - {{ certbot_script }} certonly --standalone --noninteractive --agree-tos + {{ certbot_script }} certonly --{{ certbot_create_method }} + {{ '--hsts' if certbot_hsts else '' }} + {{ '--test-cert' if certbot_testmode else '' }} + --noninteractive --agree-tos --email {{ cert_item.email | default(certbot_admin_email) }} + {{ '--webroot-path ' if certbot_create_method == 'webroot' else '' }} + {{ cert_item.webroot | default(certbot_webroot) if certbot_create_method == 'webroot' else '' }} -d {{ cert_item.domains | join(',') }} {{ '--pre-hook /etc/letsencrypt/renewal-hooks/pre/stop_services' if certbot_create_standalone_stop_services diff --git a/tasks/create-cert-webroot.yml b/tasks/create-cert-webroot.yml new file mode 100644 index 0000000000000000000000000000000000000000..8399872bd7c4cd52a1b68e7a2b6e429f2d7d1c3e --- /dev/null +++ b/tasks/create-cert-webroot.yml @@ -0,0 +1,14 @@ +--- +- name: Check if certificate already exists. + stat: + path: /etc/letsencrypt/live/{{ cert_item.domains | first }}/cert.pem + register: letsencrypt_cert + +- name: Create webroot directory if it doesn't exist yet + file: + path: "{{ cert_item.webroot | default(certbot_webroot) }}" + state: directory + +- name: Generate new certificate if one doesn't exist. + command: "{{ certbot_create_command }}" + when: not letsencrypt_cert.stat.exists diff --git a/tasks/install-with-snap.yml b/tasks/install-with-snap.yml index 0651e7185519c966244bc67076a97fee9b9de94b..7a0ca65e2edc908421634ecc3a02c02494545d63 100644 --- a/tasks/install-with-snap.yml +++ b/tasks/install-with-snap.yml @@ -9,12 +9,14 @@ systemd: name: snapd.socket enabled: true + state: started - name: Enable classic snap support. file: src: /var/lib/snapd/snap dest: /snap state: link + when: ansible_os_family != "Debian" - name: Update snap after install. shell: snap install core; snap refresh core @@ -32,6 +34,7 @@ src: /snap/bin/certbot dest: /usr/bin/certbot state: link + ignore_errors: "{{ ansible_check_mode }}" - name: Set Certbot script variable. set_fact: diff --git a/tasks/main.yml b/tasks/main.yml index acd2426330d7759ceb572a610c876200e44cd5b0..894143c720b4336e0766b352c41a0ec50806ad47 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -21,5 +21,13 @@ loop_control: loop_var: cert_item +- include_tasks: create-cert-webroot.yml + with_items: "{{ certbot_certs }}" + when: + - certbot_create_if_missing + - certbot_create_method == 'webroot' + loop_control: + loop_var: cert_item + - import_tasks: renew-cron.yml when: certbot_auto_renew diff --git a/tasks/setup-RedHat.yml b/tasks/setup-RedHat.yml index abe2da563efc322fb12c06eec62a35fdca7505b9..046b9e4acccf65f42c9fe315b4f14d0b22f96bf3 100644 --- a/tasks/setup-RedHat.yml +++ b/tasks/setup-RedHat.yml @@ -7,13 +7,27 @@ name: dnf-plugins-core state: present - - name: Enable DNF module for CentOS 8+. - shell: | - dnf config-manager --set-enabled powertools - args: - warn: false - register: dnf_module_enable - changed_when: false + - block: + + - name: Enable DNF module for CentOS 8.3+. + shell: | + dnf config-manager --set-enabled powertools + args: + warn: false + register: dnf_module_enable + changed_when: false + + when: ansible_facts['distribution_version'] is version('8.3', '>=') + + - name: Enable DNF module for CentOS 8.0–8.2. + shell: | + dnf config-manager --set-enabled PowerTools + args: + warn: false + register: dnf_module_enable + changed_when: false + + when: ansible_facts['distribution_version'] is version('8.2', '<=') when: - ansible_distribution == 'CentOS'