Reputation: 643
I want to format a dict in ansible like so,
from
{'a': 1, 'b': 2, 'c': 3}
to
'a=1,b=2,c=3'
and have to set it as an environment variable in a block like so,
vars:
test_env:
a: 1
b: 2
c: 3
- block:
# tasks
environment:
SOME_ENV: 'a=1,b=2,c=3'
here I want to convert test_env
dict to 'a=1,b=2,c=3'
I can not set the fact to modify the dict and then set it to the SOME_ENV
because environment
is a different clause, maybe I can modify the dict in the vars
clause but is there any other solution?
Upvotes: 3
Views: 11485
Reputation: 68394
Decompose the dictionary to the lists of keys and values. Then zip the lists and join the items. For example,
- block:
- command: echo $SOME_ENV
register: result
- debug:
var: result.stdout
environment:
SOME_ENV: "{{ test_env.keys()|
zip(test_env.values())|
map('join', '=')|
join(',') }}"
give
result.stdout: a=1,b=2,c=3
update
There are more options. You can also use Jinja or JMESPath. The below expressions give the same result
SOME_ENV: |-
{%- for k,v in test_env.items() %}
{{ k }}={{ v }}{% if not loop.last %},{% endif %}
{%- endfor %}
SOME_ENV: "{{ test_env|dict2items|
json_query('[].join(`=`, [key, to_string(value)])')|
join(',') }}"
Example of a complete playbook for testing
- hosts: all
vars:
test_env:
a: 1
b: 2
c: 3
tasks:
- block:
- command: "echo ${{ item }}"
register: result
loop: [SOME_ENV, SOME_EN2, SOME_EN3]
- debug:
msg: "{{ result.results|
items2dict(key_name='item', value_name='stdout') }}"
environment:
SOME_ENV: "{{ test_env.keys()|
zip(test_env.values())|
map('join', '=')|
join(',') }}"
SOME_EN2: |-
{%- for k,v in test_env.items() %}
{{ k }}={{ v }}{% if not loop.last %},{% endif %}
{%- endfor %}
SOME_EN3: "{{ test_env|dict2items|
json_query('[].join(`=`, [key, to_string(value)])')|
join(',') }}"
gives (abridged)
msg:
SOME_EN2: a=1,b=2,c=3
SOME_EN3: a=1,b=2,c=3
SOME_ENV: a=1,b=2,c=3
Upvotes: 8