Dict converted to string in 2.19

I just ran a playbook I have not run in awhile, and 2.19 bit me :slight_smile: I cant figure out how to re-write this and make it work again. Any help would be appreciated.

I have a group_vars file that has data like this:

__ds_defaults:
  clob: false
  connectionLimit: -1
  validate: false

my_config:
  ds_sources: >
    {
      {% for ds_name, ds_values in __env_ds.items() %}
        '{{ ds_name }}': {{
          __ds_defaults |
          combine(ds_values)|
          combine({
            'some_url': 'https://' + ds_values.host + ':' + ds_values.port 
          })
        }},
      {% endfor %}
    }

And then my playbook will define some __env_ds like

__env_ds:
  one:
    a: 1
    host: example.com
    port: 443
    clob: true

When I ran my playbook, I would use copy to dump my_config | to_nice_json to a file. ds_sources would be rendered as a dict/object in the json as expected.

With 2.19, its being rendered as a string in the config file. What can I do to fix this?

- hosts: localhost
  tasks:
    - debug:
        msg: "{{ my_config }}"
  vars:
    __ds_defaults:
      clob: false
      connectionLimit: -1
      validate: false
    __env_ds:
      one:
        a: 1
        host: example.com
        port: 443
        clob: true
    my_config: |-
      {% set my_var_tmp = {} %}
      {% for ds_name, ds_values in __env_ds.items() %}
      {% set _ = my_var_tmp.update(
          {ds_name:
             __ds_defaults |
             combine(ds_values)|
             combine({
              'some_url': 'https://' ~ ds_values.host ~ ':' ~ ds_values.port 
             })
          }
      ) %}
      {% endfor %}
      {{ my_var_tmp }}

(Based on something similar @bvitnik posted on Matrix a day ago or so :slight_smile: )

4 Likes

It works :face_holding_back_tears:. thanks @felixfontein and @bvitnik!

I found an open issue on the ansible repo that had something similar but for lists. I couldnt get it to work and was about to try something completely different. Amazing stuff