一、什么是 Jinja2 过滤器?

Jinja2 过滤器(Filters) 是一种用于对模板变量进行格式化或转换的工具。
在 Ansible 中,它们常用于:

  • 对用户输入做默认值处理;
  • 转换数据类型(如字符串转数字);
  • 操作字符串、列表、字典等结构;
  • 加密、路径处理、网络地址解析等高级操作。

📌 语法{{ 变量 | 过滤器(参数) }}


二、为什么需要过滤器?——核心价值

🎯 场景示例:安装软件包(带默认值)

- name: install packages
  hosts: node02
  gather_facts: no
  tasks:
    - name: install web pkgs
      yum:
        name: "{{ web_name | default('nginx') }}"
        state: present
  • 如果用户传入 web_name=apache → 安装 apache;
  • 如果未传入 → 自动安装 nginx(默认值)。

优势

  • 避免变量未定义导致 playbook 失败;
  • 提高 playbook 的灵活性与健壮性。

三、常用过滤器分类详解


🔹 1. 默认值过滤器:default

过滤器 作用 示例
default(value) 若变量未定义或为空,则使用默认值 {{ mysql_port |default(‘3306’) }}

💡 注意:若变量为 None 或空字符串(""),也会触发默认值(除非设置 default(..., true) 忽略空值)。


🔹 2. 字符串操作过滤器

过滤器 作用 示例
upper 转大写 "hello" | upper"HELLO"
lower 转小写 "HELLO" | lower"hello"
capitalize 首字母大写 "hello" | capitalize"Hello"
reverse 倒序 "abc" | reverse"cba"
first / last 取首/尾字符 "abc" | first"a"
trim 去除首尾空格 " abc " | trim"abc"
center(30) 居中并补空格至30位 "hi" | center(10)" hi "
length 返回长度 "abc" | length3
list 转为字符列表 "ab" | list['a', 'b']
shuffle 随机打乱字符顺序 "abc" | shuffle → 如 ['c','a','b']

使用场景:日志格式化、用户名标准化、配置文件内容预处理。


🔹 3. 数字操作过滤器

过滤器 作用 示例
int 转整数(失败可设默认) '8.6' | int8'a' | int(default=0)0
float 转浮点数 '8' | float8.0
abs 绝对值 -5 | abs5
round 四舍五入 3.14159 | round(2)3.14
random 生成随机数 100 | random0~99 之间;支持 start, step

使用场景:端口计算、随机密码生成、数值校验。


🔹 4. 列表操作过滤器

过滤器 作用 示例
length 列表长度 [1,2,3] | length3
first / last 取首/尾元素 [1,2,3] | first1
min / max 最小/最大值 [3,1,2] | max3
sort 排序(reverse=true 降序) [3,1,2] | sort[1,2,3]
sum 求和 [1,2,3] | sum6
flatten 扁平化嵌套列表 [[1,2],[3]] | flatten[1,2,3]
join(',') 合并为字符串 ['a','b'] | join(',')"a,b"
random 随机取一个元素 [1,2,3] | random → 如 2
shuffle 随机打乱顺序 [1,2,3] | shuffle → 如 [3,1,2]
union 集合并集运算 {{ [1,2,3] | union([3,4,5]) }}[1,2,3,4,5]
intersect 集合交集运算 {{ [1,2,3] | intersect([2,3,4]) }}[2,3]
difference 集合差集运算 {{ [1,2,3] | difference([2,3,4]) }}[1]
symmetric_difference 集合对称差运算 {{ [1,2,3] | symmetric_difference([2,3,4]) }}[1,4]

使用场景:合并多个服务列表、去重、权限组交集判断。

🧩 集合运算示例:

vars:
  group_a: [dev, ops, admin]
  group_b: [ops, qa, admin]

tasks:
  - debug: msg="{{ group_a | union(group_b) }}"           # [dev, ops, admin, qa]
  - debug: msg="{{ group_a | intersect(group_b) }}"       # [ops, admin]
  - debug: msg="{{ group_a | difference(group_b) }}"      # [dev]
  - debug: msg="{{ group_a | symmetric_difference(group_b) }}" # [dev, qa]

🔹 5. 注册变量状态过滤器(⚠️ Ansible 2.9+ 已弃用)

过滤器 作用
failed 任务是否失败
changed 任务是否变更
success 任务是否成功
skipped 任务是否跳过

⚠️ 替代方案:直接使用 register_result is failed 等条件判断。


🔹 6. 文件路径过滤器

过滤器 作用 示例
basename 取文件名 /etc/passwd | basename"passwd"
dirname 取目录路径 /etc/passwd | dirname"/etc"
expanduser 展开 ~ "~/.bashrc" | expanduser/home/user/.bashrc
realpath 解析软链接真实路径 /etc/localtime | realpath/usr/share/zoneinfo/Asia/Shanghai

使用场景:动态构建日志路径、备份脚本路径处理。


🔹 7. 加解密过滤器

过滤器 作用 示例
hash('sha256') 通用哈希 "secret" | hash('sha256')
password_hash('sha512') 密码加密(用于 user 模块) "123456" | password_hash('sha512')
b64encode / b64decode Base64 编解码 "hello" | b64encode"aGVsbG8="

使用场景:安全存储密码、API Token 编码传输。


