Reputation: 73
I have a list of strings that looks like this:
"forwarded_ports": [
"123",
"234",
"456"
]
And I'd like to use the values of this list as values in a list of dictionaries that would look like this:
"mapped_ports": [
{
"external_port": "123",
"internal_port": "123"
},
{
"external_port": "234",
"internal_port": "234"
},
{
"external_port": "456",
"internal_port": "456"
}
]
Is there a way to do this using inline Ansible/Jinja filters? I know I can do this easily with an Ansible loop like this:
- set_fact:
mapped_ports: "{{ mapped_ports| default([]) + [{ 'internal_port' : item , 'external_port' : item }] }}"
loop: "{{ forwarded_ports }}"
But ideally this data structure would be created on the fly in a defaults file with just filters, etc. It seems like there's a simple way to do it with map
and dict
filters but I can't seem to figure it out. Thanks for any help!
Upvotes: 3
Views: 556
Reputation: 33203
Ordinarily, I don't recommend json_query
but in this case it's a great fit for what you're trying to do because of its ability to construct new nodes via projection:
- debug:
msg: >-
{{ forwarded_ports | json_query("[*].{external_port: @, internal_port: @}") }}
vars:
"forwarded_ports": [
"123",
"234",
"456"
]
yields
ok: [localhost] => {
"msg": [
{
"external_port": "123",
"internal_port": "123"
},
{
"external_port": "234",
"internal_port": "234"
},
{
"external_port": "456",
"internal_port": "456"
}
]
}
Upvotes: 4
Reputation: 44635
In a nutshell (but I don't really recommend it as it is using a var as a full jinja2 template and I would stick to your actual set_fact
which is probably more legible for most users...):
---
- hosts: localhost
gather_facts: false
vars:
forwarded_ports:
- 123
- 234
- 456
mapped_ports: >-
{%- set mapped=[] -%}
{%- for port in forwarded_ports -%}
{{ mapped.append({'external_port': port, 'internal_port': port}) }}
{%- endfor -%}
{{ mapped }}
tasks:
- debug:
var: mapped_ports
Which gives:
$ ansible-playbook my_playbook.yml
PLAY [localhost] **************************************************************************************************************************************************************************************************************
TASK [debug] ******************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"mapped_ports": [
{
"external_port": 123,
"internal_port": 123
},
{
"external_port": 234,
"internal_port": 234
},
{
"external_port": 456,
"internal_port": 456
}
]
}
PLAY RECAP ********************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Upvotes: 3