Extract elements from a list and set it to variable (set_fact)

Viewed 423

I am passing the following list to my script as an extra var

ansible-playbook /home/ec2-user/ansible/start.yml --extra-vars  multi_config=['aa|111','bb|222','cc|444']

This is the only way I found to pass variables that contain a list or key/values (with the | separator) and I can't use json file as argument...

I'd like to loop this multi_config list and search for the element that contains "bb" and set it to a variable with set_fact to use it later.

I can load the list like this:

- name: set multi_config
  set_fact:
    multi_config: "{{ multi_config}}"
  when: multi_config is defined

But how can I extract the element that contains "bb"?

2 Answers

The extra variables passed to Ansible from the command line are always strings, e.g.

    - debug:
        msg: "{{ multi_config|type_debug }}"

gives

  msg: str

Use the filter from_yaml and convert the string to the list and iterate the items. There are many options for how to parse the data. For example, split the keys and values, and combine a dictionary

    - set_fact:
        mc_dict: "{{ mc_dict|default({})|combine({_key: _val}) }}"
      loop: "{{ multi_config|from_yaml }}"
      vars:
        _key: "{{ item.split('|').0 }}"
        _val: "{{ item.split('|').1 }}"

gives

  mc_dict:
    aa: '111'
    bb: '222'
    cc: '444'

There is actually a much better way to pass your info as --extra-vars supports inlined json

$ ansible localhost -m debug -a "msg={{ multi_config | type_debug }}" \
    -e '{"multi_config":{"aa":111,"bb":222,"cc":444}}'
localhost | SUCCESS => {
    "msg": "dict"
}

$ ansible localhost -m debug -a var=multi_config \
    -e '{"multi_config":{"aa":111,"bb":222,"cc":444}}'
localhost | SUCCESS => {
    "multi_config": {
        "aa": 111,
        "bb": 222,
        "cc": 444
    }
}

$ ansible localhost -m debug -a "msg={{ multi_config.cc }}" \
    -e '{"multi_config":{"aa":111,"bb":222,"cc":444}}'
localhost | SUCCESS => {
    "msg": "444"
}
Related