From 4814ea8bda739118266b7f556833ccccf2128521 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 25 Apr 2023 18:03:59 +0200 Subject: [PATCH] Use one ACME account key per host This is nicer for us, since this avoids sharing a secret. Also put certificate directories in `certs` sub-directory for better organization. --- playbooks/roles/cert/meta/argument_specs.yml | 15 +---- playbooks/roles/cert/tasks/deploy_cert.yml | 61 +++++++++++++------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/playbooks/roles/cert/meta/argument_specs.yml b/playbooks/roles/cert/meta/argument_specs.yml index c79ff1a..664f8c6 100644 --- a/playbooks/roles/cert/meta/argument_specs.yml +++ b/playbooks/roles/cert/meta/argument_specs.yml @@ -18,19 +18,10 @@ argument_specs: required: false type: str default: root - cert__acme_account: - description: ACME account details + cert__acme_account_email: + description: E-Mail address for ACME account required: true - type: dict - options: - email: - description: E-mail address to send certificate expiary notifications to - required: true - type: str - key: - description: Private RSA or Elliptic Curve key of the ACME account - required: true - type: str + type: str cert__cloudflare_dns: description: Cloudflare DNS API details required: true diff --git a/playbooks/roles/cert/tasks/deploy_cert.yml b/playbooks/roles/cert/tasks/deploy_cert.yml index f60a049..821272d 100644 --- a/playbooks/roles/cert/tasks/deploy_cert.yml +++ b/playbooks/roles/cert/tasks/deploy_cert.yml @@ -1,4 +1,4 @@ -- name: Ensure certs directory exists +- name: Ensure `ansible_certs` directory exists ansible.builtin.file: path: /etc/ansible_certs state: directory @@ -7,18 +7,27 @@ mode: "755" become: true +- name: Ensure `certs` sub-directory exists + ansible.builtin.file: + path: /etc/ansible_certs/certs + state: directory + owner: root + group: root + mode: "755" + become: true + - name: Ensure sub-directory for the certificate exists ansible.builtin.file: - path: "/etc/ansible_certs/{{ item }}" + path: "/etc/ansible_certs/certs/{{ item }}" state: directory owner: "{{ cert__owner }}" group: "{{ cert__group }}" mode: "755" become: true -- name: Ensure private key is generated +- name: Ensure private key for certificate exists community.crypto.openssl_privatekey: - path: "/etc/ansible_certs/{{ item }}/key.pem" + path: "/etc/ansible_certs/certs/{{ item }}/key.pem" size: 4096 type: RSA owner: "{{ cert__owner }}" @@ -28,8 +37,8 @@ - name: Ensure certificate signing request is created community.crypto.openssl_csr: - path: "/etc/ansible_certs/{{ item }}/csr.pem" - privatekey_path: "/etc/ansible_certs/{{ item }}/key.pem" + path: "/etc/ansible_certs/certs/{{ item }}/csr.pem" + privatekey_path: "/etc/ansible_certs/certs/{{ item }}/key.pem" common_name: "{{ item }}" owner: "{{ cert__owner }}" group: "{{ cert__group }}" @@ -37,18 +46,28 @@ become: true register: cert__csr_result +- name: Ensure private key for ACME account exists + community.crypto.openssl_privatekey: + path: "/etc/ansible_certs/account_key.pem" + size: 4096 + type: RSA + owner: root + group: root + mode: "0600" + become: true + - name: Check certificate status and create ACME challenge if needed community.crypto.acme_certificate: - account_email: "{{ cert__acme_account.email }}" - account_key_content: "{{ cert__acme_account.key }}" + account_email: "{{ cert__acme_account_email }}" + account_key_src: "/etc/ansible_certs/account_key.pem" acme_directory: https://acme-v02.api.letsencrypt.org/directory acme_version: 2 remaining_days: 28 terms_agreed: true challenge: dns-01 - csr: "/etc/ansible_certs/{{ item }}/csr.pem" - dest: "/etc/ansible_certs/{{ item }}/cert.pem" - fullchain_dest: "/etc/ansible_certs/{{ item }}/fullchain.pem" + csr: "/etc/ansible_certs/certs/{{ item }}/csr.pem" + dest: "/etc/ansible_certs/certs/{{ item }}/cert.pem" + fullchain_dest: "/etc/ansible_certs/certs/{{ item }}/fullchain.pem" become: true register: cert__acme_challenge @@ -68,16 +87,16 @@ state: present - name: Retrieve certificate community.crypto.acme_certificate: - account_email: "{{ cert__acme_account.email }}" - account_key_content: "{{ cert__acme_account.key }}" + account_email: "{{ cert__acme_account_email }}" + account_key_src: "/etc/ansible_certs/account_key.pem" acme_directory: https://acme-v02.api.letsencrypt.org/directory acme_version: 2 terms_agreed: true remaining_days: 28 challenge: dns-01 - csr: "/etc/ansible_certs/{{ item }}/csr.pem" - dest: "/etc/ansible_certs/{{ item }}/cert.pem" - fullchain_dest: "/etc/ansible_certs/{{ item }}/fullchain.pem" + csr: "/etc/ansible_certs/certs/{{ item }}/csr.pem" + dest: "/etc/ansible_certs/certs/{{ item }}/cert.pem" + fullchain_dest: "/etc/ansible_certs/certs/{{ item }}/fullchain.pem" data: "{{ cert__acme_challenge }}" become: true notify: "{{ cert__handlers }}" @@ -95,7 +114,7 @@ - name: Ensure correct permissions for certificate are set ansible.builtin.file: - path: "/etc/ansible_certs/{{ item }}/cert.pem" + path: "/etc/ansible_certs/certs/{{ item }}/cert.pem" owner: "{{ cert__owner }}" group: "{{ cert__group }}" mode: "0660" @@ -103,7 +122,7 @@ - name: Ensure correct permissions for fullchain cert are set ansible.builtin.file: - path: "/etc/ansible_certs/{{ item }}/fullchain.pem" + path: "/etc/ansible_certs/certs/{{ item }}/fullchain.pem" owner: "{{ cert__owner }}" group: "{{ cert__group }}" mode: "0660" @@ -111,20 +130,20 @@ - name: Get content of cert.pem ansible.builtin.slurp: - src: "/etc/ansible_certs/{{ item }}/cert.pem" + src: "/etc/ansible_certs/certs/{{ item }}/cert.pem" become: true register: cert__cert_slurp - name: Get content of fullchain.pem ansible.builtin.slurp: - src: "/etc/ansible_certs/{{ item }}/fullchain.pem" + src: "/etc/ansible_certs/certs/{{ item }}/fullchain.pem" become: true register: cert__fullchain_slurp - name: Ensure ca.pem is created ansible.builtin.copy: content: "{{ cert__fullchain_slurp.content | b64decode | replace(cert__cert_slurp.content | b64decode, '') }}" - dest: "/etc/ansible_certs/{{ item }}/ca.pem" + dest: "/etc/ansible_certs/certs/{{ item }}/ca.pem" owner: "{{ cert__owner }}" group: "{{ cert__group }}" mode: "0660"