本地添加模块和插件

您可以通过添加自定义模块或插件来扩展 Ansible。您可以从零开始创建它们,或者复制现有的模块或插件以供本地使用。您可以将本地模块或插件存储在 Ansible 控制节点上,并与您的团队或组织共享。您还可以通过将插件和模块包含在集合(collection)中,然后将集合发布到 Ansible Galaxy 来共享它们。

如果您正在使用本地模块或插件但 Ansible 无法找到它,那么本页面提供了您所需的所有信息。

如果您想创建插件或模块,请参阅 开发插件开发模块开发集合

通过本地模块和插件扩展 Ansible 具有以下优势:

  • 您可以复制其他人的模块和插件。

  • 编写新模块时,您可以选择任何您喜欢的编程语言。

  • 无需克隆任何仓库。

  • 无需发起拉取请求 (Pull Request)。

  • 无需添加测试(尽管我们建议您这样做!)。

模块和插件:有什么区别?

如果您想为 Ansible 添加功能,您可能会纠结是需要模块还是插件。以下是帮助您理解需求的简要概述:

  • 插件 扩展了 Ansible 的核心功能。大多数类型的插件在控制节点的 /usr/bin/ansible 进程内执行。插件为 Ansible 的核心功能提供了选项和扩展:转换数据、记录输出、连接到资产清单(inventory)等。

  • 模块是一种插件,它在“目标”(通常是远程系统)上执行自动化任务。模块作为独立脚本运行,Ansible 在控制节点之外的独立进程中执行它们。模块主要通过 JSON 与 Ansible 进行交互,接受参数并在退出前通过向 stdout 打印 JSON 字符串来返回信息。与必须使用 Python 编写的其他插件不同,模块可以使用任何语言编写;尽管 Ansible 仅原生提供 Python 和 PowerShell 格式的模块。

在集合中添加模块和插件

您可以通过 创建集合 来添加模块和插件。通过集合,您可以在任何 Playbook 或角色中使用自定义模块和插件。您可以随时通过 Ansible Galaxy 轻松共享您的集合。

本页面的其余部分介绍了使用本地独立模块或插件的其他方法。

在集合之外添加模块或插件

您可以配置 Ansible,使其在特定位置加载独立的本地模块或插件,并使其对所有 Playbook 和角色可用(使用已配置的路径)。或者,您可以使非集合的本地模块或插件仅对特定的 Playbook 或角色可用(使用相邻路径)。

为所有 Playbook 和角色添加独立本地模块

要自动加载独立本地模块并使其对所有 Playbook 和角色可用,请使用 DEFAULT_MODULE_PATH 配置设置或 ANSIBLE_LIBRARY 环境变量。该配置设置和环境变量接受以冒号分隔的列表,类似于 $PATH。您有两种选择:

  • 将您的独立本地模块添加到默认配置的位置之一。详情请参阅 DEFAULT_MODULE_PATH 配置设置。默认位置可能会在不另行通知的情况下更改。

  • 将独立本地模块的位置添加到环境变量或配置中:

要查看当前的模块配置设置:

ansible-config dump |grep DEFAULT_MODULE_PATH

将模块文件保存在这些位置之一后,Ansible 会加载它,您就可以在任何本地任务、Playbook 或角色中使用它。

确认 my_local_module 可用的方法:

  • 输入 ansible localhost -m my_local_module 查看该模块的输出,或者

  • 输入 ansible-doc -t module my_local_module 查看该模块的文档。

注意

这适用于所有插件类型,但需要针对每种插件类型进行特定的配置和/或相邻目录设置,详见下文。

注意

ansible-doc 命令可以解析用 Python 编写或带有相邻 YAML 文件的模块文档。如果您编写的模块使用的编程语言不是 Python,则应在模块文件旁边的 Python 或 YAML 文件中编写文档。相邻的 YAML 文档文件

为选定的 Playbook 或单个角色添加独立本地模块

Ansible 会自动从 Playbook 或角色相邻的特定目录中加载所有可执行文件作为模块。这些位置的独立模块仅对父目录中的特定 Playbook 或角色可用。

  • 要仅在选定的 Playbook 中使用独立模块,请将该模块存储在包含 Playbook 的目录下的 library 子目录中。

  • 要仅在单个角色中使用独立模块,请将该模块存储在该角色内的 library 子目录中。

注意

