MBasith
MBasith

Reputation: 1499

Ansible Update Dict Var using Parsed String and Loop

I'm trying to use Ansible to update a dict var with a nested dict after parsing a string in a specific format. I am able to do this easily in python but having trouble translating the logic to Ansible. Looking through some documentation I see that I can use combine in a loop to update a dict but am not getting the desired results. Is there something I am missing in the logic I have below?

String: "husky-1-dog,burmese-2-cat"

Desired Ansible Dict: {'cat': {'age': '2', 'breed': 'burmese'}, 'dog': {'age': '1', 'breed': 'husky'}}

In Python:

mydict = {}
mystr = "husky-1-dog,burmese-2-cat"

mydict.update({i.split('-')[2]:
                   {'breed': i.split('-')[0],
                    'age': i.split('-')[1]}
               for i in mystr.split(',')})

Output:

{'cat': {'age': '2', 'breed': 'burmese'}, 'dog': {'age': '1', 'breed': 'husky'}}

Ansible:

---
- hosts: localhost
  gather_facts: false
  vars:
    mydict: {}
    mystr: "husky-1-dog,burmese-2-cat"

  tasks:

    - name: Create Nested Dict
      set_fact:
        contents_dict: "{{ mydict | combine({item.split('-')[2]: {'breed': item.split('-')[0], 'age': item.split('-')[1]}}, recursive=true) }}"
      loop: "{{ mystr.split(',') }}"

    - debug: msg={{mystr.split(',')}}
    - debug: var=mydict

Output:

PLAY [localhost] ***********************

TASK [Create Nested Dict] **************
ok: [127.0.0.1] => (item=husky-1-dog)
ok: [127.0.0.1] => (item=burmese-2-cat)

TASK [debug] **************************
ok: [127.0.0.1] => {
    "mydict": {}
}

Upvotes: 1

Views: 148

Answers (1)

Zeitounator
Zeitounator

Reputation: 44595

You were really close. You are just setting the wrong named var. Moreover, you can bypass initializing the var to empty dict by using the default filter:

---
- hosts: localhost
  gather_facts: false
  vars:
    mystr: "husky-1-dog,burmese-2-cat"

  tasks:

    - name: Create Nested Dict
      set_fact:
        mydict: "{{ mydict | default({}) | combine({item.split('-')[2]: {'breed': item.split('-')[0], 'age': item.split('-')[1]}}, recursive=true) }}"
      loop: "{{ mystr.split(',') }}"

    - debug: msg={{mystr.split(',')}}
    - debug: var=mydict

which gives:

PLAY [localhost] **************************************************************************************************************************************************************************************************

TASK [Create Nested Dict] *****************************************************************************************************************************************************************************************
ok: [localhost] => (item=husky-1-dog)
ok: [localhost] => (item=burmese-2-cat)

TASK [debug] ******************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "husky-1-dog",
        "burmese-2-cat"
    ]
}

TASK [debug] ******************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "mydict": {
        "cat": {
            "age": "2",
            "breed": "burmese"
        },
        "dog": {
            "age": "1",
            "breed": "husky"
        }
    }
}

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Upvotes: 1

Related Questions