Ansible Jinja2 Filters: Transform Data in Playbooks (Complete Reference)
By Luca Berton · Published 2024-01-01 · Category: web-servers
Complete reference for Ansible Jinja2 filters. Transform strings, lists, dictionaries, JSON, YAML, IP addresses, hashes, and dates with practical playbook.
Jinja2 filters transform data inline within Ansible playbooks. They convert types, format strings, filter lists, parse JSON/YAML, manipulate IPs, and more — all using the pipe (|) syntax.
String Filters
vars:
name: "ansible automation"
tasks:
- ansible.builtin.debug:
msg:
upper: "{{ name | upper }}" # ANSIBLE AUTOMATION
lower: "{{ name | lower }}" # ansible automation
title: "{{ name | title }}" # Ansible Automation
capitalize: "{{ name | capitalize }}" # Ansible automation
replace: "{{ name | replace('ansible', 'red hat') }}" # red hat automation
trim: "{{ ' hello ' | trim }}" # hello
length: "{{ name | length }}" # 20
truncate: "{{ name | truncate(10) }}" # ansible...
regex_replace: "{{ name | regex_replace('auto.*', 'platform') }}" # ansible platform
regex_search: "{{ name | regex_search('auto\\w+') }}" # automation
split: "{{ name | split(' ') }}" # ['ansible', 'automation']
join: "{{ ['a', 'b', 'c'] | join(', ') }}" # a, b, c
See also: Ansible default() Filter: Set Fallback Values for Undefined Variables
List Filters
vars:
servers: [web1, db1, web2, db2, web1]
numbers: [3, 1, 4, 1, 5, 9, 2, 6]
tasks:
- ansible.builtin.debug:
msg:
unique: "{{ servers | unique }}" # [web1, db1, web2, db2]
sort: "{{ numbers | sort }}" # [1, 1, 2, 3, 4, 5, 6, 9]
reverse: "{{ numbers | reverse | list }}" # [6, 2, 9, 5, 1, 4, 1, 3]
first: "{{ servers | first }}" # web1
last: "{{ servers | last }}" # web1
length: "{{ servers | length }}" # 5
flatten: "{{ [[1,2],[3,4]] | flatten }}" # [1, 2, 3, 4]
min: "{{ numbers | min }}" # 1
max: "{{ numbers | max }}" # 9
sum: "{{ numbers | sum }}" # 31
random: "{{ servers | random }}" # random element
shuffle: "{{ servers | shuffle }}" # random order
difference: "{{ [1,2,3,4] | difference([2,4]) }}" # [1, 3]
intersect: "{{ [1,2,3] | intersect([2,3,4]) }}" # [2, 3]
union: "{{ [1,2] | union([2,3]) }}" # [1, 2, 3]
Select & Reject Filters
vars:
users:
- name: alice
role: admin
active: true
- name: bob
role: developer
active: false
- name: charlie
role: admin
active: true
tasks:
# Filter by attribute
- name: Get active users
ansible.builtin.debug:
msg: "{{ users | selectattr('active') | list }}"
- name: Get admins
ansible.builtin.debug:
msg: "{{ users | selectattr('role', 'equalto', 'admin') | list }}"
- name: Get admin names only
ansible.builtin.debug:
msg: "{{ users | selectattr('role', 'eq', 'admin') | map(attribute='name') | list }}"
# ['alice', 'charlie']
- name: Get inactive users
ansible.builtin.debug:
msg: "{{ users | rejectattr('active') | list }}"
# Filter simple lists
- name: Numbers greater than 3
ansible.builtin.debug:
msg: "{{ [1,2,3,4,5] | select('greaterthan', 3) | list }}"
# [4, 5]
- name: Strings matching pattern
ansible.builtin.debug:
msg: "{{ ['web1','db1','web2','cache1'] | select('match', 'web.*') | list }}"
# ['web1', 'web2']
See also: Ansible map Filter: Extract Attributes from Lists (Complete Guide)
Dictionary Filters
vars:
config:
host: db.example.com
port: 5432
name: myapp
password: secret
tasks:
- ansible.builtin.debug:
msg:
keys: "{{ config | dict2items | map(attribute='key') | list }}"
items: "{{ config | dict2items }}"
combine: "{{ config | combine({'port': 3306, 'ssl': true}) }}"
dict2items / items2dict
# Convert dict → list of {key, value}
- name: Iterate dictionary
ansible.builtin.debug:
msg: "{{ item.key }} = {{ item.value }}"
loop: "{{ config | dict2items }}"
# Convert list → dict
- name: Build dict from list
ansible.builtin.set_fact:
rebuilt: "{{ [{'key': 'a', 'value': 1}, {'key': 'b', 'value': 2}] | items2dict }}"
# {a: 1, b: 2}
Type Conversion
- ansible.builtin.debug:
msg:
to_int: "{{ '42' | int }}" # 42
to_float: "{{ '3.14' | float }}" # 3.14
to_bool: "{{ 'true' | bool }}" # true
to_json: "{{ config | to_json }}" # JSON string
to_yaml: "{{ config | to_yaml }}" # YAML string
to_nice_json: "{{ config | to_nice_json }}" # Pretty JSON
from_json: "{{ json_string | from_json }}" # Parse JSON
from_yaml: "{{ yaml_string | from_yaml }}" # Parse YAML
string: "{{ 42 | string }}" # "42"
See also: Ansible regex_replace Filter: Find & Replace with Regex (Complete Guide)
Default Values
# Set default if undefined
- ansible.builtin.debug:
msg: "{{ optional_var | default('fallback') }}"
# Default with boolean check (empty string/list/0 → default)
- ansible.builtin.debug:
msg: "{{ maybe_empty | default('fallback', true) }}"
# Chained defaults
- ansible.builtin.debug:
msg: "{{ primary | default(secondary) | default('last_resort') }}"
# Mandatory — fail if undefined
- ansible.builtin.debug:
msg: "{{ required_var | mandatory }}"
JSON Query (json_query)
vars:
instances:
- name: web1
ip: 10.0.0.1
tags: {env: prod, role: web}
- name: db1
ip: 10.0.0.2
tags: {env: prod, role: db}
- name: web-dev
ip: 10.0.1.1
tags: {env: dev, role: web}
tasks:
- name: Get all IPs
ansible.builtin.debug:
msg: "{{ instances | json_query('[*].ip') }}"
# [10.0.0.1, 10.0.0.2, 10.0.1.1]
- name: Get prod instances
ansible.builtin.debug:
msg: "{{ instances | json_query('[?tags.env==`prod`].name') }}"
# [web1, db1]
- name: Get web server IPs
ansible.builtin.debug:
msg: "{{ instances | json_query('[?tags.role==`web`].ip') }}"
# [10.0.0.1, 10.0.1.1]
IP Address Filters
- ansible.builtin.debug:
msg:
network: "{{ '192.168.1.5/24' | ipaddr('network') }}" # 192.168.1.0
netmask: "{{ '192.168.1.5/24' | ipaddr('netmask') }}" # 255.255.255.0
broadcast: "{{ '192.168.1.5/24' | ipaddr('broadcast') }}" # 192.168.1.255
address: "{{ '192.168.1.5/24' | ipaddr('address') }}" # 192.168.1.5
prefix: "{{ '192.168.1.5/24' | ipaddr('prefix') }}" # 24
is_ipv4: "{{ '192.168.1.1' | ansible.utils.ipv4 }}" # 192.168.1.1
is_ipv6: "{{ '::1' | ansible.utils.ipv6 }}" # ::1
Hash and Encryption
- ansible.builtin.debug:
msg:
sha256: "{{ 'hello' | hash('sha256') }}"
md5: "{{ 'hello' | hash('md5') }}"
password: "{{ 'mypassword' | password_hash('sha512') }}"
b64encode: "{{ 'hello world' | b64encode }}"
b64decode: "{{ 'aGVsbG8gd29ybGQ=' | b64decode }}"
Path Filters
- ansible.builtin.debug:
msg:
basename: "{{ '/etc/nginx/nginx.conf' | basename }}" # nginx.conf
dirname: "{{ '/etc/nginx/nginx.conf' | dirname }}" # /etc/nginx
expanduser: "{{ '~/docs' | expanduser }}" # /home/user/docs
realpath: "{{ '/etc/nginx/../hosts' | realpath }}" # /etc/hosts
splitext: "{{ 'file.tar.gz' | splitext }}" # ('file.tar', '.gz')
Ternary (Conditional)
- ansible.builtin.debug:
msg: "{{ (ansible_os_family == 'Debian') | ternary('apt', 'yum') }}"
- name: Set package manager
ansible.builtin.set_fact:
pkg_mgr: "{{ (ansible_os_family == 'RedHat') | ternary('dnf', 'apt') }}"
FAQ
What are Ansible Jinja2 filters?
Filters transform data using the pipe (|) syntax in Ansible templates and playbooks. They convert types, format strings, filter lists, parse JSON/YAML, and more — executed inline without separate tasks.
What is the difference between select and selectattr?
select filters simple lists by value ([1,2,3] | select('greaterthan', 1)). selectattr filters lists of dictionaries by attribute (users | selectattr('active', 'equalto', true)).
How do I set a default value for undefined variables?
Use the default filter: {{ my_var | default('fallback') }}. Add true as second argument to also trigger default on empty values: {{ my_var | default('fallback', true) }}.
How do I parse JSON in Ansible?
Use from_json: {{ json_string | from_json }}. For querying complex JSON structures, use json_query with JMESPath expressions: {{ data | json_query('[?status==active].name') }}.
Conclusion
Most-used filters quick reference:
• default() — Fallback for undefined variables
• selectattr() / map() — Filter and transform lists of dicts
• to_json / from_json — Serialize/parse JSON
• regex_replace() / regex_search() — Pattern matching
• combine() — Merge dictionaries
• json_query() — JMESPath queries on complex data
Related Articles
• Ansible map Filter: Transform Lists • Ansible regex_replace: Search & Replace • Ansible default() Filter: Set Fallback Values • Ansible Variable Precedence Guide • Ansible regex_search Filter Guide • Can You Use assert in Jinja Templates? • Ansible Compare Lists: difference, intersect, unionCategory: web-servers