I’m having trouble creating a wildcard certificate for a domain with acme_certificate.
I’ve followed this guide and successfully produced certificate (I changed the “shell”-part with appropriate openssl-modules)
I want to create a certificate with .domain.name and domain.name but it’s not working with that playbook.
I get stuck in the task “Implement http-01 challenge files”
Obviously… You can’t name a file with a '’ in it’s name.
How do I get around this problem within ansible and being idempotent or do I have to do a certbot shell-command to the host listening on port 80 to create the certificate *.domain.name?
Hi,
you cannot use http-01 challenges for wildcard certificates. You need
to use the dns-01 challenge type for that. (This is a policy decision
by Let's Encrypt.)
How that works depends on how your DNS setup. Ansible needs to be able
to create/update the DNS TXT record _acme_challenge.domain.name for
this. (If you feel uncomfortable to give Let's Encrypt access to it,
you can also use a CNAME record and use
https://github.com/joohoi/acme-dns. Haven't tried that with Ansible
though.)
<https://www.digitalocean.com/community/tutorials/how-to-acquire-a-let-s-encrypt-certificate-using-ansible-on-ubuntu-18-04>
Interesting, I haven't seen that. One remark: you should change the
step which creates the http-01 challenge files slightly by adding
when: item in acme_challenge_your_domain['challenge_data']
to it. (Also see the examples in the module docs:
https://docs.ansible.com/ansible/latest/modules/acme_certificate_module.html#examples)
Obviously... You can't name a file with a '*' in it's name.
Actually, you can; you can even have a newline in a filename. But
that's never a good idea And won't help you here, since you can't
get wildcard certificates with the http-01 challenge.
Cheers,
Felix
Thank you for the answer!
Unfortunately I still can’t make acme_certificate to create the certificate.
I’ve changed the challenge to dns-01 and
taken care of creating the _acme-challenge.domain.name vi REST api
but when the last task is run I get:
“msg”: “Authorization for dns:*.domain.name returned invalid: CHALLENGE: dns-01 DETAILS: DNS problem: NXDOMAIN looking up TXT for _acme-challenge.domain.name - check that a DNS record exists for this domain;”
or
“msg”: “Authorization for dns:domain.name returned invalid: CHALLENGE: dns-01 DETAILS: DNS problem: NXDOMAIN looking up TXT for _acme-challenge.domain.name - check that a DNS record exists for this domain;”
alternately.
The DNS record exists * 2 before last task is run and as of the ansible output (-vvv) it’s the same token.
Thank You!
Patric
Hi,
Thank you for the answer!
Unfortunately I still can't make acme_certificate to create the
certificate. I've changed the challenge to dns-01 and
taken care of creating the _acme-challenge.domain.name vi REST api
but when the last task is run I get:
"msg": "Authorization for dns:*.domain.name returned invalid:
CHALLENGE: dns-01 DETAILS: DNS problem: NXDOMAIN looking up TXT for _
acme-challenge.domain.name - check that a DNS record exists for this
domain;"
or
"msg": "Authorization for dns:domain.name returned invalid:
CHALLENGE: dns-01 DETAILS: DNS problem: NXDOMAIN looking up TXT for _
acme-challenge.domain.name - check that a DNS record exists for this
domain;"
alternately.
The DNS record exists * 2 before last task is run and as of the
ansible output (-vvv) it's the same token.
it looks like the DNS record wasn't there when Let's Encrypt tried to
validate it from (some of) the authoritative name servers for your
domain. You might need to add some waiting to make sure that the DNS
entries propagated among all authoritative name servers for your domain.
Depending on how you set the DNS records, you can ask the API to tell
you when the values propagated (route53 can do that for example), or
you can simply let your playbook/role sleep for some time (I personally
use 30 seconds for my DNS provider; probably less will work as well,
but I never had problems with 30 so I'm sticking to it).
Best,
Felix
I created this snippet to wait for DNS resolution before proceeding with
the ACME verification.
\- name: '\{\{ certificate\.common\_name \}\} | "Wax on, wax off"'
debug:
msg: "\{\{ dns\_txt\_record \}\} <=> \{\{ item\.1 | first \}\}"
when: acme\_challenge is changed
loop: "\{\{ acme\_challenge\.challenge\_data\_dns | dictsort \}\}"
until: dns\_txt\_record == item\.1\[0\]
\# If the until parameter isn’t defined, the value for the retries
parameter is forced to 1.
Hi Edoardo,
for route53, you can simply set `wait: yes` (see
https://docs.ansible.com/ansible/latest/modules/route53_module.html#parameter-wait)
and the module will only return once all DNS servers have been updated.
Also takes some time (feels like forever ), but a lot less than 20
minutes.
For general waits, there's also the pause module
(https://docs.ansible.com/ansible/latest/modules/pause_module.html).
For example:
- name: Wait for DNS entries to propagate
pause:
seconds: 10
For 20 minutes your solution is better though, since you can see that
something is still happening once per minute
Cheers,
Felix
Thank you all!
I found a typo in a variable. It’s working as expected now.