重复使用 Ansible 工件

您可以将简单的剧本编写在一个非常大的文件中,大多数用户首先学习单文件方法。但是,将自动化工作分解成较小的文件是组织复杂的任务集并重复使用它们的极好方法。较小的、分布式的工件使您可以在多个剧本中重复使用相同的变量、任务和剧本以解决不同的用例。您可以在多个父剧本中使用分布式工件,甚至在一个剧本中多次使用。例如,您可能希望在几个不同的剧本中更新您的客户数据库。如果您将与更新数据库相关的任务都放在一个任务文件中或角色中,您可以在许多剧本中重复使用它们,而只需在一个地方维护它们。

创建可重用文件和角色

Ansible 提供四种分布式、可重用工件:变量文件、任务文件、剧本和角色。

  • 变量文件只包含变量。

  • 任务文件只包含任务。

  • 剧本至少包含一个剧本,并且可能包含变量、任务和其他内容。您可以重复使用高度集中的剧本,但您只能静态地重复使用它们,而不是动态地重复使用它们。

  • 角色包含一组相关的任务、变量、默认值、处理程序,甚至模块或其他插件,这些插件位于定义的文件树中。与变量文件、任务文件或剧本不同,角色可以通过 Ansible Galaxy 轻松上传和共享。有关创建和使用角色的详细信息,请参阅 角色

2.4 版新增功能。

重复使用剧本

您可以将多个剧本合并到一个主剧本中。但是,您只能使用导入来重复使用剧本。例如

- import_playbook: webservers.yml
- import_playbook: databases.yml

导入在其他剧本中静态地包含剧本。Ansible 按每个导入剧本中列出的顺序运行每个剧本和任务,就像它们直接在主剧本中定义一样。

您可以通过定义带有变量的导入剧本文件名,然后使用 --extra-varsvars 关键字传递变量,在运行时选择要导入的剧本。例如

- import_playbook: "/path/to/{{ import_from_extra_var }}"
- import_playbook: "{{ import_from_vars }}"
  vars:
    import_from_vars: /path/to/one_playbook.yml

如果您使用 ansible-playbook my_playbook -e import_from_extra_var=other_playbook.yml 运行此剧本,Ansible 将导入 one_playbook.yml 和 other_playbook.yml。

何时将剧本转换为角色

对于某些用例,简单的剧本效果很好。但是,从一定复杂程度开始,角色比剧本效果更好。角色允许您将默认值、处理程序、变量和任务存储在单独的目录中,而不是存储在一个长文档中。角色易于在 Ansible Galaxy 上共享。对于复杂的用例,大多数用户发现角色比一体化剧本更容易阅读、理解和维护。

重复使用文件和角色

Ansible 提供两种在剧本中重复使用文件和角色的方法:动态和静态。

任务包含和导入语句可以在任意深度使用。

您仍然可以在剧本级别使用裸 roles 关键字来静态地将角色合并到剧本中。但是,裸 include 关键字(曾用于任务文件和剧本级别包含)现在已弃用。

包含:动态重用

包含角色、任务或变量会将它们动态地添加到剧本中。Ansible 会按在剧本中遇到的顺序处理包含的文件和角色,因此包含的任务可能会受到顶级剧本中较早任务结果的影响。包含的角色和任务类似于处理程序 - 它们可能会运行也可能不会运行,具体取决于顶级剧本中其他任务的结果。

使用 include_* 语句的主要优点是循环。当使用循环包含时,包含的任务或角色将为循环中的每个项目执行一次。

包含角色、任务和变量的文件名在包含之前会被模板化。

您可以将变量传递给包含。有关变量继承和优先级的更多详细信息,请参阅 变量优先级:我应该将变量放在哪里?

导入:静态重用

导入角色、任务或剧本会将它们静态地添加到剧本中。Ansible 在运行剧本中任何任务之前预处理导入的文件和角色,因此导入的内容永远不会受到顶级剧本中其他任务的影响。

导入角色和任务的文件名支持模板化,但变量必须在 Ansible 预处理导入时可用。这可以使用 vars 关键字或使用 --extra-vars 来完成。

您可以将变量传递给导入。如果您想在一个剧本中多次运行导入的文件,您必须传递变量。例如

