Reputation: 24032
I'm trying to build security groups rule and routes from a list of CIDRs, and can't quite get the mapping syntax right.
I have an list of cidrs:
cidrs:
- 10.12.0.0/16
- 10.99.0.0/16
- 192.168.128.0/24
And I'd like to transform it into a list of rules for a security group, such as:
rules:
- proto: all
cidr_ip: 10.12.0.0/16
- proto: all
cidr_ip: 10.99.0.0/16
- proto: all
cidr_ip: 192.168.128.0/24
What's the syntax for performing this sort of transformation using Jinja2/Ansible filters?
Upvotes: 4
Views: 4352
Reputation: 68024
1. Filter combine in loop
For example, the playbook
shell> cat playbook.yml
- hosts: localhost
vars:
cidrs:
- 10.12.0.0/16
- 10.99.0.0/16
- 192.168.128.0/24
protos:
proto: all
tasks:
- set_fact:
rules: "{{ rules|default([]) +
[{'cidr_ip': item}|combine(protos)] }}"
loop: "{{ cidrs }}"
- debug:
var: rules
gives (abridged)
shell> ansible-playbook playbook.yml
rules:
- cidr_ip: 10.12.0.0/16
proto: all
- cidr_ip: 10.99.0.0/16
proto: all
- cidr_ip: 192.168.128.0/24
proto: all
2. Modified list and filter combine in map
If the input is a list of dictionaries, aka hashes, then simple map would do the job. For example, the playbook below gives the same result
shell> cat playbook.yml
- hosts: localhost
gather_facts: false
vars:
cidrs:
- cidr_ip: 10.12.0.0/16
- cidr_ip: 10.99.0.0/16
- cidr_ip: 192.168.128.0/24
protos:
proto: all
tasks:
- set_fact:
rules: "{{ cidrs|map('combine', protos)|list }}"
- debug:
var: rules
3. Custom plugin and filter combine in map
The filter product seems a good candidate to start with the transformation of a simple list into a list of hashes. But, there is no filter in Ansible to transform a list of two items into a dictionary, AFAIK. Let's write such a filter. For example
shell> cat filter_plugins/dict.py
def item2dict(t):
h = {t[0]:t[1]}
return h
class FilterModule(object):
''' Ansible dict filters '''
def filters(self):
return {
'item2dict': item2dict
}
Then the playbook below gives the same result
shell> cat playbook.yml
- hosts: localhost
vars:
cidrs:
- 10.12.0.0/16
- 10.99.0.0/16
- 192.168.128.0/24
protos:
proto: all
tasks:
- set_fact:
rules: "{{ ['cidr_ip']|product(cidrs)|map('item2dict')|
map('combine', protos)|list }}"
- debug:
var: rules
Upvotes: 2