--- - name: Create and validate a TLS certificate using LetsEncrypt with DNS-01 challenge type, and AWS Route53 hosts: all gather_facts: false vars: account_email: someone@example.org acme_directory: https://acme-v02.api.letsencrypt.org/directory # acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory common_name: service.example.org remaining_days: 7 zone: example.org pre_tasks: - name: Generate private keys for an account and the certificate community.crypto.openssl_privatekey: path: "{{ item }}" type: RSA size: 4096 with_items: - /tmp/{{ common_name }}.key - /tmp/acme.account.key.pem - name: Generate private keys for an account and the certificate - OpenSSH alternative when: false community.crypto.openssh_keypair: path: "{{ item }}" type: rsa size: 4096 with_items: - /tmp/{{ common_name }}.key - /tmp/acme.account.key.pem tasks: - name: Generate the CRS for the certificate community.crypto.openssl_csr: path: /tmp/{{ common_name }}.crs privatekey_path: /tmp/{{ common_name }}.key common_name: "{{ common_name }}" - name: Create the DNS challenge for '{{ common_name }}' community.crypto.acme_certificate: challenge: dns-01 acme_version: 2 acme_directory: "{{ acme_directory }}" account_key_src: /tmp/acme.account.key.pem account_email: "{{ account_email }}" csr: /tmp/{{ common_name }}.crs dest: /tmp/{{ common_name }}.endpointOnly.crt # endpoint only certificate fullchain_dest: /tmp/{{ common_name }}.crt # full certificate chain terms_agreed: true remaining_days: "{{ remaining_days }}" # force: true register: dns_challenge notify: Create TXT records for challenge validation handlers: - name: Create TXT records for challenge validation when: common_name in dns_challenge.challenge_data amazon.aws.route53: zone: "{{ zone }}" record: "{{ dns_challenge.challenge_data[common_name]['dns-01'].record }}" type: TXT ttl: 60 state: present overwrite: true wait: true value: # shall be enclosed in quotation marks >- {{ dns_challenge.challenge_data[common_name]['dns-01'].resource_value | regex_replace('^(.*)$', '"\1"') }} notify: Validate the challenge and create the certificate - name: Validate the challenge and create the certificate community.crypto.acme_certificate: challenge: dns-01 acme_version: 2 acme_directory: "{{ acme_directory }}" account_key_src: /tmp/acme.account.key.pem account_email: "{{ account_email }}" csr: /tmp/{{ common_name }}.crs dest: /tmp/{{ common_name }}.endpointOnly.crt # endpoint only certificate fullchain_dest: /tmp/{{ common_name }}.crt # full certificate chain remaining_days: "{{ remaining_days }}" terms_agreed: true data: "{{ dns_challenge }}" # force: true post_tasks: - name: Delete TXT records for challenge validation vars: validation_record: "{{ ['_acme-challenge', common_name] | join('.') }}" when: query('community.dns.lookup', validation_record, type='TXT') != [] amazon.aws.route53: zone: "{{ zone }}" record: "{{ validation_record }}" type: TXT state: absent wait: true