🔹 8. 网络地址过滤器(需安装 python3-netaddr

控制节点执行:pip3 install netaddr

表达式 作用 示例(输入:192.168.1.10/24
ipaddr 验证并返回标准格式 "192.168.1.10/24"
ipaddr('network') 网络地址 "192.168.1.0"
ipaddr('netmask') 子网掩码 "255.255.255.0"
ipaddr('broadcast') 广播地址 "192.168.1.255"
ipaddr('size') 可用 IP 数 256
ipaddr('host') 主机地址+掩码 "192.168.1.10/24"
ipaddr('ipv4') 强制 IPv4 同上

使用场景:自动生成防火墙规则、DHCP 范围计算。


🔹 9. URL 解析过滤器

过滤器 作用 示例(URL: https://user:pass@www.example.com:8080/path?query=1
urlsplit('hostname') 域名 "www.example.com"
urlsplit('port') 端口 8080
urlsplit('scheme') 协议 "https"
urlsplit('path') 路径 "/path"
urlsplit('query') 查询参数 "query=1"
urlsplit('netloc') 完整主机部分 "user:pass@www.example.com:8080"

使用场景:解析 API 地址、动态构建服务 URL。


🔹 10. 查找与替换过滤器(支持正则)

过滤器 作用 示例
replace("old", "new") 普通替换 "hello world" | replace("world", "Ansible")
regex_replace(r'\d+', '#') 正则替换 "abc123" | regex_replace('\d+', 'XXX')"abcXXX"
regex_search(r'\w+') 搜索第一个匹配 "ID: 123" | regex_search('\d+')"123"
regex_findall(r'\d+') 查找所有匹配 "a1b2c3" | regex_findall('\d')['1','2','3']

使用场景:日志提取、配置文件动态修改、敏感信息脱敏。


🔹 11. 字典操作过滤器

过滤器 作用 示例
combine(other_dict) 合并字典(后者覆盖前者) {"a":1} | combine({"b":2}){"a":1,"b":2}
dict2items 字典 → 列表(每项含 key/value) {"name":"tom"} | dict2items[{"key":"name","value":"tom"}]
items2dict 列表 → 字典 上述结果反向转换
to_json / to_yaml 转 JSON/YAML 字符串 用于调试或写入文件
to_nice_json 格式化易读 JSON 适合 human-readable 输出
from_json / from_yaml 从字符串解析结构 读取外部配置文件

使用场景:动态生成配置、合并多来源配置、API 数据处理。


🔹 12. 自定义过滤器(Python 开发)

步骤:

  1. ansible.cfg 中指定插件路径:

    [defaults]
    filter_plugins = ./plugins/filter
    
  2. 创建 ./plugins/filter/my_filters.py

    def to_uppercase(value):
        return str(value).upper()
    
    class FilterModule:
        def filters(self):
            return {
                'to_uppercase': to_uppercase
            }
    
  3. 在 playbook 中使用:

    - debug:
        msg: "{{ 'hello' | to_uppercase }}"  # 输出: HELLO
    

使用场景:企业特定逻辑封装(如合规检查、特殊编码规则)。


四、综合使用场景举例

场景 1:动态生成 Nginx 配置

server {
    listen {{ port | default(80) }};
    server_name {{ domain | lower | default('localhost') }};
    root /var/www/{{ app_name | default('default') }};
}

场景 2:安全密码处理

- name: create user with encrypted password
  user:
    name: alice
    password: "{{ 'MyPass123' | password_hash('sha512') }}"

场景 3:IP 地址自动分配

- set_fact:
    network_base: "{{ ip_range | ipaddr('network') }}"
    gateway: "{{ ip_range | ipaddr('gateway') }}"

五、练习题(巩固掌握)

📝 基础题

  1. 写一个 playbook,要求用户输入一个字符串,若未输入则默认为 "default_value",并将其转为大写输出。
  2. 将列表 [10, 5, 8, 3] 排序后取最大值,并计算总和。
  3. 使用 b64encode"ansible" 进行编码,再用 b64decode 解码验证。

📝 进阶题

  1. 给定路径 /opt/app/config.yaml,使用过滤器分别提取目录名和文件名。
  2. 用户输入一个 IP 地址(如 10.0.0.5/24),自动计算其子网、广播地址和可用 IP 数量。
  3. 将字典 {"name": "Tom", "age": 25} 转换为 YAML 格式并美化输出。

📝 挑战题

  1. 编写一个自定义过滤器 mask_ip,将 IP 地址 192.168.1.10 转为 192.168.1.xxx
  2. 从 URL https://api.example.com/v1/users?id=123&token=abc 中提取 idtoken 参数(提示:先 urlsplit('query'),再用 split 或正则)。

六、总结

类别 关键过滤器 应用价值
默认处理 default 防止变量缺失
数据转换 int, float, upper, lower 类型适配、格式统一
结构操作 join, sort, combine, flatten 动态构建复杂数据
安全加密 password_hash, b64encode 安全合规
网络/路径 ipaddr, basename 自动化运维核心
正则处理 regex_replace 灵活文本处理
自定义扩展 Python 插件 企业级定制能力

💡 记住:过滤器是 Ansible 实现“声明式 + 灵活性”的关键工具!

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