11.4 Jinja2 Filters 🔧
Τι είναι τα Filters;
Τα filters μετασχηματίζουν τιμές μέσα σε expressions. Χρησιμοποιούν το σύμβολο | (pipe):
{{ value | filter }}
{{ value | filter(argument) }}
{{ value | filter1 | filter2 | filter3 }} ← chaining!
String Filters
{# ── Μετατροπή κειμένου ──────────────────── #}
{{ 'hello world' | upper }} → HELLO WORLD
{{ 'HELLO WORLD' | lower }} → hello world
{{ 'hello world' | capitalize }} → Hello world
{{ 'hello world' | title }} → Hello World
{# ── Trim & Replace ──────────────────────── #}
{{ ' hello ' | trim }} → hello
{{ ' hello ' | lstrip }} → hello (αριστερά)
{{ ' hello ' | rstrip }} → hello (δεξιά)
{{ 'hello world'| replace('world', 'ansible') }}
→ hello ansible
{# ── Length & Count ──────────────────────── #}
{{ 'hello' | length }} → 5
{{ ['a','b','c'] | length }} → 3
{# ── Truncate ────────────────────────────── #}
{{ 'Hello World' | truncate(5) }} → Hello...
{# ── String testing ──────────────────────── #}
{{ 'hello' | string }} → 'hello' (string type)
{# ── Formatting ──────────────────────────── #}
{{ '%s:%d' | format('host', 80) }} → host:80
{# ── Center/Left/Right align ─────────────── #}
{{ 'hi' | center(10) }} → hi
{{ 'hi' | ljust(10) }} → hi
{{ 'hi' | rjust(10) }} → hi
List Filters
{# ── Sorting ─────────────────────────────── #}
{{ [3,1,4,1,5] | sort }} → [1,1,3,4,5]
{{ [3,1,4,1,5] | sort(reverse=true) }}
→ [5,4,3,1,1]
{{ ['b','a','c'] | sort }} → ['a','b','c']
{# ── Unique ──────────────────────────────── #}
{{ [1,2,2,3,3,3] | unique }} → [1,2,3]
{{ [1,2,2,3,3,3] | unique | list }} → [1,2,3]
{# ── Min/Max/Sum ─────────────────────────── #}
{{ [3,1,4,1,5] | min }} → 1
{{ [3,1,4,1,5] | max }} → 5
{{ [3,1,4,1,5] | sum }} → 14
{# ── First/Last ──────────────────────────── #}
{{ [1,2,3,4,5] | first }} → 1
{{ [1,2,3,4,5] | last }} → 5
{# ── Join ────────────────────────────────── #}
{{ ['a','b','c'] | join(', ') }} → a, b, c
{{ ['a','b','c'] | join('\n') }} → a\nb\nc
{# ── Flatten ──────────────────────────────── #}
{{ [[1,2],[3,4]] | flatten }} → [1,2,3,4]
{# ── Reverse ──────────────────────────────── #}
{{ [1,2,3] | reverse | list }} → [3,2,1]
{# ── Select/Reject ───────────────────────── #}
{{ [1,2,3,4,5] | select('odd') | list }} → [1,3,5]
{{ [1,2,3,4,5] | reject('odd') | list }} → [2,4]
{{ [1,2,3,4,5] | select('gt',3) | list }} → [4,5]
{# ── Map ─────────────────────────────────── #}
{{ ['hello','world'] | map('upper') | list }}
→ ['HELLO','WORLD']
{# ── Batch (χωρισμός σε ομάδες) ──────────── #}
{{ [1,2,3,4,5] | batch(2) | list }} → [[1,2],[3,4],[5]]
Math Filters
{# ── Βασικά ──────────────────────────────── #}
{{ 3.7 | round }} → 4.0
{{ 3.7 | round(0, 'floor') }} → 3.0
{{ 3.7 | round(0, 'ceil') }} → 4.0
{{ 3.14159 | round(2) }} → 3.14
{# ── Absolute value ──────────────────────── #}
{{ -5 | abs }} → 5
{# ── Integer/Float conversion ────────────── #}
{{ '42' | int }} → 42
{{ '42' | int(0) }} → 42 (default=0 αν αποτύχει)
{{ '3.14' | float }} → 3.14
{{ '3.14' | float(0.0) }} → 3.14
{# ── Power/Log ───────────────────────────── #}
{{ 2 | pow(10) }} → 1024.0
{{ 1024 | log(2) }} → 10.0
Type Conversion Filters
{# ── Type casting ────────────────────────── #}
{{ 'true' | bool }} → True
{{ 'false' | bool }} → False
{{ 1 | bool }} → True
{{ 0 | bool }} → False
{{ '42' | int }} → 42
{{ '3.14' | float }} → 3.14
{{ 42 | string }} → '42'
{# ── List/Dict conversions ───────────────── #}
{{ 'hello' | list }} → ['h','e','l','l','o']
{{ {'a':1,'b':2} | dict2items }} → [{'key':'a','value':1},...]
{{ [{'key':'a','value':1}] | items2dict }}
→ {'a': 1}
Dict Filters
{# ── Keys & Values ───────────────────────── #}
{{ {'a':1,'b':2} | dict2items }}
{# → [{'key':'a','value':1},{'key':'b','value':2}] #}
{{ {'a':1,'b':2}.keys() | list }} → ['a','b']
{{ {'a':1,'b':2}.values() | list }} → [1,2]
{# ── Combine (merge dicts) ───────────────── #}
{% set dict1 = {'a': 1, 'b': 2} %}
{% set dict2 = {'b': 3, 'c': 4} %}
{{ dict1 | combine(dict2) }}
{# → {'a':1, 'b':3, 'c':4} (dict2 override) #}
Path Filters
{# ── Path operations ─────────────────────── #}
{{ '/etc/nginx/nginx.conf' | basename }} → nginx.conf
{{ '/etc/nginx/nginx.conf' | dirname }} → /etc/nginx
{{ '/etc/nginx/nginx.conf' | splitext }} → ['/etc/nginx/nginx', '.conf']
{{ '/etc/nginx' | realpath }} → /etc/nginx (resolved)
{{ 'relative/path' | expanduser }} → /home/user/relative/path
Hashing & Crypto Filters
{# ── Hashing ─────────────────────────────── #}
{{ 'hello' | hash('sha1') }} → aaf4c61...
{{ 'hello' | hash('sha256') }} → 2cf24dba...
{{ 'hello' | hash('md5') }} → 5d41402a...
{# ── Password hashing (για /etc/shadow) ──── #}
{{ 'MyPassword' | password_hash('sha512') }}
{# → $6$rounds=... (salted hash) #}
{# ── Base64 ──────────────────────────────── #}
{{ 'hello' | b64encode }} → aGVsbG8=
{{ 'aGVsbG8=' | b64decode }} → hello
Ansible-specific Filters
{# ── Human readable ──────────────────────── #}
{{ 1073741824 | human_readable }} → 1.00 GB
{{ ansible_facts['memtotal_mb'] * 1024 * 1024
| human_readable }}
{# ── Human to bytes ──────────────────────── #}
{{ '1GB' | human_to_bytes }} → 1073741824
{# ── IP address filters ───────────────────── #}
{{ '192.168.1.10' | ipaddr }} → 192.168.1.10
{{ '192.168.1.10' | ipaddr('network') }} → 192.168.1.0
{{ '192.168.1.10/24' | ipaddr('prefix') }}→ 24
{# ── Regex ───────────────────────────────── #}
{{ 'Hello World' | regex_replace('World', 'Ansible') }}
→ Hello Ansible
{{ 'foo123bar' | regex_findall('[0-9]+') }}
→ ['123']
{{ 'hello' | regex_search('e(l+)o', '\\1') }}
→ ['ll']
{# ── Random ──────────────────────────────── #}
{{ ['a','b','c'] | random }} → τυχαίο στοιχείο
{{ 100 | random }} → 0-99
{{ range(1,10) | random }} → 1-9
{# ── Shuffle ──────────────────────────────── #}
{{ ['a','b','c','d'] | shuffle }} → τυχαία σειρά
{# ── Unique ──────────────────────────────── #}
{{ [1,2,2,3,3] | unique | list }} → [1,2,3]
{# ── zip ─────────────────────────────────── #}
{{ [1,2,3] | zip(['a','b','c']) | list }}
{# → [[1,'a'],[2,'b'],[3,'c']] #}
Filters σε Templates — Πρακτικά παραδείγματα
{# templates/nginx.conf.j2 #}
{# ── Worker processes — από facts ─────────── #}
worker_processes {{ ansible_facts['processor_vcpus'] | int }};
{# ── Worker connections — υπολογισμός ────── #}
worker_connections {{ (ansible_facts['memtotal_mb'] / 4) | int | min(1024) }};
{# ── Server names — join από λίστα ─────────── #}
server_name {{ server_names | join(' ') }};
{# ── Keepalive — με default ─────────────── #}
keepalive_timeout {{ keepalive | default(65) }};
{# ── Client max body size — human readable ─ #}
client_max_body_size {{ max_upload | default('10M') }};
{# ── Log format — με replace ────────────── #}
access_log /var/log/nginx/{{ app_name | replace('-', '_') }}_access.log;
{# ── SSL protocols — join από λίστα ──────── #}
{% if ssl_enabled %}
ssl_protocols {{ ssl_protocols | default(['TLSv1.2', 'TLSv1.3']) | join(' ') }};
{% endif %}
{# templates/hosts.j2 #}
{# ── Δημιουργία /etc/hosts από inventory ─── #}
127.0.0.1 localhost
::1 localhost
{# Όλοι οι managed servers #}
{% for host in groups['all_managed'] %}
{{ hostvars[host]['ansible_host'] | default(host) }} {{ host }}
{% endfor %}
{# templates/fail2ban_jail.j2 #}
[DEFAULT]
bantime = {{ bantime | default(3600) }}
findtime = {{ findtime | default(600) }}
maxretry = {{ maxretry | default(5) }}
{# ── IPs από λίστα ───────────────────────── #}
{% if whitelist_ips is defined and whitelist_ips | length > 0 %}
ignoreip = 127.0.0.1/8 ::1 {{ whitelist_ips | join(' ') }}
{% else %}
ignoreip = 127.0.0.1/8 ::1
{% endif %}
[sshd]
enabled = true
port = {{ ssh_port | default(2022) }}
maxretry = {{ ssh_maxretry | default(3) }}
Filter Chaining — Συνδυασμός Filters
{# Πολλαπλά filters σε σειρά #}
{# Πάρε τα CPU cores, διπλασίασέ τα, μέγιστο 16 #}
{{ ansible_facts['processor_vcpus'] | int | multiply(2) | min(16) }}
{# Λίστα → unique → sort → join #}
{{ packages | unique | sort | join(', ') }}
{# String → lower → replace spaces → truncate #}
{{ app_name | lower | replace(' ', '_') | truncate(20, false, '') }}
{# Memory σε GB με 2 δεκαδικά #}
{{ (ansible_facts['memtotal_mb'] / 1024) | round(2) }} GB
{# Hostname → πρώτο γράμμα κεφαλαίο #}
{{ inventory_hostname | split('.') | first | capitalize }}
Σύνοψη 11.4
Jinja2 Filters
├── Σύνταξη: {{ value | filter }}
├── Chaining: {{ value | f1 | f2 | f3 }}
│
├── String: upper, lower, title, trim, replace,
│ length, truncate, format, center
├── List: sort, unique, min, max, sum,
│ first, last, join, flatten,
│ select, reject, map, batch
├── Math: round, abs, int, float, pow, log
├── Type: bool, int, float, string, list
├── Dict: dict2items, items2dict, combine
├── Path: basename, dirname, splitext
├── Crypto: hash, password_hash, b64encode/decode
└── Ansible: human_readable, ipaddr,
regex_replace, random, shuffle,
unique, zip, human_to_bytes