I need to dynamically set a new list type variable list var.
Here's a basic playbook example:
vars:
app_instances:
- host_name: host1-domain
inst_count: 3
- host_name: host2-domain
inst_count: 1
- host_name: host3-domain
inst_count: 1
tasks:
- set_fact:
instance_config: >-
{% set inst_config = [] %}
{% for inst in app_instances %}
{% for inst_num in range(inst.inst_count) %}
{% set node_number = inst.host_name.split('-') | first | replace('host', '') %}
{% set host_name = "host_name" %}
{% set host_num = "host_num" %}
{% set inst_name = "inst_name" %}
{% set node_conf = { host_name: inst.host_name, host_num: node_number, inst_name: inst_num+1 } %}
{{ inst_config.append(node_conf) }}
{% endfor %}
{% endfor %}
{{ inst_config|join(",") }}
- debug:
msg: "{{ instance_config }}"
This obviously sets the instance_config
to a string with the following contents:
"instance_config": " \n \n \n \n \n {'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 1},{'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 2},{'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 3},{'host_name': 'host2-domain', 'host_num': '2', 'inst_name': 1},{'host_name': 'host3-domain', 'host_num': '3', 'inst_name': 1}"
So while the structure of the list that I'm getting is correct, it's a String and I can't seem to make this into a variable that would be a list instead. What Am I missing here? What I need eventually is a variable:
instance_config = [
{'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 1},
{'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 2},
{'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 3},
{'host_name': 'host2-domain', 'host_num': '2', 'inst_name': 1},
{'host_name': 'host3-domain', 'host_num': '3', 'inst_name': 1}
]
Answering my own question as I have found a solution:
do
jinja extension in ansible.cfg:jinja2_extensions = jinja2.ext.do
{{ inst_config.append(node_conf) }}
with{% do inst_config.append(node_conf) %}
{%-
and-%}
.The final result of the
set_fact
task looks like this:As an alternative approach to a similar problem using builtin
union
filter:Worth noting that any array modifications are not applied for clarity but should be easy to adopt.
My case was about gathering systemd unit names, which were generated dynamically by a few, independent from each other, roles.