Score:1

Ansible: Convert string to dictionary

eg flag

I'm launching Ansible from Tower, then I'm filling the new users as a text:

{ name: user1, uid: 5000 }
{ name: user2, uid: 5001 }

I would like to iterate those users as a dictionary, something as:

- name: Print vars
  debug:
    var: "{{ item.name }}"
  with_items: "{{ users.split('\n') }}"

But it doesn't work:

TASK [Print vars] *********************************************************************************************************************
ok: [lx-test] => (item={ name: user1, uid: 5000 }) => {
    "ansible_loop_var": "item",
    "item": "{ name: user1, uid: 5000 }",
    "{ name: user1, uid: 5000 }": "VARIABLE IS NOT DEFINED!"
}
ok: [lx-test] => (item={ name: user2, uid: 5001 }) => {
    "ansible_loop_var": "item",
    "item": "{ name: user2, uid: 5001 }",
    "{ name: user2, uid: 5001 }": "VARIABLE IS NOT DEFINED!"
}

Any idea how to convert that string to a real dictionary? Thanks in advance!

Score:1
br flag

Update

The expression below

users_list: "{{ users_str.splitlines()|map('from_yaml')|list }}"

gives

users_list:
  - name: user1
    uid: 5000
  - name: user2
    uid: 5001

Declare the variable as appropriate.


Original answer

The text is neither valid JSON nor YAML. You'll have to split the lines and read the dictionaries line by line. For example, given the text

users_str: |
  { name: user1, uid: 5000 }
  { name: user2, uid: 5001 }

the task below

    - set_fact:
        users_list: "{{ users_list|d([]) + [item|from_yaml] }}"
      loop: "{{ users_str.splitlines() }}"

creates the list of dictionaries

users_list:
  - name: user1
    uid: 5000
  - name: user2
    uid: 5001

The iteration is trivial now

    - debug:
        var: item.name
      loop: "{{ users_list }}"

gives

  item.name: user1
  item.name: user2
Costales avatar
eg flag
Awesome reply, works perfect! Thank you so much Vladimir
Francisco Rebolledo avatar
us flag
Thanks! your solutions worked awesome. But would you please explain what users_list: "{{ users_list|d([]) + [item|from_yaml] }}" does? Thanks!
br flag
Sure. The expression concatenates the list. 'd' is an alias of 'default'. The 'item' is a string therefore it must be converted by the filter 'from_yaml'. You might want to decompose the loop and see it on your own.
br flag
See the simplified code.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.