adb
adb

Reputation: 153

How to turn a variable into a dictionary item

I am struggling with what I believe is the simplest of tasks. I want to take a variable v and turn that into a dictionary where

v: ValueofV

The end goal is to write that dictionary to a JSON file that contains a list of variables, with key: value where key name is always a variable name, so for variables a, b, c, ... I should end up with:

{
  "a": "a_val",
  "b": "v_val",
  "c": "c_val"
}

I've tried building lists with_items, e.g.

- name: Var3
  set_fact:
    node_state4: "{{ node_state4 | default({}) | combine({ item : item })}}"
  with_items:
    - requested_node_count
    - added_node_count

But, that makes the value the string name. If I make the second item {{ item }} it fails.

Upvotes: 1

Views: 1338

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 68004

Use filter community.general.dict_kv e.g.

  _dict: "{{ v|community.general.dict_kv('v') }}"

gives

  _dict:
    v: ValueofV

Given the list of the variables

    rnodes: [a, b, c]
    a: a_val
    b: b_val
    c: c_val

iterate the list and create the dictionary, e.g.

    - set_fact:
        _dict: "{{ _dict|d({})|
                   combine(lookup('vars', item)|
                           community.general.dict_kv(item)) }}"
      loop: "{{ rnodes }}"

gives

  _dict:
    a: a_val
    b: b_val
    c: c_val

The next option is to extract the variables and use filters dict and zip, e.g. the task below gives the same result

    - set_fact:
        _dict: "{{ dict(rnodes|zip(_vals)) }}"
      vars:
        _vals: "{{ rnodes|map('extract', vars) }}"

Upvotes: 1

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39099

In order to access a variable value via a string representation of its name, you need to use the vars lookup.

So your task should be:

- set_fact:
    node_state4: >-
      {{ 
        node_state4 
          | default({}) 
          | combine({ item: lookup('vars', item) })
      }}
  loop:
    - requested_node_count
    - added_node_count

Given this the two tasks:

- set_fact:
  node_state4: >-
      {{ 
        node_state4 
          | default({}) 
          | combine({ item: lookup('vars', item) })
      }}
  loop:
    - requested_node_count
    - added_node_count
  vars:
    requested_node_count: foo
    added_node_count: bar

- debug:
    var: node_state4

This yields:

TASK [set_fact] **********************************************************
ok: [localhost] => (item=requested_node_count)
ok: [localhost] => (item=added_node_count)

TASK [debug] *************************************************************
ok: [localhost] => {
    "node_state4": {
        "added_node_count": "bar",
        "requested_node_count": "foo"
    }
}

Upvotes: 2

Related Questions