Ansible自动化(十二):Jinja2过滤器

一、什么是 Jinja2 过滤器?

Jinja2 过滤器(Filters) 是一种用于对模板变量进行格式化或转换的工具。

在 Ansible 中,它们常用于:

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

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


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

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

yaml 复制代码
- 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

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


🔹 2. 字符串操作过滤器

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

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


🔹 3. 数字操作过滤器

过滤器 作用 示例
int 转整数(失败可设默认) `'8.6'
float 转浮点数 `'8'
abs 绝对值 `-5
round 四舍五入 `3.14159
random 生成随机数 `100

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


🔹 4. 列表操作过滤器

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

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

🧩 集合运算示例:

yaml 复制代码
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
dirname 取目录路径 `/etc/passwd
expanduser 展开 ~ `"~/.bashrc"
realpath 解析软链接真实路径 `/etc/localtime

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


🔹 7. 加解密过滤器

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

使用场景:安全存储密码、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"
regex_replace(r'\d+', '#') 正则替换 `"abc123"
regex_search(r'\w+') 搜索第一个匹配 `"ID: 123"
regex_findall(r'\d+') 查找所有匹配 `"a1b2c3"

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


🔹 11. 字典操作过滤器

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

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


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

步骤:

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

    ini 复制代码
    [defaults]
    filter_plugins = ./plugins/filter
  2. 创建 ./plugins/filter/my_filters.py

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

    yaml 复制代码
    - debug:
        msg: "{{ 'hello' | to_uppercase }}"  # 输出: HELLO

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


四、综合使用场景举例

场景 1:动态生成 Nginx 配置

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

场景 2:安全密码处理

yaml 复制代码
- name: create user with encrypted password
  user:
    name: alice
    password: "{{ 'MyPass123' | password_hash('sha512') }}"

场景 3:IP 地址自动分配

yaml 复制代码
- 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 实现"声明式 + 灵活性"的关键工具!

相关推荐
cly117 小时前
Ansible自动化(十三):调试与优化
数据库·自动化·ansible
P-ShineBeam17 小时前
八卡A100服务器坏卡引发 CUDA initialization: cudaGetDeviceCount()异常
运维·服务器·人工智能·语言模型
萤丰信息17 小时前
开启园区“生命体”时代——智慧园区系统,定义未来的办公与生活
java·大数据·运维·数据库·人工智能·生活·智慧园区
cly117 小时前
Ansible自动化(十四):Roles(角色)
服务器·自动化·ansible
Nobody__118 小时前
解决多台服务器 UID/GID 做对齐后,文件系统元数据未更新的情况
运维·服务器
兆龙电子单片机设计18 小时前
【STM32项目开源】STM32单片机智能语音家居控制系统
stm32·单片机·嵌入式硬件·物联网·开源·自动化
珂玥c18 小时前
windows系统nfs挂载
运维·windows·ssh·remmina·cygwin
菜择贰18 小时前
在linux(wayland)中禁用键盘
linux·运维·chrome
梦想的旅途218 小时前
基于 UI 自动化(RPA)实现企业微信外部群操作的架构设计
ui·自动化·rpa