Ansible教程:Jinja2 模板-filter过滤器

介绍

Filter 是 Jinja2 的 数据转换工具,Ansible 同时内置原生 Jinja2 过滤器 + Ansible 扩展过滤器;

语法

使用管道符 |,所有过滤逻辑运行在控制节点,不是远程主机;支持链式调用 var | filter1 | filter2。

语法格式

{{ 变量 | 过滤器名(参数) }}
{{ var | filter1 | filter2(arg) }}  # 链式

区分:filter 用于转换数据;test(is)用于布尔判断,不要混淆。

变量默认值(高频)

变量未定义/None 时返回默认值;

default("变量",boolean)

参数:

  • boolean=true 会把空字符串、空列表、0 都当成空。

例子

nano playbook_过滤器.yml

内容如下:

---
- name: 测试 Jinja2 filter
  hosts: localhost
  gather_facts: false
  vars:
    name: 李雷
    num: 0
    users:
      - name: Alice
        enabled: true
      - name: Bob
        enabled: false
      - name: Charlie
        enabled: true
  tasks:
    - name: 判断admin变量是否定义
      debug:
        msg: "{{ admin | default(name) }}"   # 没定义admin变量,就使用name变量的值

    - name: 判断值为0就取默认值
      debug:
        msg: "{{ num | default(10, boolean=true) }}"   # 如果num是0,就取值10

    - name: 判断list_var列表类型的变量未定义
      debug:
        msg: "{{ list_var | default([]) }}"  # 如果 list_var 未定义就返回 []

提示:列表、字典变量一律加 default([]) / default({})

模拟执行:

ansible-playbook playbook_过滤器.yml  -C -i ansible_client.ini

空值自定义提示

如果变量没定义,执行时会英文错误,不方便看

使用 mandatory(),当变量未定义时,可以给出自定义提示

{{ app_name | mandatory("必须定义 app_name") }}

例子

nano playbook_过滤器_空值自定义提示.yml

内容如下:

---
- name: 空值自定义提示
  hosts: localhost
  gather_facts: false
  tasks:
    - name: 空值自定义提示
      debug:
        msg: "{{ app_name | mandatory('必须定义 app_name') }}"

提示:列表、字典变量一律加 default([]) / default({})

模拟执行:

ansible-playbook playbook_过滤器_空值自定义提示.yml  -C -i ansible_client.ini

字符串处理过滤器

lower / upper:大小写转换

{{ "Hello" | lower }}  # hello
{{ "hello" | upper }}  # HELLO

regex_replace(pattern, replace, count=0, ignore_case=false)

正则替换,count=0 全部替换

{{ "a1b2c3" | regex_replace("[0-9]", "") }} # abc

split(分隔符):字符串切分成列表

{{ "192.168.1.1" | split(".") }} # ['192','168','1','1']

join(分隔符):列表拼接字符串

{{ ["a","b","c"] | join(",") }} # a,b,c

quote:shell 转义(shell 模块专用,防止注入)

{{ user_input | quote }}

b64encode / b64decode base64编解码

{{ "secret" | b64encode }}
{{ "c2VjcmV0" | b64decode }}

replace(原串,目标串):简单字符串替换

{{ "test" | replace("es","xx") }} # txx t

trim:去除首尾空白字符

{{ "  abc  " | trim }}

列表/数组过滤器(Ansible 最常用)

first / last:取列表第一个/最后一个元素

{{ [1,2,3] | first }} #1
{{ [1,2,3] | last }} #3

length:获取长度(字符串、列表、字典都可用)

{{ [1,2,3] | length }} #3
{{ "abc" | length }} #3

unique:列表去重

{{ [1,1,2,3] | unique }} # [1,2,3]

sort:列表排序

{{ [3,1,2] | sort }} # [1,2,3]
{{ users | sort(attribute='age') }} # 对象列表按属性排序

map(过滤器):对列表每一项执行过滤器

{{ ["A","B","C"] | map("lower") | list }} # ["a","b","c"]
{{ users | map(attribute="name") | list }} #提取所有name字段

select / reject:过滤元素

  • select:保留满足条件;reject:剔除满足条件
    {{ [1,2,3,4] | select("gt",2) | list }} #大于2:3,4
    {{ [1,2,3,4] | reject("gt",2) | list }} #<=2:1,2
    

selectattr / rejectattr:对象列表按属性过滤

# 保留 status == enabled 的对象
{{ users | selectattr("status","equalto","enabled") | list }}

字典过滤器

dict2items / items2dict:字典 ↔ 键值对列表转换

# dict -> [{"key":"k","value":"v"},...]
{{ {"name":"tom","age":20} | dict2items }}
# 键值列表转回字典
{{ [{"key":"k","value":"v"}] | items2dict }}

combine:合并多个字典(覆盖key)

{{ dict1 | combine(dict2) }}
{{ dict1 | combine(dict2, recursive=True) }} #递归合并嵌套字典

路径处理过滤器(Ansible扩展)

{{ "/etc/nginx/nginx.conf" | basename }} # nginx.conf
{{ "/etc/nginx/nginx.conf" | dirname }} # /etc/nginx
{{ "~/.ssh/id_rsa" | expanduser }} #展开家目录
{{ "/a/b/../c" | normpath }} #规范化路径

数据序列化:JSON / YAML

{{ data | to_json }}       #紧凑json
{{ data | to_nice_json }}  #带缩进格式化json
{{ data | to_yaml }}
{{ data | from_json }}     #json字符串转对象
{{ data | from_yaml }}

数学计算

{{ 10 | int }}    #转为整数
{{ 10.5 | float }}#转为浮点数
{{ 3 | pow(2) }}  #3^2=9
{{ 5 | round }}   #四舍五入

时间过滤器

{{ "%Y-%m-%d" | strftime }} #当前时间格式化
{{ 1727452800 | strftime("%Y-%m-%d") }} #时间戳转日期