--- # Copyright (c) Ansible Project # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later ## PRIVATE KEY ################################################################################ - name: ({{ certgen_title }}) Create cert private key openssl_privatekey: path: "{{ remote_tmp_dir }}/{{ certificate_name }}.key" type: "{{ 'RSA' if key_type == 'rsa' else 'ECC' }}" size: "{{ rsa_bits if key_type == 'rsa' else omit }}" curve: >- {{ omit if key_type == 'rsa' else 'secp256r1' if key_type == 'ec256' else 'secp384r1' if key_type == 'ec384' else 'secp521r1' if key_type == 'ec521' else 'invalid value for key_type!' }} passphrase: "{{ certificate_passphrase | default(omit) | default(omit, true) }}" cipher: "{{ 'auto' if certificate_passphrase | default() else omit }}" force: true ## CSR ######################################################################################## - name: ({{ certgen_title }}) Create cert CSR openssl_csr: path: "{{ remote_tmp_dir }}/{{ certificate_name }}.csr" privatekey_path: "{{ remote_tmp_dir }}/{{ certificate_name }}.key" privatekey_passphrase: "{{ certificate_passphrase | default(omit) | default(omit, true) }}" subject_alt_name: "{{ subject_alt_name }}" subject_alt_name_critical: "{{ subject_alt_name_critical }}" return_content: true register: csr_result ## ACME STEP 1 ################################################################################ - name: ({{ certgen_title }}) Obtain cert, step 1 acme_certificate: select_crypto_backend: "{{ select_crypto_backend }}" acme_version: 2 acme_directory: https://{{ acme_host }}:14000/dir validate_certs: false account_key: "{{ (remote_tmp_dir ~ '/' ~ account_key ~ '.pem') if account_key_content is not defined else omit }}" account_key_content: "{{ account_key_content | default(omit) }}" account_key_passphrase: "{{ account_key_passphrase | default(omit) | default(omit, true) }}" modify_account: "{{ modify_account }}" csr: "{{ omit if use_csr_content | default(false) else remote_tmp_dir ~ '/' ~ certificate_name ~ '.csr' }}" csr_content: "{{ csr_result.csr if use_csr_content | default(false) else omit }}" dest: "{{ remote_tmp_dir }}/{{ certificate_name }}.pem" fullchain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-fullchain.pem" chain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-chain.pem" challenge: "{{ challenge }}" deactivate_authzs: "{{ deactivate_authzs }}" force: "{{ force }}" remaining_days: "{{ remaining_days }}" terms_agreed: "{{ terms_agreed }}" account_email: "{{ account_email }}" register: challenge_data - name: ({{ certgen_title }}) Print challenge data debug: var: challenge_data - name: ({{ certgen_title }}) Create HTTP challenges uri: url: "http://{{ acme_host }}:5000/http/{{ item.key }}/{{ item.value['http-01'].resource[('.well-known/acme-challenge/'|length):] }}" method: PUT body_format: raw body: "{{ item.value['http-01'].resource_value }}" headers: content-type: "application/octet-stream" with_dict: "{{ challenge_data.challenge_data }}" when: "challenge_data is changed and challenge == 'http-01'" - name: ({{ certgen_title }}) Create DNS challenges uri: url: "http://{{ acme_host }}:5000/dns/{{ item.key }}" method: PUT body_format: json body: "{{ item.value }}" with_dict: "{{ challenge_data.challenge_data_dns }}" when: "challenge_data is changed and challenge == 'dns-01'" - name: ({{ certgen_title }}) Create TLS ALPN challenges (acme_challenge_cert_helper) acme_challenge_cert_helper: challenge: tls-alpn-01 challenge_data: "{{ item.value['tls-alpn-01'] }}" private_key_src: "{{ remote_tmp_dir }}/{{ certificate_name }}.key" private_key_passphrase: "{{ certificate_passphrase | default(omit) | default(omit, true) }}" with_dict: "{{ challenge_data.challenge_data if challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'acme_challenge_cert_helper') else {} }}" register: tls_alpn_challenges when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'acme_challenge_cert_helper')" - name: ({{ certgen_title }}) Read private key slurp: src: '{{ remote_tmp_dir }}/{{ certificate_name }}.key' register: slurp when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'acme_challenge_cert_helper')" - name: ({{ certgen_title }}) Set TLS ALPN challenges (acme_challenge_cert_helper) uri: url: "http://{{ acme_host }}:5000/tls-alpn/{{ item.domain }}/{{ item.identifier }}/certificate-and-key" method: PUT body_format: raw body: "{{ item.challenge_certificate }}\n{{ slurp.content | b64decode }}" headers: content-type: "application/pem-certificate-chain" with_items: "{{ tls_alpn_challenges.results if challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'acme_challenge_cert_helper') else [] }}" when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'acme_challenge_cert_helper')" - name: ({{ certgen_title }}) Create TLS ALPN challenges (der-value-b64) uri: url: "http://{{ acme_host }}:5000/tls-alpn/{{ item.value['tls-alpn-01'].resource }}/{{ item.value['tls-alpn-01'].resource_original }}/der-value-b64" method: PUT body_format: raw body: "{{ item.value['tls-alpn-01'].resource_value }}" headers: content-type: "application/octet-stream" with_dict: "{{ challenge_data.challenge_data if challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'der-value-b64') else {} }}" when: "challenge_data is changed and challenge == 'tls-alpn-01' and (challenge_alpn_tls | default('der-value-b64') == 'der-value-b64')" ## ACME STEP 2 ################################################################################ - name: ({{ certgen_title }}) Obtain cert, step 2 acme_certificate: select_crypto_backend: "{{ select_crypto_backend }}" acme_version: 2 acme_directory: https://{{ acme_host }}:14000/dir validate_certs: false account_key: "{{ (remote_tmp_dir ~ '/' ~ account_key ~ '.pem') if account_key_content is not defined else omit }}" account_key_content: "{{ account_key_content | default(omit) }}" account_key_passphrase: "{{ account_key_passphrase | default(omit) | default(omit, true) }}" account_uri: "{{ challenge_data.account_uri }}" modify_account: "{{ modify_account }}" csr: "{{ omit if use_csr_content | default(false) else remote_tmp_dir ~ '/' ~ certificate_name ~ '.csr' }}" csr_content: "{{ csr_result.csr if use_csr_content | default(false) else omit }}" dest: "{{ remote_tmp_dir }}/{{ certificate_name }}.pem" fullchain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-fullchain.pem" chain_dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-chain.pem" challenge: "{{ challenge }}" deactivate_authzs: "{{ deactivate_authzs }}" force: "{{ force }}" remaining_days: "{{ remaining_days }}" terms_agreed: "{{ terms_agreed }}" account_email: "{{ account_email }}" data: "{{ challenge_data }}" retrieve_all_alternates: "{{ retrieve_all_alternates | default(omit) }}" select_chain: "{{ select_chain | default(omit) if select_crypto_backend == 'cryptography' else omit }}" register: certificate_obtain_result when: challenge_data is changed - name: ({{ certgen_title }}) Deleting HTTP challenges uri: url: "http://{{ acme_host }}:5000/http/{{ item.key }}/{{ item.value['http-01'].resource[('.well-known/acme-challenge/'|length):] }}" method: DELETE with_dict: "{{ challenge_data.challenge_data }}" when: "challenge_data is changed and challenge == 'http-01'" - name: ({{ certgen_title }}) Deleting DNS challenges uri: url: "http://{{ acme_host }}:5000/dns/{{ item.key }}" method: DELETE with_dict: "{{ challenge_data.challenge_data_dns }}" when: "challenge_data is changed and challenge == 'dns-01'" - name: ({{ certgen_title }}) Deleting TLS ALPN challenges uri: url: "http://{{ acme_host }}:5000/tls-alpn/{{ item.value['tls-alpn-01'].resource }}" method: DELETE with_dict: "{{ challenge_data.challenge_data }}" when: "challenge_data is changed and challenge == 'tls-alpn-01'" - name: ({{ certgen_title }}) Get root certificate get_url: url: "http://{{ acme_host }}:5000/root-certificate-for-ca/{{ acme_expected_root_number | default(0) if select_crypto_backend == 'cryptography' else 0 }}" dest: "{{ remote_tmp_dir }}/{{ certificate_name }}-root.pem" ###############################################################################################