tasks:
- import_tasks: wordpress.yml
  vars:
    wp_user: timmy

- import_tasks: wordpress.yml
  vars:
    wp_user: alice

- import_tasks: wordpress.yml
  vars:
    wp_user: bob

有关变量继承和优先级的更多详细信息,请参阅 变量优先级:我应该将变量放在哪里?

比较包含和导入:动态和静态重用

每种重复使用分布式 Ansible 工件的方法都有优点和局限性。您可以选择对某些剧本使用动态重用,对其他剧本使用静态重用。尽管您可以在一个剧本中使用动态和静态重用,但最好为每个剧本选择一种方法。混合使用静态和动态重用可能会在您的剧本中引入难以诊断的错误。此表总结了主要区别,以便您为创建的每个剧本选择最佳方法。

Include_*

Import_*

重用类型

动态

静态

处理时间

运行时,遇到时

剧本解析时预处理

任务或剧本

所有包含都是任务

import_playbook 不能是任务

任务选项

仅适用于包含任务本身

适用于导入中所有子任务

从循环调用

为每个循环项目执行一次

不能在循环中使用

使用 --list-tags

包含中的标签未列出

所有标签都显示在 --list-tags

使用 --list-tasks

包含中的任务未列出

所有任务都显示在 --list-tasks

通知处理程序

不能触发包含中的处理程序

可以触发单独导入的处理程序

使用 --start-at-task

无法从包含文件中开始执行任务

可以从导入的任务开始执行

使用清单变量

可以使用 include_*: {{ inventory_var }}

无法使用 import_*: {{ inventory_var }}

使用剧本

没有 include_playbook

可以导入完整的剧本

使用变量文件

可以包含变量文件

使用 vars_files: 导入变量

注意

  • 在资源消耗和性能方面也存在很大差异,导入非常精简和快速,而包含需要大量的管理和计算。

将任务重新用作处理程序

您也可以在剧本的 处理程序:在更改时运行操作 部分使用包含和导入。例如,如果您想定义如何重启 Apache,您只需要在所有剧本中执行一次即可。您可能会创建一个名为 restarts.yml 的文件,内容如下:

# restarts.yml
- name: Restart apache
  ansible.builtin.service:
    name: apache
    state: restarted

- name: Restart mysql
  ansible.builtin.service:
    name: mysql
    state: restarted

您可以从导入或包含中触发处理程序,但两种重用方法的步骤不同。如果您包含文件,您必须通知包含文件本身,这将触发 restarts.yml 中的所有任务。如果您导入文件,您必须通知 restarts.yml 中的单个任务。您可以将直接任务和处理程序与包含或导入的任务和处理程序混合使用。

触发包含(动态)处理程序

包含在运行时执行,因此包含的名称在剧本执行期间存在,但包含的任务直到包含本身被触发才会存在。要使用 Restart apache 任务进行动态重用,请参考包含本身的名称。此方法会将包含文件中的所有任务触发为处理程序。例如,使用上面显示的任务文件

- name: Trigger an included (dynamic) handler
  hosts: localhost
  handlers:
    - name: Restart services
      include_tasks: restarts.yml
  tasks:
    - command: "true"
      notify: Restart services

触发导入(静态)处理程序

导入在剧本开始之前进行处理,因此导入的名称在剧本执行期间不再存在,但导入的单个任务的名称确实存在。要使用 Restart apache 任务进行静态重用,请参考导入文件中每个任务或任务的名称。例如,使用上面显示的任务文件

- name: Trigger an imported (static) handler
  hosts: localhost
  handlers:
    - name: Restart services
      import_tasks: restarts.yml
  tasks:
    - command: "true"
      notify: Restart apache
    - command: "true"
      notify: Restart mysql

另请参见

实用程序模块

此处讨论的 include*import* 模块的文档。

使用剧本

回顾剧本的基本语言特性

使用变量

关于剧本中变量的全部内容

条件

剧本中的条件

循环

剧本中的循环

一般提示

剧本的技巧和窍门

Galaxy 用户指南

如何在 Galaxy 上分享角色,角色管理

沟通

有问题吗?需要帮助吗?想分享你的想法吗?请访问 Ansible 沟通指南