这适用于所有插件类型,但需要针对每种插件类型进行特定的配置和/或相邻目录设置,详见下文。

警告

包含在集合中的角色不能包含任何模块或其他插件。集合中的所有插件必须位于集合的 plugins 目录树中。该目录树中的所有插件对于集合中的所有角色都是可用的。如果您正在开发新模块,我们建议将其发布在 集合 中,而不是在角色中。

在集合之外本地添加非模块插件

您可以配置 Ansible,使其在指定位置加载独立本地插件,并使其对所有 Playbook 和角色可用。或者,您可以使独立本地插件仅对特定 Playbook 或角色可用。

注意

尽管模块也是插件,但适用于其他插件类型的目录名和环境变量命名模式不适用于模块。请参阅 在集合之外添加模块或插件

为所有 Playbook 和角色添加本地非模块插件

要自动加载独立本地插件并使其对所有 Playbook 和角色可用,请使用您要添加的插件类型的配置设置或环境变量。这些配置设置和环境变量接受以冒号分隔的列表,类似于 $PATH。您有两种选择:

  • 将您的本地插件添加到默认配置的位置之一。有关该插件类型正确配置设置的详细信息,请参阅 配置设置。默认位置可能会在不另行通知的情况下更改。

  • 将本地插件的位置添加到环境变量或配置中:
    • 相关的 ANSIBLE_plugin_type_PLUGINS 环境变量,例如 $ANSIBLE_INVENTORY_PLUGINS$ANSIBLE_VARS_PLUGINS

    • 相关的 plugin_type_PATH 配置设置,其中大多数以 DEFAULT_ 开头,例如 DEFAULT_CALLBACK_PLUGIN_PATHDEFAULT_FILTER_PLUGIN_PATHBECOME_PLUGIN_PATH

要查看当前的非模块插件配置设置:

ansible-config dump |grep plugin_type_PATH

将插件文件添加到这些位置之一后,Ansible 会加载它,您就可以在任何本地模块、任务、Playbook 或角色中使用它。有关环境变量和配置设置的更多信息,请参阅 Ansible 配置设置

确认 plugins/plugin_type/my_local_plugin 可用的方法:

  • 输入 ansible-doc -t <plugin_type> my_local_lookup_plugin 查看该插件的文档,例如 ansible-doc -t lookup my_local_lookup_plugin

ansible-doc 命令适用于大多数插件类型,但不支持动作(action)、过滤(filter)或测试(test)插件。有关更多详细信息,请参阅 ansible-doc

为选定的 Playbook 或单个角色添加独立本地插件

Ansible 会自动从 Playbook 或角色相邻的特定目录中加载所有插件,并按插件类型分别从以该类型命名的目录中加载。这些位置的独立插件仅对父目录中的特定 Playbook 或角色可用。

  • 要仅在选定的 Playbook 中使用独立插件,请将插件存储在包含 Playbook 的目录下对应的 plugin_type 子目录中(例如 callback_pluginsinventory_plugins)。这些目录必须使用 _plugins 后缀。有关插件类型的完整列表,请参阅 使用插件

  • 要仅在单个角色中使用独立插件,请将插件存储在该角色内对应的 plugin_type 子目录中(例如 cache_pluginsstrategy_plugins)。当作为角色的一部分分发时,该插件在角色执行时即可使用。这些目录必须使用 _plugins 后缀。有关插件类型的完整列表,请参阅 使用插件

警告

包含在集合中的角色不能包含任何插件。集合中的所有插件必须位于集合的 plugins 目录树中。该目录树中的所有插件对于集合中的所有角色都是可用的。如果您正在开发新插件,我们建议将其发布在 集合 中,而不是在角色中。

警告

某些插件类型在 Ansible 执行初期就需要,例如回调(callbacks)、资产清单(inventory)和缓存(cache)。这些插件类型无法动态加载,必须存在于已配置的路径中,或者在配置中通过 FQCN(完全限定集合名称)引用。

使用 ansible.legacy 访问 ansible.builtin 模块的自定义版本

如果您需要覆盖某个 ansible.builtin 模块并正在使用 FQCN,则需要将 ansible.legacy 作为完全限定集合名称 (FQCN) 的一部分使用。例如,如果您有自己的 copy 模块,则可以通过 ansible.legacy.copy 访问它。有关如何在基于集合的角色中使用自定义模块的详细信息,请参阅 使用 ansible.legacy 访问基于集合角色中的本地自定义模块