- name: 'Build arguments for letsencrypt acme.sh driver for: {{ cert.key }}' set_fact: # NOTE(ianw): note the domains are passed in one string (between # ") as it makes argument parsing a little easier in the driver.sh acme_args: '"{% for domain in cert.value %}-d {{ domain }} {% endfor %}"' - name: Run acme.sh driver for certificate issue shell: cmd: | /opt/acme.sh/driver.sh issue {{ acme_args }} args: chdir: /opt/acme.sh/ environment: LETSENCRYPT_STAGING: '{{ "1" if letsencrypt_test_only else "0" }}' register: acme_output - debug: var: acme_output.stdout_lines # NOTE(ianw): The output is challenge-domain:txt-key which we split # into a tuple here. acme.sh by default puts the hostname into the # challenge domain it outputs. For simplicity, we don't actually make # use of the full challenge-domain part; our default CNAME setup # points "_acme-challenge.host.opendev.org" to just "acme.opendev.org" # -- thus we put all the keys into "top-level" TXT records directly at # acme.opendev.org. letsencyrpt doesn't care; it just follows the # CNAME and enumerates all the TXT records in acme.opendev.org looking # for one that matches. So even though we don't put it in the dns # records, having the hostname the TXT record is for is handy for # debugging, etc, so we pass it through. - set_fact: acme_txt_required: '{{ acme_txt_required + [(item.split(":")[0], item.split(":")[1])] }}' loop: '{{ acme_output.stdout_lines }}'