Combining values in Ansible

Viewed 31

I need to create a cronjob for renewal lets encrypt certificates. The final command should looks like this:

certbot certonly --no-eff-email -m my@mail.com --redirect --agree-tos --non-interactive --standalone -d mydomain.com -d www.mydomain.com -d domain1.mydomain.com -d domain1a.mydomain.com -d domain2.mydomain.com -d domain2a.mydomain.com

I have the following variables:

nginx:
  vhost:
    - name: mydomain.com
      server_name:
        - mydomain.com
        - www.mydomain.com
      ...
      ...
    - name: domain1.mydomain.com
      server_name:
        - domain1.mydomain.com
        - domain1a.mydomain.com
      ...
      ...
    - name: domain2.mydomain.com
      server_name:
        - domain2.mydomain.com
        - domain2a.mydomain.com
      ...
      ...
      ...

How can I get this values from nginx.vhost.server_name of each vhost in one command?

2 Answers

Here's one example; I'm using a debug task instead of, say, a command task, because I don't want to actually run anything on my computer, but this should demonstrate the technique:

- hosts: localhost
  gather_facts: false
  vars:
    nginx:
      vhost:
        - name: mydomain.com
          server_name:
            - mydomain.com
            - www.mydomain.com
        - name: domain1.mydomain.com
          server_name:
            - domain1.mydomain.com
            - domain1a.mydomain.com
        - name: domain2.mydomain.com
          server_name:
            - domain2.mydomain.com
            - domain2a.mydomain.com
  tasks:
    - debug:
        msg: "cerbot {% for name in server_names %}-d {{name}} {%endfor%}"
      vars:
        server_names: "{{ nginx.vhost|map(attribute='server_name')|flatten }}"

We use the map filter to extract the value of server_name from each item in the nginx.vhost list, and then pass the result to flatten to get a single list instead of a list of lists.

Running the above will generate as output:

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "cerbot -d mydomain.com -d www.mydomain.com -d domain1.mydomain.com -d domain1a.mydomain.com -d domain2.mydomain.com -d domain2a.mydomain.com "
}

For example

    - debug:
        msg: "cerbot -d {{ server_names }}"
      vars:
        server_names: "{{ nginx.vhost|map(attribute='server_name')|flatten|join(' -d ') }}"

gives

  msg: cerbot -d mydomain.com -d www.mydomain.com -d domain1.mydomain.com -d domain1a.mydomain.com -d domain2.mydomain.com -d domain2a.mydomain.com
Related