Ansible 剧本与角色

Posted

技术标签:

【中文标题】Ansible 剧本与角色【英文标题】:Ansible Playbooks vs Roles 【发布时间】:2015-11-13 01:51:53 【问题描述】:

根据 Ansible 文档,Playbook 是:

...真正简单的配置管理和多机部署系统的基础,不同于现有的任何系统,并且非常适合部署复杂的应用程序。

同样,根据这些相同的文档,Role 是:

...基于已知文件结构自动加载某些 vars_files、任务和处理程序的方法。按角色对内容进行分组还可以轻松地与其他用户共享角色。

但是,这些及其不同用例之间的区别对我来说并不是很明显。例如,如果我将/etc/ansible/hosts 文件配置为:

[databases]
mydb01.example.org
mydb02.example.org

[mail_servers]
mymail01.example.org
mymail_dr.example.org

...那么这个“[databases]”条目是什么...一个角色?或者某个地方的剧本 YAML 文件的名称?还是别的什么?!?

如果有人可以向我解释这些差异,我对 Ansible 的理解将大大提高!

Playbook vs Role vs [databases] 以及/etc/ansible/hosts 中的类似条目 如果剧本是在 YAML 文件中定义的,那么角色是在哪里定义的? 除了位于 Ansible 服务器上的 ansible.cfg 之外,如何使用可用的 Playbook/角色添加/配置 Ansible?例如,当我运行 ansible-playbook someplaybook.yaml 时,Ansible 怎么知道在哪里可以找到该剧本?

【问题讨论】:

角色是一种使剧本中的代码可重用的方法,方法是将功能放入通用的“库”中,然后可以根据需要在任何剧本中使用。 tasks 做事。 playbooks 组织和启动任务。 roles 组织执行特定功能的任务、处理程序等。启动role(s) 需要一些playbookrolesplaybooks 的集合叫什么?例如,一个管理您站点上所有主机配置的主机? 简单有效的 Ansible 结构元素概览:devops.stackexchange.com/a/9833/17395 【参考方案1】:

Playbook vs Role vs [databases] 以及 /etc/ansible/hosts 中的类似条目

[databases] 是一组主机的单一名称。它允许您通过一个名称引用多个主机。

角色是一组任务和附加文件,用于配置主机以服务于某个角色

Playbook 是主机和角色之间的映射。

来自documentation 的示例描述了示例项目。它包含两件事:

剧本。 site.ymlwebservers.ymlfooservers.yml 是剧本。 角色:roles/common/roles/webservers/ 包含相应的 commonwebservers 角色的定义。

在剧本 (webservers.yml) 中,您有类似的内容:

---
- hosts: webservers <- this group of hosts defined in /etc/ansible/hosts, databases and mail_servers in example from your question
  roles: <- this is list of roles to assign to these hosts
     - common
     - webservers

如果剧本是在 YAML 文件中定义的,那么角色是在哪里定义的?

