过滤器与查找的分工
过滤器处理已经拿到的值:列表、字符串、字典经过一串管道运算得到新值,纯计算、没有副作用。查找插件处理取数据这件事:它会去读文件、取环境变量、执行命令或查询密码库,通常默认在控制端执行且真的有 IO。两者的关键差别就是求值位置与副作用,混用会带来意料之外的结果与性能开销。
基本信息
| 过滤器写法 | 值后接管道再接过滤器名与参数 |
|---|---|
| 查找写法 | 调用查找函数传名称与参数,查询形式返回列表 |
| 求值位置 | 查找默认在控制端,可按需指定在目标端执行 |
| 常用过滤器 | default、map、select、join、combine、regex_replace、结构化输出 |
典型使用场景
- 处理列表:提取字段、按条件筛选、拼接成一行内容
- 生成结构化配置:把字典序列化成 JSON 或格式化 JSON 再落盘
- 读取控制端本地文件内容进变量:文本文件查找
- 取环境变量或证书内容:对应的专用查找插件
- 需要多个值时用返回列表的查询形式,避免只拿到第一项
过滤器与查找
过滤器与查找
- name: 过滤器链 # 纯计算,按顺序作用在值上
ansible.builtin.debug:
msg: "{{ users | map(attribute='name') | list | join(',') }}"
- name: 条件筛选后再拼 # 测试函数筛选元素
ansible.builtin.debug:
msg: "{{ ports | select('greaterthan', 1024) | list }}"
- name: 查找插件读取内容 # 默认在控制端执行,存在 IO
ansible.builtin.debug:
msg: "{{ lookup('file', '/etc/hostname') }}"类别对照
| 类别 | 写法特征 | 求值位置与副作用 |
|---|---|---|
| 过滤器 | 值后接管道与参数 | 控制端纯计算,无 IO |
| 查找插件 | 函数式调用并给名称 | 默认控制端,有 IO |
| 查询形式 | 返回列表的调用 | 多值场景更合适 |
| 模板渲染 | 由模板模块在目标端落文件 | IO 发生在目标机 |
查找默认读的是控制端的文件与变量,不是目标机的。需要目标机上的内容时改用读取远端文件的模块,或把执行位置显式指向目标主机。
涉及凭据的查找结果可能被写进执行输出与日志。敏感值先取到变量里,再在任务上关闭日志输出,避免口令出现在回显中。
组合顺序的经验
过滤器链的书写顺序就是求值顺序:先筛选再拼接,与先拼接再筛选得到的类型完全不同。稳妥的做法是把长链条拆成中间变量,每一步单独调试;涉及 IO 的查找尽量放在循环之外,先取一次到变量里复用,避免每次迭代都触发一次文件读取或命令执行。