168 lines
6.7 KiB
YAML
168 lines
6.7 KiB
YAML
---
|
|
- name: Include vault variables
|
|
ansible.builtin.include_vars: vault.yml
|
|
|
|
- name: Get local public IP
|
|
ansible.builtin.uri:
|
|
url: https://ipinfo.io/ip
|
|
return_content: true
|
|
register: local_public_ip
|
|
|
|
- name: Get public IP of "{{ domain }}"
|
|
ansible.builtin.set_fact:
|
|
target_public_ip: "{{ lookup('community.general.dig', domain, '@1.1.1.1') }}"
|
|
|
|
- name: Create needed directories
|
|
become: true
|
|
ansible.builtin.file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: 0755
|
|
with_items:
|
|
- /etc/letsencrypt/renewal
|
|
- /etc/letsencrypt/archive
|
|
- "/etc/letsencrypt/archive/{{ domain }}"
|
|
- /etc/letsencrypt/live
|
|
- "/etc/letsencrypt/live/{{ domain }}"
|
|
|
|
- name: Add webroot configuration for letsencrypt
|
|
become: true
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/letsencrypt/cli.ini
|
|
line: webroot-path = /var/www/acme
|
|
|
|
- name: Create renewal configuration for "{{ domain }}"
|
|
become: true
|
|
ansible.builtin.template:
|
|
src: renewal.conf.j2
|
|
dest: "/etc/letsencrypt/renewal/{{ domain }}.conf"
|
|
mode: 0644
|
|
|
|
- name: Create private key for account
|
|
become: true
|
|
community.crypto.openssl_privatekey_pipe:
|
|
register: account_privkey
|
|
|
|
- name: Create private key for challenge
|
|
become: true
|
|
community.crypto.openssl_privatekey:
|
|
path: "/etc/letsencrypt/archive/{{ domain }}/privkey1.pem"
|
|
register: challenge_privkey
|
|
|
|
- name: Create csr for letsencrypt
|
|
become: true
|
|
community.crypto.openssl_csr_pipe:
|
|
privatekey_path: "/etc/letsencrypt/archive/{{ domain }}/privkey1.pem"
|
|
common_name: "{{ domain }}"
|
|
register: csr
|
|
changed_when: challenge_privkey is changed
|
|
|
|
- name: Do http-01 challenge
|
|
become: true
|
|
when: local_public_ip.content == target_public_ip
|
|
block:
|
|
- name: Create acme challenge
|
|
community.crypto.acme_certificate:
|
|
acme_version: 2
|
|
acme_directory: https://acme-v02.api.letsencrypt.org/directory
|
|
account_email: "{{ server_admin }}"
|
|
account_key_content: "{{ account_privkey.privatekey }}"
|
|
terms_agreed: true
|
|
csr_content: "{{ csr.csr }}"
|
|
challenge: http-01
|
|
dest: "/etc/letsencrypt/archive/{{ domain }}/cert1.pem"
|
|
chain_dest: "/etc/letsencrypt/archive/{{ domain }}/chain1.pem"
|
|
fullchain_dest: "/etc/letsencrypt/archive/{{ domain }}/fullchain1.pem"
|
|
register: letsencrypt_challenge
|
|
- name: Copy http-01 resource
|
|
ansible.builtin.copy:
|
|
dest: "/var/www/acme/{{ letsencrypt_challenge['challenge_data'][domain]['http-01']['resource'] }}"
|
|
content: "{{ letsencrypt_challenge['challenge_data'][domain]['http-01']['resource_value'] }}"
|
|
mode: 0644
|
|
when: letsencrypt_challenge is changed and domain in letsencrypt_challenge.challenge_data
|
|
- name: Validate the challenge and get the cert
|
|
community.crypto.acme_certificate:
|
|
acme_version: 2
|
|
acme_directory: https://acme-v02.api.letsencrypt.org/directory
|
|
account_email: "{{ server_admin }}"
|
|
account_key_content: "{{ account_privkey.privatekey }}"
|
|
csr_content: "{{ csr.csr }}"
|
|
challenge: http-01
|
|
dest: "/etc/letsencrypt/archive/{{ domain }}/cert1.pem"
|
|
chain_dest: "/etc/letsencrypt/archive/{{ domain }}/chain1.pem"
|
|
fullchain_dest: "/etc/letsencrypt/archive/{{ domain }}/fullchain1.pem"
|
|
data: "{{ letsencrypt_challenge }}"
|
|
when: letsencrypt_challenge is changed and domain in letsencrypt_challenge.challenge_data
|
|
- name: Remove the http-01 resource
|
|
ansible.builtin.file:
|
|
path: "/var/www/acme/{{ letsencrypt_challenge['challenge_data'][domain]['http-01']['resource'] }}"
|
|
state: absent
|
|
when: letsencrypt_challenge is changed and domain in letsencrypt_challenge.challenge_data
|
|
|
|
- name: Do dns-01 challenge
|
|
become: true
|
|
when: local_public_ip.content != target_public_ip
|
|
block:
|
|
- name: Create acme challenge
|
|
community.crypto.acme_certificate:
|
|
acme_version: 2
|
|
acme_directory: https://acme-v02.api.letsencrypt.org/directory
|
|
account_email: "{{ server_admin }}"
|
|
account_key_content: "{{ account_privkey.privatekey }}"
|
|
terms_agreed: true
|
|
csr_content: "{{ csr.csr }}"
|
|
challenge: dns-01
|
|
dest: "/etc/letsencrypt/archive/{{ domain }}/cert1.pem"
|
|
chain_dest: "/etc/letsencrypt/archive/{{ domain }}/chain1.pem"
|
|
fullchain_dest: "/etc/letsencrypt/archive/{{ domain }}/fullchain1.pem"
|
|
register: letsencrypt_challenge
|
|
- name: Create dns-01 record
|
|
community.general.gandi_livedns:
|
|
api_key: "{{ gandi_livedns_api_key }}"
|
|
domain: "{{ (domain | split('.'))[-2:] | join('.') }}"
|
|
record: "{{ letsencrypt_challenge.challenge_data[domain]['dns-01'].resource }}.{{ (domain | split('.'))[:-2] | join('.') }}"
|
|
values:
|
|
- "{{ letsencrypt_challenge.challenge_data[domain]['dns-01'].resource_value }}"
|
|
type: TXT
|
|
state: present
|
|
ttl: 300
|
|
when: letsencrypt_challenge is changed and domain in letsencrypt_challenge.challenge_data
|
|
- name: Wait for DNS to propagate
|
|
ansible.builtin.pause:
|
|
seconds: 300
|
|
when: letsencrypt_challenge is changed and domain in letsencrypt_challenge.challenge_data
|
|
- name: Validate the challenge and get the cert
|
|
community.crypto.acme_certificate:
|
|
acme_version: 2
|
|
acme_directory: https://acme-v02.api.letsencrypt.org/directory
|
|
account_email: "{{ server_admin }}"
|
|
account_key_content: "{{ account_privkey.privatekey }}"
|
|
csr_content: "{{ csr.csr }}"
|
|
challenge: dns-01
|
|
dest: "/etc/letsencrypt/archive/{{ domain }}/cert1.pem"
|
|
chain_dest: "/etc/letsencrypt/archive/{{ domain }}/chain1.pem"
|
|
fullchain_dest: "/etc/letsencrypt/archive/{{ domain }}/fullchain1.pem"
|
|
data: "{{ letsencrypt_challenge }}"
|
|
when: letsencrypt_challenge is changed and domain in letsencrypt_challenge.challenge_data
|
|
- name: Remove dns-01 record
|
|
community.general.gandi_livedns:
|
|
api_key: "{{ gandi_livedns_api_key }}"
|
|
domain: "{{ (domain | split('.'))[-2:] | join('.') }}"
|
|
record: "{{ letsencrypt_challenge.challenge_data[domain]['dns-01'].resource }}.{{ (domain | split('.'))[:-2] | join('.') }}"
|
|
type: TXT
|
|
state: absent
|
|
when: letsencrypt_challenge is changed and domain in letsencrypt_challenge.challenge_data
|
|
|
|
- name: Create symlinks for the certificate
|
|
become: true
|
|
ansible.builtin.file:
|
|
path: "/etc/letsencrypt/live/{{ domain }}/{{ item.dest }}"
|
|
src: "/etc/letsencrypt/archive/{{ domain }}/{{ item.src }}"
|
|
state: link
|
|
with_items:
|
|
- {src: cert1.pem, dest: cert.pem}
|
|
- {src: chain1.pem, dest: chain.pem}
|
|
- {src: fullchain1.pem, dest: fullchain.pem}
|
|
- {src: privkey1.pem, dest: privkey.pem}
|