From 76624cf39886de4ef9763467d7ddf475dcf8f7d5 Mon Sep 17 00:00:00 2001 From: Andrew Williams Date: Fri, 23 Jun 2023 07:18:31 +0100 Subject: [PATCH] Initial commit --- defaults/main.yaml | 8 ++++++++ meta/main.yaml | 15 +++++++++++++++ tasks/cert.yaml | 20 ++++++++++++++++++++ tasks/config.yaml | 21 +++++++++++++++++++++ tasks/install.yaml | 35 +++++++++++++++++++++++++++++++++++ tasks/install_el.yaml | 37 +++++++++++++++++++++++++++++++++++++ tasks/main.yaml | 11 +++++++++++ tasks/request_certs.yaml | 9 +++++++++ templates/do_secrets.j2 | 2 ++ templates/gd_secrets.j2 | 3 +++ 10 files changed, 161 insertions(+) create mode 100644 defaults/main.yaml create mode 100644 meta/main.yaml create mode 100644 tasks/cert.yaml create mode 100644 tasks/config.yaml create mode 100644 tasks/install.yaml create mode 100644 tasks/install_el.yaml create mode 100644 tasks/main.yaml create mode 100644 tasks/request_certs.yaml create mode 100644 templates/do_secrets.j2 create mode 100644 templates/gd_secrets.j2 diff --git a/defaults/main.yaml b/defaults/main.yaml new file mode 100644 index 0000000..94b30ab --- /dev/null +++ b/defaults/main.yaml @@ -0,0 +1,8 @@ +--- +certbot_certs: [] +certbot_certs_email: root@{{ ansible_inventory }} + +certbot_plugin_arguments: + digitalocean: --dns-digitalocean --dns-digitalocean-credentials /root/do_secrets.ini + godaddy: --authenticator dns-godaddy --dns-godaddy-credentials /root/gd_secrets.ini + default: "--webroot -w /var/www/acme-challenge" diff --git a/meta/main.yaml b/meta/main.yaml new file mode 100644 index 0000000..1b0844f --- /dev/null +++ b/meta/main.yaml @@ -0,0 +1,15 @@ +--- +allow_duplicates: false + +galaxy_info: + role_name: certbot + author: Andrew Williams + description: Basic installation for Certbot + license: MIT + + min_ansible_version: "2.4" + + platforms: + - name: Ubuntu + versions: + - jammy diff --git a/tasks/cert.yaml b/tasks/cert.yaml new file mode 100644 index 0000000..187eeca --- /dev/null +++ b/tasks/cert.yaml @@ -0,0 +1,20 @@ +--- +- name: "Check the cert exists" + ansible.builtin.stat: + path: "/etc/letsencrypt/live/{{ item.hostname }}/cert.pem" + register: cert_stat + +- name: "Get the SANs from the certificate file" + community.crypto.x509_certificate_info: + path: "/etc/letsencrypt/live/{{ item.hostname }}/cert.pem" + register: cert_info + when: cert_stat.stat.exists + +- name: Calculate the SAN list + ansible.builtin.set_fact: + cert_sans: "{{ ['DNS:'] | product(item.sans | default([item.hostname])) | map('join') | list }}" + +- name: "Request a certificate" # noqa no-changed-when ignore-errors + ansible.builtin.command: "certbot certonly -n --expand --agree-tos {{ certbot_plugin_arguments[item.plugin | default('default')] }} -d '{{ item.hostname }}' {% for san in item.sans | default([]) %} -d '{{ san }}' {% endfor %} -m {{ certbot_certs_email }}" # noqa no-change-when + ignore_errors: true + when: not cert_stat.stat.exists or cert_sans | difference(cert_info.subject_alt_name) | list | length > 0 diff --git a/tasks/config.yaml b/tasks/config.yaml new file mode 100644 index 0000000..3e71865 --- /dev/null +++ b/tasks/config.yaml @@ -0,0 +1,21 @@ +--- +- name: Write out DigitalOcean auth key + ansible.builtin.template: + src: do_secrets.j2 + dest: /root/do_secrets.ini + mode: "0600" + owner: root + group: root + when: + - certbot_digitalocean_token is defined + +- name: Write out GoDaddy auth key + ansible.builtin.template: + src: do_secrets.j2 + dest: /root/gd_secrets.ini + mode: "0600" + owner: root + group: root + when: + - certbot_godaddy_secret is defined + - certbot_godaddy_key is defined diff --git a/tasks/install.yaml b/tasks/install.yaml new file mode 100644 index 0000000..6f4847a --- /dev/null +++ b/tasks/install.yaml @@ -0,0 +1,35 @@ +--- +- name: Install certbot + ansible.builtin.package: + name: "{{ packages }}" + state: present + vars: + packages: + - certbot + +- name: Install DigitalOcean certbot extension + ansible.builtin.package: + name: "{{ packages }}" + state: present + vars: + packages: + - python3-certbot-dns-digitalocean + when: + - certbot_digitalocean_token is defined + +- name: Install GoDaddy certbot extension from PyPi + ansible.builtin.pip: + name: "{{ packages }}" + state: present + vars: + packages: + - certbot-dns-godaddy + when: + - certbot_godaddy_key is defined + - certbot_godaddy_secret is defined + +- name: Enable certbot renewal timer + ansible.builtin.systemd: + name: certbot.timer + state: started + enabled: true diff --git a/tasks/install_el.yaml b/tasks/install_el.yaml new file mode 100644 index 0000000..8c59ae9 --- /dev/null +++ b/tasks/install_el.yaml @@ -0,0 +1,37 @@ +--- +- name: When on EL 8 + when: + - ansible_os_family == 'RedHat' + - ansible_distribution_major_version != '9' + block: + - name: Install certbot + ansible.builtin.package: + name: "{{ certbot_el_packages }}" + state: present + vars: + certbot_el_packages: + - certbot + - python3-certbot-dns-digitalocean + +- name: When on EL 9 + when: + - ansible_os_family == 'RedHat' + - ansible_distribution_major_version == '9' + block: + - name: Install certbot + ansible.builtin.package: + name: "{{ certbot_el9_packages }}" + state: present + vars: + certbot_el9_packages: + - certbot + - name: Install certbot-dns-digitalocean from pip + ansible.builtin.pip: + name: certbot-dns-digitalocean + state: present + +- name: Enable certbot renewal timer + ansible.builtin.systemd: + name: certbot-renew.timer + state: started + enabled: true diff --git a/tasks/main.yaml b/tasks/main.yaml new file mode 100644 index 0000000..01f3574 --- /dev/null +++ b/tasks/main.yaml @@ -0,0 +1,11 @@ +--- +- name: Install Certbot + ansible.builtin.import_tasks: install.yaml + +- name: Configure Certbot + ansible.builtin.import_tasks: config.yaml + +- name: Request Certificates + ansible.builtin.import_tasks: request_certs.yaml + tags: + - request_certs diff --git a/tasks/request_certs.yaml b/tasks/request_certs.yaml new file mode 100644 index 0000000..163c535 --- /dev/null +++ b/tasks/request_certs.yaml @@ -0,0 +1,9 @@ +--- +- name: Add FQDN if not already listed in certs + ansible.builtin.set_fact: + certbot_certs: "{{ certbot_certs + [{'hostname': ansible_fqdn}] }}" + when: certbot_certs | selectattr('hostname', 'equalto', ansible_fqdn) | list | length == 0 + +- name: Request Certificate + ansible.builtin.include_tasks: cert.yaml + loop: "{{ certbot_certs }}" diff --git a/templates/do_secrets.j2 b/templates/do_secrets.j2 new file mode 100644 index 0000000..24c691d --- /dev/null +++ b/templates/do_secrets.j2 @@ -0,0 +1,2 @@ +# DigitalOcean API credentials used by Certbot +dns_digitalocean_token = {{ digitalocean_token }} diff --git a/templates/gd_secrets.j2 b/templates/gd_secrets.j2 new file mode 100644 index 0000000..6ce27e7 --- /dev/null +++ b/templates/gd_secrets.j2 @@ -0,0 +1,3 @@ +# GoDaddy API credentials used by Certbot +dns_godaddy_secret = {{ certbot_godaddy_secret }} +dns_godaddy_key = {{ certbot_godaddy_key }}