Let's say I would like to run the following task from ansible:
- name: dns-cloudflare | Request certificate
ansible.builtin.shell:
cmd: certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials {{ certbot_cloudflare_credentials_file }} \
--non-interactive \
--agree-tos \
--expand \
--email {{ certbot_email }} \
--domain {{ __domains }}
args:
executable: /bin/bash
creates: "{{ certbot_directory }}/{{ item.name }}/{{ item.name }}/cert.pem"
I build it with a block like this:
certbot_cert:
- name: test1.example.com
cn:
- test2-cn.example.com
post-hook: systemctl restart apache2
- name: test3.example.com
I want to add the --post-hook argument to my certbot command depending on whether item.post-hook
. And the content for this hook is not static, whatever I type in there should land in my certbot command like --post-hook 'systemctl restart apache2'
But when I don't define this variable, there should not be an empty post-hook, it should not be in the certbot command at all.
How can I achieve this?
I played around with variables and filters and I read through the documentation but I didn't find a proper way to handle is. Duplication this task several times for every possible optional argument should not be the way.
The way you've written the value of cmd
does not preserve newlines -- which is what you want, since that means (a) you don't need to escape (\
) the end of lines like you've done in your example, and (b) you can conveniently use jinja conditionals to suppress some lines.
Like this:
- hosts: localhost
gather_facts: false
vars:
certbot_cloudflare_credentials_file: creds.conf
certbot_email: alice@example.com
__domains: example.com
certbot_directory: certs
certbot_cert:
- name: test1.example.com
cn:
- test2-cn.example.com
post-hook: systemctl restart apache2
- name: test3.example.com
tasks:
- name: dns-cloudflare | Request certificate
loop: "{{ certbot_cert }}"
ansible.builtin.shell:
cmd: certbot certonly
--dns-cloudflare
--dns-cloudflare-credentials "{{ certbot_cloudflare_credentials_file }}"
--non-interactive
--agree-tos
--expand
--email "{{ certbot_email }}"
--domain "{{ __domains }}"
{% if 'post-hook' in item %}
--post-hook "{{ item["post-hook"] }}"
{% endif %}
args:
executable: /bin/bash
creates: "{{ certbot_directory }}/{{ item.name }}/{{ item.name }}/cert.pem"
For the first item in certbot_cert
, this will run:
certbot certonly --dns-cloudflare --dns-cloudflare-credentials creds.conf --non-interactive --agree-tos --expand --email alice@example.com --domain example.com --post-hook systemctl restart apache2
And for the second line it will run:
certbot certonly --dns-cloudflare --dns-cloudflare-credentials creds.conf --non-interactive --agree-tos --expand --email alice@example.com --domain example.com