cd $INTRO_ANSIBLE_DIR/filters
.
├── ansible.cfg
├── data.csv
├── hosts
├── playbook-formatting.yml
├── playbook-list.yml
├── playbook-lookup.yml
└── undefined.yml
- A subset of functionality provided by Jinja2
- Toolset for
- formatting data
- iteration
- filtering
- Filter syntax:
-
variable
|
filtername
-
variable
contains data of some kind -
The "
|
" is the pipe symbol
-
- Filters will usually be used within Jinja2 expression syntax
-
{{
data
|
filter
}}
-
- Output data in yaml or json format respectively
- Can be used to generate config files that are consumed by applications
- Variants for making output prettier
- `to_nice_yaml`
- `to_nice_json`
- Add the following task to
playbook-formatting.yml
- name: Output myfirstapp as yaml config copy: dest: /home/train/myfirstapp.yml content: "{{ myfirstapp | to_nice_yaml }}" owner: train group: train mode: 0644
- Run the playbook
ansible-playbook playbook-formatting.yml
- Extra credit: use
to_nice_yaml
and adjust indentation
- There are different ways to deal with undefined variables
- Force failure
{{ variable |
mandatory
}}
- Provide a default
{{ variable |
default('ok')
}}
- Run
undefined.yml
- The mandatory filter causes the playbook to terminate at start when it attempts to access the variable
- Run a second time, but pass a value to someport using an extra variable
- Using
mandatory
filter not strictly necessary because Ansible will crash anyway if it encounters an undefined variable
- Note value of
db_port
in playbook outputTASK [Output value of a variable that hasn't been defined] **** ok: [localhost] => { "db_port": "3306" }
- The
default
filter can be used to set default value for an undefined variable - This is a better approach to handling undefined variables than
mandatory
(IMHO) - Run playbook with
-e someport2=5432
as an extra variable
- There are a plethora of filters for processing data structures
- Sorting
- Shuffling
- Slicing
- Set theory operations
- Filters can be chained for processing complex structures
myvar: {{ data | filter1 | filter2 | filter3 .. }}
- The
map
filter is useful for processing lists - Useful when chained to to other filters
- In
playbook-list.yml
add the followingsecurity_group_names: "{{ security_groups | map(attribute='name') | unique | list }}"
map
can extract data from dictionaries{{ [0,2] | map('extract', list1) | list }}
- <code style="font-size:18pt;"e>{{ ['day', 'year'] | map('extract', dict1) | list }}
- Add these to the vars section and add debug tasks to display them
- The
ipaddr
filter can be used to test vailidity of IP addresses-
'192.168.1.1' | ipaddr
=> '192.168.1.1'
-
'192.168.25.1.25' | ipaddr
=> false
-
-
`ipaddr` can also extract IP address from CIDR notation
'10.14.33.0/24' | ipaddr('address')
=> '10.14.33.0
-
`ipv4` and `ipv6` validate specific IP v4 and v6, respectively
myipv4 | ipv4
myipv6 | ipv6
- The
basename
filter extracts the base file name frm a path'/home/train/somefile.txt' | basename
- returns
somefile.txt
- Alternatively, extract the directory path with
dirname
'/home/train/somefile.txt' | dirname
- returns
/home/train
- Ansible provides a few useful filters for working with sets of data
- union
- union of two lists
- intersect
- unique list of items in two lists
- difference
- list of items in list 1 but not in list 2
-
Have a look at
set-filters.yml
-
Demonstrates a few simple set operations
-
Run the playbook
$ ansible-playbook set-filters.yml
Combination of items in two sets
All items in list1 and list2
all_items: "{{ list1 | union(list2) }}"
# apple,banana,orange,strawberry,peach,...
Items that are in first and second list
Items that are in both list1 and list2
intersect_lists "{{ list1 | intersect(list2) }}"
# apple, strawberry
Items that are in first set but not second set
Items that are in e list1 but not in list2
difference_list: "{{ list1 | difference(list2) }}"
# banana, orange, lime
- Ansible/Jinja2 provide a lot of filters for
- Processing string/text data
- Processing complex data
- Official Documentation