
ansible 的 filter plugin 不支持直接导入同目录下的普通 python 模块,需通过自定义 collection 结构,将共享逻辑放入 module_utils 目录,再以标准命名空间方式导入,从而实现跨 filter 的代码复用。
在 Ansible 中,filter plugin 本质上是被动态加载的 Python 模块,其加载机制严格限定于 filter_plugins/ 目录下的合法插件文件(即必须含 FilterModule 类且实现 filters() 方法)。因此,将工具函数放在同一目录下的 tools.py 中并尝试 import tools 是无效的——Ansible 会将其误判为待加载的插件(触发 FilterModule 属性缺失警告),而 Python 解释器也无法通过常规路径解析该模块。
官方明确不支持 filter_plugins/ 内部模块互导,也未提供类似 module_utils 对 filter 的原生支持(该机制仅适用于 modules/)。但幸运的是,Ansible Collections 提供了标准化、可复用、且被完整支持的替代方案:将 filter plugin 与共享工具代码共同组织为一个本地 collection,并利用 collection 内部的 plugins/module_utils/ 目录存放可导入的工具模块。
✅ 正确实践结构如下(以 larsks.myplugins 为例):
./
├── playbook.yaml
└── collections/
└── ansible_collections/
└── larsks/
└── myplugins/
└── plugins/
├── filter/
│ └── myfilter.py # 实际 filter 插件
└── module_utils/
└── tools.py # 共享工具函数(含 __init__.py 可选)其中 collections/ansible_collections/larsks/myplugins/plugins/module_utils/tools.py 内容示例:
# tools.py
def shared_function(data_to_process):
"""通用数据处理逻辑,可在多个 filter 中复用"""
return data_to_process.strip().replace(" ", "_").lower()对应 filter 插件 myfilter.py:
# myfilter.py
from ansible_collections.larsks.myplugins.plugins.module_utils.tools import shared_function
class FilterModule:
def filters(self):
return {
'normalize': lambda s: shared_function(s),
'prefix_upper': lambda s: f"PREFIX_{shared_function(s).upper()}"
}在 playbook 中使用时,需带上 collection 命名空间:
- hosts: localhost
gather_facts: false
tasks:
- debug:
msg: "{{ 'Hello World' | larsks.myplugins.normalize }}"
- debug:
msg: "{{ 'Test Data' | larsks.myplugins.prefix_upper }}"⚠️ 注意事项:
- collections/ 目录必须与 playbook 文件同级,且路径必须严格为 collections/ansible_collections/{namespace}/{collection_name}/...;
- module_utils/ 下的模块无需 __init__.py(Ansible 2.10+ 自动识别),但添加空 __init__.py 也不影响;
- 所有导入语句必须使用完整 collection 命名空间路径(ansible_collections.{ns}.{coll}.plugins.module_utils.xxx),不可简写;
- 本地 collection 无需发布或安装,Ansible 运行时自动发现并加载;
- 若需多 filter 复用,可将 tools.py 拆分为多个模块(如 string_utils.py, json_utils.py),保持高内聚低耦合。
该方案符合 Ansible 最佳实践,具备可移植性、可测试性与团队协作友好性,是解决 filter 插件代码复用问题的唯一推荐路径。










