aboutsummaryrefslogtreecommitdiff
path: root/roles
diff options
context:
space:
mode:
authorGravatar Jonas Gunz <himself@jonasgunz.de> 2022-09-20 18:11:00 +0200
committerGravatar Jonas Gunz <himself@jonasgunz.de> 2022-09-20 18:11:00 +0200
commite56713301b19c67480d84b55dd513575b50cfd42 (patch)
tree335eb6d29bc208d9c8057bb83c08311b4cf0316d /roles
parent216bc43ef7a270925ac597806c06030354ba9149 (diff)
downloadansible_collection-e56713301b19c67480d84b55dd513575b50cfd42.tar.gz
ACME for signed_certificate
Diffstat (limited to 'roles')
-rw-r--r--roles/signed_certificate/README.md35
-rw-r--r--roles/signed_certificate/defaults/main.yml12
-rw-r--r--roles/signed_certificate/playbook_create_account.yml28
-rw-r--r--roles/signed_certificate/tasks/letsencrypt.yml81
-rw-r--r--roles/signed_certificate/tasks/main.yml27
-rw-r--r--roles/signed_certificate/tasks/selfsigned.yml25
-rw-r--r--roles/signed_certificate/tasks/sign_selfsigned.yml (renamed from roles/signed_certificate/tasks/sign.yml)2
7 files changed, 174 insertions, 36 deletions
diff --git a/roles/signed_certificate/README.md b/roles/signed_certificate/README.md
index b048295..b1fa10e 100644
--- a/roles/signed_certificate/README.md
+++ b/roles/signed_certificate/README.md
@@ -3,22 +3,31 @@
## CA Settings
```
-signed_certificate:
- issuer_cn: 'Tets CN'
- renew_at: '+5d'
- valid_for: '+30d'
- privkey_path: '/tmp/ca.key'
- privkey_passphrase: '1234'
- cert_content: '{{ lookup('file', /tmp/cert.pem) }}'
-```
-
-## Certificate settings
-
-```
+---
cert_name: '{{ ansible_facts.fqdn }}'
+common_name: '{{ ansible_facts.fqdn }}'
key_path: '/etc/ssl/private/'
cert_path: '/etc/ssl/certs/'
alt_name: '{{ "DNS:" + ansible_facts.fqdn }}'
owner: root
-group: root
+group: ssl-cert
+
+signed_certificate:
+ issuer_cn: ''
+ renew_at: '+5d'
+ valid_for: '+30d'
+ privkey_path: '/invalid'
+ privkey_passphrase: ''
+ cert_content: ''
+
+use_acme: false
+
+acme:
+ directory: https://acme-v01.api.letsencrypt.org/directory
+ renew_at: 10
+ account_email: mail@example.com
+ account_key: 'INVALID'
+ gandi:
+ api_key: ''
+ domain: ''
```
diff --git a/roles/signed_certificate/defaults/main.yml b/roles/signed_certificate/defaults/main.yml
index d0ee48e..a94a14e 100644
--- a/roles/signed_certificate/defaults/main.yml
+++ b/roles/signed_certificate/defaults/main.yml
@@ -1,5 +1,6 @@
---
cert_name: '{{ ansible_facts.fqdn }}'
+common_name: '{{ ansible_facts.fqdn }}'
key_path: '/etc/ssl/private/'
cert_path: '/etc/ssl/certs/'
alt_name: '{{ "DNS:" + ansible_facts.fqdn }}'
@@ -13,3 +14,14 @@ signed_certificate:
privkey_path: '/invalid'
privkey_passphrase: ''
cert_content: ''
+
+use_acme: false
+
+acme:
+ directory: https://acme-v01.api.letsencrypt.org/directory
+ renew_at: 10
+ account_email: mail@example.com
+ account_key: 'INVALID'
+ gandi:
+ api_key: ''
+ domain: ''
diff --git a/roles/signed_certificate/playbook_create_account.yml b/roles/signed_certificate/playbook_create_account.yml
new file mode 100644
index 0000000..ac6c474
--- /dev/null
+++ b/roles/signed_certificate/playbook_create_account.yml
@@ -0,0 +1,28 @@
+---
+- name: Create ACME Account
+ hosts: localhost
+ vars:
+ directory: 'https://acme-staging-v02.api.letsencrypt.org/directory'
+ contact:
+ - 'mailto:mail@assdfkjsdhf.com'
+ tasks:
+ - name: Create private key
+ community.crypto.openssl_privatekey:
+ path: acme_account.key
+ return_content: True
+ size: 2048
+ register: privkey
+
+ - name: Create ACME Account
+ community.crypto.acme_account:
+ acme_directory: '{{ directory }}'
+ acme_version: 2
+ account_key_content: '{{ privkey.privatekey }}'
+ contact: '{{ contact }}'
+ state: present
+ terms_agreed: True
+ register: account
+
+ - name: Print account
+ debug:
+ var: account
diff --git a/roles/signed_certificate/tasks/letsencrypt.yml b/roles/signed_certificate/tasks/letsencrypt.yml
new file mode 100644
index 0000000..9d84bd3
--- /dev/null
+++ b/roles/signed_certificate/tasks/letsencrypt.yml
@@ -0,0 +1,81 @@
+---
+- name: Create CSR
+ community.crypto.openssl_csr_pipe:
+ privatekey_path: '{{ key_path }}/{{ cert_name }}.key'
+ common_name: '{{ common_name }}'
+ subject_alt_name: '{{ alt_name }}'
+ register: request
+ become: yes
+
+- name: Create a challenge using account key file.
+ community.crypto.acme_certificate:
+ account_key_content: '{{ acme.account_key }}'
+ modify_account: False
+ dest: '{{ cert_path }}/{{ cert_name }}.pem'
+ fullchain_dest: '{{ cert_path }}/{{ cert_name }}.fullchain.pem'
+ csr_content: '{{ request.csr }}'
+ challenge: dns-01
+ acme_directory: '{{ acme.directory }}'
+ acme_version: 2
+ remaining_days: '{{ acme.renew_at }}'
+ register: dns_challenge
+
+- name: Create DNS Challenge DNS Entry in LiveDNS
+ community.general.gandi_livedns:
+ domain: '{{ acme.gandi.domain }}'
+ record: '{{ item.key }}.'
+ type: TXT
+ ttl: 300
+ values: "{{ item.value | map('regex_replace', '^(.*)$', '\"\\1\"' ) | list }}"
+ api_key: '{{ acme.gandi.api_key }}'
+ state: present
+ loop: "{{ dns_challenge.challenge_data_dns | dict2items }}"
+ when: dns_challenge is changed
+
+- name: Wait a bit
+ pause:
+ seconds: 20
+ when: dns_challenge is changed
+
+- name: Validate the challenge and install certificates and chain
+ community.crypto.acme_certificate:
+ account_key_content: '{{ acme.account_key }}'
+ modify_account: False
+ csr_content: '{{ request.csr }}'
+ dest: '{{ cert_path }}/{{ cert_name }}.pem'
+ fullchain_dest: '{{ cert_path }}/{{ cert_name }}.fullchain.pem'
+ challenge: dns-01
+ acme_directory: '{{ acme.directory }}'
+ acme_version: 2
+ remaining_days: '{{ acme.renew_at }}'
+ data: '{{ dns_challenge }}'
+ register: dns_challenge
+ when: dns_challenge is changed
+ become: yes
+
+- name: Remove DNS Challenge DNS Entry in LiveDNS
+ community.general.gandi_livedns:
+ domain: '{{ acme.gandi.domain }}'
+ record: '{{ item.key }}.'
+ type: TXT
+ api_key: '{{ acme.gandi.api_key }}'
+ state: absent
+ loop: "{{ dns_challenge.challenge_data_dns | dict2items }}"
+ when: dns_challenge is changed
+
+# ===========================
+
+- name: Adjust file permissions
+ file:
+ path: '{{ item }}'
+ owner: '{{ owner }}'
+ group: '{{ group }}'
+ loop:
+ - '{{ cert_path }}/{{ cert_name }}.pem'
+ - '{{ cert_path }}/{{ cert_name }}.fullchain.pem'
+ become: yes
+
+- name: Set cert_changed flag
+ set_fact:
+ cert_changed: True
+ when: dns_challenge is changed
diff --git a/roles/signed_certificate/tasks/main.yml b/roles/signed_certificate/tasks/main.yml
index 4e214d2..4fb424d 100644
--- a/roles/signed_certificate/tasks/main.yml
+++ b/roles/signed_certificate/tasks/main.yml
@@ -35,27 +35,10 @@
become: yes
when: not key_check.failed
-- name: Read Existing Certificate
- community.crypto.x509_certificate_info:
- path: '{{ cert_path }}/{{ cert_name }}.pem'
- valid_at:
- point_1: '{{ signed_certificate.renew_at }}'
- ignore_errors: yes
- become: yes
- register: existing_cert
-
-- name: Check Certificate
- assert:
- that:
- - existing_cert.valid_at.point_1
- - not existing_cert.failed
- - existing_cert.subject.commonName == ansible_facts.fqdn
- - existing_cert.issuer.commonName == '{{ signed_certificate.issuer_cn }}'
- success_msg: Certificate is valid
- fail_msg: Certificate is not valid. creating a new one.
- ignore_errors: yes
- register: cert_assert
+- name: Trigger Cert Generation
+ include_tasks: selfsigned.yml
+ when: use_acme == false
- name: Trigger Cert Generation
- include: sign.yml
- when: cert_assert.failed
+ include_tasks: letsencrypt.yml
+ when: use_acme == true
diff --git a/roles/signed_certificate/tasks/selfsigned.yml b/roles/signed_certificate/tasks/selfsigned.yml
new file mode 100644
index 0000000..7b0957c
--- /dev/null
+++ b/roles/signed_certificate/tasks/selfsigned.yml
@@ -0,0 +1,25 @@
+---
+- name: Read Existing Certificate
+ community.crypto.x509_certificate_info:
+ path: '{{ cert_path }}/{{ cert_name }}.pem'
+ valid_at:
+ point_1: '{{ signed_certificate.renew_at }}'
+ ignore_errors: yes
+ become: yes
+ register: existing_cert
+
+- name: Check Certificate
+ assert:
+ that:
+ - existing_cert.valid_at.point_1
+ - not existing_cert.failed
+ - existing_cert.subject.commonName == common_name
+ - existing_cert.issuer.commonName == '{{ signed_certificate.issuer_cn }}'
+ success_msg: Certificate is valid
+ fail_msg: Certificate is not valid. creating a new one.
+ ignore_errors: yes
+ register: cert_assert
+
+- name: Trigger Cert Generation
+ include_tasks: sign_selfsigned.yml
+ when: cert_assert.failed
diff --git a/roles/signed_certificate/tasks/sign.yml b/roles/signed_certificate/tasks/sign_selfsigned.yml
index b99df32..fb610f6 100644
--- a/roles/signed_certificate/tasks/sign.yml
+++ b/roles/signed_certificate/tasks/sign_selfsigned.yml
@@ -2,7 +2,7 @@
- name: Create CSR
community.crypto.openssl_csr_pipe:
privatekey_path: '{{ key_path }}/{{ cert_name }}.key'
- common_name: '{{ ansible_facts.fqdn }}'
+ common_name: '{{ common_name }}'
subject_alt_name: '{{ alt_name }}'
register: request
become: yes