Search code examples
loopsdictionarysslansiblecertificate

Is it possible to update a dictionary in ansible with a new value?


is it possible to update a dictionary in ansible with a new value?

Here's what I have:

  vars:
    LIST_OF_CERTS:
    - url: "supercoolhost.org"
      port: 443
      expiry_date: ""
    - url: "anotherHost.org"
      port: 443
      expiry_date: ""

Then in one of the playbooks, I have this happening, where we are looping through LIST_OF_CERTS and doing various tasks on them. Part of that includes:

- name: Set Variables
  set_fact:
    CERT_NAME : "{{ item.url }}"
    CERT_PORT : "{{ item.port }}"

Which works, and CERT_NAME and CERT_PORT are used in a few other tasks. In addition to that I'm trying to update the expiry_date bit with:

- name: Set expiry date
  set_fact:
    "{{ item.expiry_date }}" : "{{ EXPIRY_DATE.stdout }}"

I get this as an error though:

fatal: [localhost]: FAILED! => {"changed": false, "msg": "The variable name '' is not valid. Variables must start with a letter or underscore character, and contain only letters, numbers and underscores."}

What am I doing wrong? It looks like that "{{ item.expiry_date }}" will output the empty string that I have, which is improper syntax, which makes sense to me, but how do I update the expiry_date key in the item dict?

UPDATE Set the Set expiry date to be something new, and tried to update dict with combine:

- name: Set expiry date
  set_fact:
    CERT_EXPIRY : "{{ EXPIRY_DATE.stdout }}"

- name: Add in expiry date to list of certs and update dict.
  set_fact:
    LIST_OF_CERTS: "{ LIST_OF_CERTS|combine({{'url': CERT_NAME, 'port': CERT_PORT, 'expiry_date': CERT_EXPIRY }}) }"

This seems to blank out my dict though, because the email I send out for notifications goes from

The following certs were checked:

* {'url': 'supercoolhost.org', 'port': 443, 'expiry_date': ''}
* {'url': 'anotherHost.org', 'port': 443, 'expiry_date': ''}

To just:

The following certs were checked:

* url
* port
* expiry_date

Solution

  • I just did a different solution altogether: Created an empty list called

    LIST_UPDATED_CERTS: []
    

    Then added the dict with the expiry_date to it like so:

    - name: Add in expiry date to list of certs.
      set_fact:
        LIST_UPDATED_CERTS: "{​​​​​​{​​​​​​ LIST_UPDATED_CERTS + [{​​​​​​'url': CERT_NAME, 'port': CERT_PORT, 'expiry_date': CERT_EXPIRY }​​​​​​]}​​​​​​}​​​​​​"
    

    And had the notification section for the email that gets set out use LIST_UPDATED_CERTS instead of LIST_CERTS.