它们在roles/* 目录中定义。角色主要使用 YAML 文件定义,但也可以包含任何类型的资源(files/templates/)。根据documentation,角色定义的结构是这样的:

如果 roles/x/tasks/main.yml 存在,其中列出的任务将被添加到 play 中 如果 roles/x/handlers/main.yml 存在,则其中列出的处理程序将被添加到 play 中 如果 roles/x/vars/main.yml 存在,其中列出的变量将被添加到 play 中 如果角色/x/meta/main.yml 存在,则其中列出的任何角色依赖项都将添加到角色列表(1.3 及更高版本)中 任何复制任务都可以引用 roles/x/files/ 中的文件,而无需相对或绝对路径 任何脚本任务都可以引用 roles/x/files/ 中的脚本,而无需相对或绝对路径 任何模板任务都可以引用 roles/x/templates/ 中的文件,而无需相对或绝对路径 任何包含任务都可以引用 roles/x/tasks/ 中的文件,而无需相对或绝对路径

最重要的文件是roles/x/tasks/main.yml,这里定义任务,当角色执行时会执行。

除了 Ansible 服务器上的 ansible.cfg 之外,如何使用可用的 Playbook/角色添加/配置 Ansible?例如,当我运行 ansible-playbook someplaybook.yaml 时,Ansible 怎么知道在哪里可以找到该 playbook?

$ ansible-playbook someplaybook.yaml

将在当前目录中查找剧本。

$ ansible-playbook somedir/somedir/someplaybook.yaml

将在somedir/somedir/ 目录中查找剧本。

您有责任将包含所有剧本和角色的项目放在服务器上。 Ansible 与此无关。

【讨论】:

感谢@Yaroslav Admin (+1) - 一个快速的后续问题:您声明角色是在 directories 中定义的,但实际上是什么设置了角色?换句话说,webservers.yml playbook 将[webservers] 主机映射到commonwebservers 角色。但是common 角色究竟包含了什么?没有办法在目录中定义它,那么这些“角色目录”中通常有 YAML 文件吗?再次感谢! @smeeb 是的,你说得对,角色是由该目录中的文件定义的。它们主要是 YAML,但也可以包含其他类型的文件。有关详细信息,请参阅更新的答案。 好的。这应该在 ansible 的文档中,就在他们解释其原理和词汇的地方。我已经多次阅读他们的入门指南,但无法理解剧本和角色如何不同和相互作用。有了你的解释,我第一次尝试!【参考方案2】:

Playbook vs Role vs [databases] 以及 /etc/ansible/hosts 中的类似条目

角色是一种将任务组合到一个容器中的方法。你可以有一个角色来设置 mysql,另一个角色来设置 Postfix 等等。

剧本定义发生了什么地点。这是您定义主机(主机组,见下文)和将应用于这些主机的角色的地方。

[databases] 和清单中的其他条目是主机组。主机组定义了一组游戏将在其上运行的主机。

剧本是剧本中的一组任务或角色(或两者兼有)。在大多数情况下(和示例),剧本将只包含一个剧本。但是你可以拥有任意数量的。这意味着您可以拥有一个剧本,它将在主机组mail_servers 上运行角色postfix,在主机组databases 上运行角色mysql

- hosts: mail_servers
  roles:
    - postfix

- hosts: databases
  roles:
    - mysql

如果剧本是在 YAML 文件中定义的,那么角色是在哪里定义的?

在 Ansible 中,几乎所有内容都在 YAML 中定义,这对于角色和剧本都很重要。

除了 Ansible 服务器上的 ansible.cfg 之外,如何使用可用的 Playbook/角色添加/配置 Ansible?例如,当我运行 ansible-playbook someplaybook.yaml 时,Ansible 怎么知道在哪里可以找到该 playbook?

AFAIK 在调用 ansible-playbook 时,您必须提供 playbook 的路径。所以ansible-playbook someplaybook.yaml 会期望someplaybook.yaml 在你的当前目录中。但您可以提供完整路径:ansible-playbook /path/to/someplaybook.yaml

【讨论】:

【参考方案3】:

这是一个术语/语义问题。即使有基线定义,它也可能是主观的。

我的看法如下:

任何配置管理/部署系统都有:

    source data - 用于创建目标主机配置的数据 target data - 用于识别目标主机的数据 config changes - 我们使用source data 在基于target data 的目标主机上应用的规则/操作的列表/集

在 Ansible 中:

    source data - 是我们可以放数据的各个地方 - group_varsplaybook vars、role vars 等,这些地方影响优先级(如果同名变量在不同位置重新定义,则是在ansible/ansible-playbook 执行期间变量值的非常具体的规则 target data - 是清单(而且,还可以在清单中定义清单/主机组变量!) config changes - ansible 有 4 个抽象级别:
      任务 - 单个操作 任务列表 - 操作列表 角色 - 按同一“主题”分组的操作列表(或列表列表),通常所有目标都在同一主机/主机组上运行 剧本 - 剧本列表,每个剧本都在可能不同的主机组上运行,应用多个 roles/tasks/tasklists(以及像 handlers 这样的特殊任务)

从“软件”方面 - 角色应该足够通用以重用

在一些(相当大的)组织中,“角色”由 A 组提供,而在 B 组维护的剧本中使用。

总结

以上所有内容都允许将类似的配置分组 - 成一个role。 将相关子系统/组件组合成一个playbook。 此外,值得一提的是,剧本中的 1 个 YAML 项目(包括 hosts:taskspre_taskspost_tasksroles)称为 play

现在回答你的问题:

是的,一开始很混乱。

您通常将您的source data 连接到您角色的语义,所以当您看到角色setup_db 被应用到相关主机组上时(例如db_hosts) 但是play 可以在多个主机组的联合上运行。 这只是约定与灵活性的问题。

附言

请给我回信,这是否增加了混乱或澄清。 谢谢。

【讨论】:

【参考方案4】:

简单地说:

剧本就像主程序,它包含完成工作的完整指令。但是,对于大型项目,实际上并不希望将每个细节都放入其中。所以你需要角色。

角色是一个子程序,通常实现一个目标,例如。设置数据库服务器。您可以将其放在roles/ 目录中,或者通过在rolesfile.yml 中提供URI 并让ansible-galaxy 为您下载它们来下载第3 方角色。

[database] 是在库存文件 中定义的主机组,列出了属于database 组的主机。您还可以通过指定类似的内容来指定一组 Web 服务器

[web]
web1.example.com
web2.example.com

webdatabase 然后可用于剧本或角色以指定要应用的主机。

这些组也可以在命令ansible 中用于运行临时命令。

【讨论】:

【参考方案5】:

另外请记住,如果使用旨在影响不同角色的元文件,则剧本可以调用多个角色。

示例剧本:dual_role-playbook.yml

- name: Some Action for two roles
  hosts: localhost

  vars_files:
    - roles/dual_role/meta/main.yml

  roles:
    - dual_role/container-1
    - dual_role/container-2

角色文件夹和文件方案如下所示:

dual_role-playbook.yml
  -- roles
     -- dual_role
        -- meta/main.yml
        -- container-1
           -- tasks/main.yml
           -- templates/template.j2
        -- container-2
           -- tasks/main.yml
           -- templates/template.j2

【讨论】:

以上是关于Ansible 剧本与角色的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用Ansible创建一个在运行每个角色之前提示的剧本?

[ansible]-ansible-剧本

如何控制Ansible Playbook的执行顺序运行选定的剧本资源

如何控制Ansible Playbook的执行顺序运行选定的剧本资源

ansible playbook剧本

ansible playbook剧本