介绍

虽然可以在一个非常大的文件中编写一个playbook(您可能会以这种方式开始学习playbook),但最终您将需要重新使用文件并开始组织事情。

在基本级别,饱含任务的文件允许您将配置策略分解成较小的文件。 任务包括从其他文件中拉入任务。 由于处理程序也是任务,您还可以从“handler”部分中include处理程序文件。

如果您需要查看这些概念,请参阅“ Playbooks”

Playbook还可以包括其他Playbook文件的plays。 当这样做完成时,plays将被插入到Playbook中以形成更长的plays列表。

当你开始思考任务,处理程序,变量等等 - 开始形成更大的概念。 你开始思考建模是什么,而不是如何让东西看起来像什么。 这不再是“这几个主机应用这些主机”,你说“这些主机是dbservers”或“这些主机是web服务器”。 在编程中,我们可以称之为“封装”事情的工作。 例如,您可以驾驶汽车而不知道发动机是如何工作的。

Ansible的角色建立在include文件的想法上,并将它们组合起来形成干净,可重复使用的抽象 - 它们允许您更多地关注大局,只有在需要时才能深入细节。

我们从理解的角度开始,所以角色变得更有意义,但是我们的最终目标应该是理解角色 - 角色很好,每次写剧本时都应该使用它们。

请参阅GitHub上的ansible-examples存储库,了解所有这些的一些示例。 您可能希望在您潜入时在单独的标签中打开此页面。

Task versus Play includes

task和play都使用include关键字,但是以不同的方式实现关键字。 它们之间的区别取决于他们的位置和内容。 如果include在一个play中,它只能是一个“task” include,include一个任务列表; 如果是顶级,它只能include plays。 例如:

# this is a 'play' include
- include: intro_example.yml - name: another play
hosts: all
tasks:
- debug: msg=hello # this is a 'task' include
- include: stuff.yml “task” include 可以出现在任务可以的任何地方,但是“play” include 不能在其他play中,只能在同一层次上。 虽然“task”include可以采取其他参数并且让被包含的​​任务继承它们,但是“play”include非常有限,并且大多数指令不起作用。

Task Include Files And Encouraging Reuse

假设您想在play或playbook中重复使用任务列表。 您可以使用include文件来执行此操作。 使用include的任务列表是定义系统将要实现的角色的好方法。 请记住,playbook中play的目标是将一组系统映射到多个角色。 让我们看看这是什么样子

一个task include 文件只包含一个平面的任务列表,如下所示:

---

# possibly saved as tasks/foo.yml

- name: placeholder foo

command: /bin/foo

- name: placeholder bar

command: /bin/bar

include指令看起来像这样,并且可以混合在一个playbook中的常规任务:

tasks:

  - include: tasks/foo.yml
您也可以将变量传递给include。 我们称之为“参数化include”。
例如,要部署到多个wordpress实例,我可以将所有我的wordpress任务封装在一个wordpress.yml文件中,并使用如下所示:
tasks:
- include: wordpress.yml wp_user=timmy
- include: wordpress.yml wp_user=alice
- include: wordpress.yml wp_user=bob 从1.0开始,变量也可以使用替代语法传递到包含文件,这也支持结构化变量:
tasks:

  - include: wordpress.yml
vars:
wp_user: timmy
ssh_keys:
- keys/one.txt
- keys/two.txt 使用任何一种语法,然后可以在包含的文件中使用传入的变量。 我们将在变量中介绍它们。 你可以这样引用它们:
  {{ wp_user }}
(除了明确传递的参数之外,vars部分中的所有变量也可以在这里使用。) include也可以在'handler'部分使用,例如,如果你想定义如何重新启动apache,你对所有的Playbook只做一次。 你可能会制作一个看似如下的handlers.yml:
---
# this might be in a file like handlers/handlers.yml
- name: restart apache
service: name=apache state=restarted 而在你的main Playbook文件中,只要把它include进来,放到play的底部:
handlers:
- include: handlers/handlers.yml 您可以将include与您的常规未包含的task和handler一起混合。

include也可用于将一个play文件导入另一个。 这允许您定义由其他playbook组成更高级的playbook。

例如:

- name: this is a play at the top level of a file
hosts: all
remote_user: root tasks: - name: say hi
tags: foo
shell: echo "hi..." - include: load_balancers.yml
- include: webservers.yml
- include: dbservers.yml 注意,当在一个playbook中include另一个时,不能进行变量替换。

Dynamic versus Static Includes

在“Ansible2.0”中,对“task” include 的内容进行了修改。 “play” include 仍然是“static”或不变。

在以前的Ansible版本中,所有的内容都作为预处理器声明,并在Playbook解析时被读取。 这样就会在包含的文件名中使用诸如库存变量(如分组和主机变量,在分析时间内不可用)等问题。

在Ansible 2.0之后,'task'include可以是'动态',这意味着在播放执行过程中到达include任务之前,它们不被评估。 此更改允许在include语句中重新引入循环,例如:

  - include : foo.yml param = {{ item }}
with_items :
- 1
- 2
- 3

也可以使用动态包含的任何源的变量:

- include: "{{inventory_hostname}}.yml"

从2.1开始,Ansible尝试检测“task” include何时应该是动态的(请看下面的详细信息,了解检测如何工作)。 动态include引入了一些其他限制,因为在play执行期间到达该任务之前,不会读入include的文件。 使用动态include时,请牢记以下限制:
  • 您不能使用notify来触发来自动态include的处理程序名称。
  • 您不能使用--start-at-task在动态include内的--start-at-task中开始执行。
  • 仅存在于动态include中的标签将不会显示在列表标签​​输出中。
  • 仅在动态include中存在的任务不会显示在-list-tasks输出中。

为了解决这些限制,Ansible 2.1引入了include的static选项:

- include: foo.yml
static: <yes|no|true|false> 默认情况下,从Ansible 2.1开始,当include满足以下条件时,“task”include自动被视为静态而不是动态的
  • include不使用任何循环
  • include的文件名不使用任何变量
  • static选项没有明确禁用( static: no不存在)
  • 强制静态include的ansible.cfg选项(见下文)被禁用

ansible.cfg配置中有两个选项可用于静态include:

  • task_includes_static - 强制所有include的任务部分都是静态的。
  • handler_includes_static - 强制所有include的处理程序部分都是静态的。

这些选项允许用户强制Playbook的行为与1.9.x和之前完全一样。

“静态”vs“动态”行为如何影响您的任务的一个例子:

- include: "stuff.yml"
static: no
when: verto is defined 如果这个任务是“静态的”,那么什么时候被包含的任务所继承,但是强制它是动态的,那么现在什么时候应用于包含任务本身。

Roles

New in version 1.2.

现在你已经了解了任务和处理程序,组织你的剧本的最好方式是什么? 简单的答案是使用角色! 角色是基于已知文件结构自动加载某些vars_files,任务和处理程序的方法。 按角色分组内容还可以轻松地与其他用户共享角色。

角色只是围绕'include'指令自动化,如上所述,除了对引用文件的搜索路径处理进行一些改进之外,真的不包含太多额外的魔法。 但是,这可以是一件大事!

示例项目结构:

site.yml
webservers.yml
fooservers.yml
roles/
common/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
webservers/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/ 在一个playbook中,它将如下所示:
---
- hosts: webservers
roles:
- common
- webservers 这为每个角色“x”指定了以下行为:
  • 如果roles/ x / tasks / main.yml存在,其中列出的任务将添加到play中
  • 如果roles/ x /处理程序/ main.yml存在,列出的处理程序将被添加到play中
  • 如果roles/ x / vars / main.yml存在,其中列出的变量将被添加到play中
  • 如果roles / x / defaults / main.yml存在,其中列出的变量将被添加到play中
  • 如果roles / x / meta / main.yml存在,其中列出的任何角色依赖将被添加到角色列表(1.3和更高版本)
  • 任何副本,脚本,模板或包含任务(在角色中)都可以引用roles/ x / {文件,模板,任务} /(目录取决于任务)中的文件,而不必相对或绝对地路径

在Ansys 1.4及更高版本中,您可以配置一个roles_path来搜索角色。 使用它来检查所有常见角色到一个位置,并在多个playbook项目之间轻松分享它们。 有关如何在ansible.cfg中进行设置的详细信息,请参阅配置文件

如果任何文件不存在,它们将被忽略。 例如,一个没有'vars /'子目录的角色是可以的。

请注意,您仍然可以在不使用角色的情况下将任务,vars_files和处理程序“松散”列入剧本,但角色是一个很好的组织功能,并被强烈推荐。 如果剧本中有松散的东西,首先评估角色。

此外,如果您希望参数化角色,通过添加变量,您可以这样做:

---

- hosts: webservers
roles:
- common
- { role: foo_app_instance, dir: '/opt/a', app_port: 5000 }
- { role: foo_app_instance, dir: '/opt/b', app_port: 5001 } 虽然这可能不是您经常应该做的事情,但您也可以有条件地使用如下角色:
---

- hosts: webservers
roles:
- { role: some_role, when: "ansible_os_family == 'RedHat'" } 这通过将条件应用于角色中的每个任务来起作用。 条件稍后将在文档中介绍。
最后,您可能希望为您指定的角色分配标签。 你可以这样内联:
---

- hosts: webservers
roles:
- { role: foo, tags: ["bar", "baz"] } 请注意,此标记将使用指定的标记标记该角色中的所有任务 ,覆盖角色中指定的任何标记。 如果您发现自己构建了许多标签的角色,并且希望在不同时间调用角色的子集,那么您应该考虑将该角色分解为多个角色。
如果play仍然有“task”部分,这些任务在应用角色后执行。

如果要在应用角色之后定义某些任务发生在AND之前,您可以执行以下操作:

---

- hosts: webservers

  pre_tasks:
- shell: echo 'hello' roles:
- { role: some_role } tasks:
- shell: echo 'still busy' post_tasks:
- shell: echo 'goodbye'

Role Default Variables

1.3版新功能

角色默认变量允许您为include或依赖的角色设置默认变量(见下文)。 要创建默认值,只需在您的角色目录中添加一个defaults / main.yml文件。

这些变量将具有可用的任何变量的最低优先级,并且可以容易地被任何其他变量覆盖,包括库存变量。

Role Dependencies

1.3版新功能

角色相关性允许您在使用角色时自动拉入其他角色。 角色依赖关系存储在包含在角色目录中的meta / main.yml文件中。 此文件应包含要在指定角色之前插入的角色和参数列表,例如role / myapp / meta / main.yml中的以下内容

---
dependencies:
- { role: common, some_parameter: 3 }
- { role: apache, apache_port: 80 }
- { role: postgres, dbname: blarg, other_parameter: 12 } 角色依赖也可以指定为完整路径,就像顶级角色一样:
---
dependencies:
- { role: '/path/to/common/roles/foo', x: 1 } 角色依赖关系还可以从源代码控制repos或tar文件(通过galaxy )使用逗号分隔格式的路径,可选版本(标签,提交,分支等)和可选的友好角色名称(尝试导出角色名称从repo名称或归档文件名)。 通过命令行或通过require.yml传递给ansible-galaxy。
角色依赖性始终在包含它们的角色之前执行,并且是递归的。 默认情况下,角色也只能作为依赖关系添加一次 - 如果另一个角色也将其列为依赖关系,则不会再次运行。 可以通过向meta / main.yml文件添加allow_duplicates :yes来覆盖此行为。
例如,名为“car”的角色可以向其依赖关系添加名为“wheel”的角色,如下所示:
---
dependencies:
- { role: wheel, n: 1 }
- { role: wheel, n: 2 }
- { role: wheel, n: 3 }
- { role: wheel, n: 4 } 而用于wheel的meta / main.yml包含以下内容:
---
allow_duplicates: yes
dependencies:
- { role: tire }
- { role: brake } 所产生的执行顺序如下:
tire(n=1)
brake(n=1)
wheel(n=1)
tire(n=2)
brake(n=2)
wheel(n=2)
...
car

Embedding Modules and Plugins In Roles

这是一个与大多数用户不相关的高级主题。

这是一个与大多数用户不相关的高级主题。

如果您编写自定义模块(请参阅开发模块 )或插件(请参阅开发插件 ),则可能希望将其作为角色的一部分进行分发。 一般来说,Ansible作为一个项目非常有兴趣将高质量的模块引入到可插拔的核心中,所以这不应该是规范,但很容易做到。

一个很好的例子是,如果您在一家名为AcmeWidgets的公司工作,并写了一个内部模块,帮助您配置内部软件,并希望组织中的其他人轻松使用此模块,但您不想告诉大家如何配置其可执行库路径。

除了角色的“任务”和“处理程序”结构之外,还添加一个名为“library”的目录。 在这个'库'目录中,直接在其中包含模块。

假设你有这个:

roles/
my_custom_modules/
library/
module1
module2 该模块将可用于角色本身以及此角色之后调用的任何角色,如下所示:
- hosts: webservers
roles:
- my_custom_modules
- some_other_role_using_my_custom_modules
- yet_another_role_using_my_custom_modules 在某些限制下,还可以使用Ansible核心分发中的模块进行修改,例如在生产版本发布之前使用模块的开发版本。 然而,这并不总是可取的,因为API签名可能在核心组件中发生变化,但并不总是保证工作。 对于核心模块来说,它可以是一个方便的补丁,但是如果你有这个好的理由。 自然,该项目倾向于通过拉动请求将贡献引导回github。

可以使用相同的机制将插件嵌入和分配到角色中,并使用相同的模式。 例如,对于过滤器插件:

roles/
my_custom_filter/
filter_plugins
filter1
filter2
然后可以在模板或jinja模板中使用任何角色“my_custom_filter”
 
 
 
 
 
 

 

Ansible Playbook Roles and Include Statements的更多相关文章

  1. ansible使用4-Playbook Roles and Include Statements

    task include --- # possibly saved as tasks/foo.yml - name: placeholder foo command: /bin/foo - name: ...

  2. Ansible playbook roles

    1  概述 角色(roles):如果我们使用playbook写成一个文件,这个文件会很大,但是不方便组织,我们可以分组,把playbook根据功能,如handler,tasks等分门别类的放在在各自的 ...

  3. Playbook 角色(Roles) 和 Include 语句

    简介 当我们刚开始学习运用 playbook 时,可能会把 playbook 写成一个很大的文件,到后来可能你会希望这些文件是可以方便去重用的,所以需要重新去组织这些文件. Include 语句 基本 ...

  4. ansible playbook最佳实践

    本篇主要是根据官方翻译而来,从而使简单的翻译,并没有相关的实验步骤,以后文章会补充为实验步骤,此篇主要是相关理论的说明,可以称之为中文手册之一,具体内容如下: Ansible playbooks最佳实 ...

  5. Git+Gitlab+Ansible的roles实现一键部署Nginx静态网站(一)--技术流ken

    前言 截止目前已经写了<Ansible基础认识及安装使用详解(一)--技术流ken>,<Ansible常用模块介绍及使用(二)--技术流ken><Ansible剧本介绍及 ...

  6. ansible playbook模式及语法

    一.什么是playbook及其组成 什么是playbook playbook 翻译过来就是"剧本" playbook的组成 play:定义的是主机的角色 task:定义的是具体执行 ...

  7. Ansible之roles角色

    一.roles简介 ansible自1.2版本引入的新特性,用于层次性.结构化地组织playbook.roles能够根据层次型结构自动装载变量文件.tasks以及handlers等.要使用roles只 ...

  8. Git+Gitlab+Ansible的roles实现一键部署Nginx静态网站(4)

    前言 截止目前已经写了<Ansible基础认识及安装使用详解(一)–技术流ken>,<Ansible常用模块介绍及使用(二)–技术流ken><Ansible剧本介绍及使用 ...

  9. 014.Ansible Playbook Role 及调试

    一 role 简介 在ansible中,role是将playbook分割为多个文件的主要机制,大大简化了复杂的playbook的编写,同时已与复用 role各个目录的作用及可用文件 files:存放由 ...

随机推荐

  1. sql存储过程输出

    1.存储过程写法 create procedure [dbo].[Y_GetICBillNo] @IsSave smallint, @FBillType int, @BillID VARCHAR (5 ...

  2. VMware 安装Windows sever 2008 R2服务器

    一. 安装包下载: Windows Server 2008 R2 简体中文企业版[server 2008 r2下载] 二. 新建虚拟机 三. 安装Window Server 2008 R2 四. 服务 ...

  3. 1012 The Best Rank (25 分)

    1012 The Best Rank (25 分) To evaluate the performance of our first year CS majored students, we cons ...

  4. 牛逼的lsof命令!!!

    linux lsof命令详解 简介 lsof(list open files)是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访 ...

  5. sklearn的BaseEstimator、transformerMixin、ClassifierMixin、RegressorMixin、ClusterMixin介绍

    class sklearn.base.BaseEstimator:为所有的estimators提供基类 方法: __init__() 初始化方法 get_params(deep=True) 获取这个估 ...

  6. Spring MVC 底层原理

    参考博客:http://www.cnblogs.com/xiaoxi/p/6164383.html Spring MVC处理的流程: 具体执行步骤如下: 1 首先用户发送请求给前端控制器,前端控制器根 ...

  7. hint之qb_name

    http://www.thinkindata.com/?p=34 该hint用于子查询(query_block)   很多的情况下,如果子查询共用相同的别名(alias), 可以通过设定不同的qb_n ...

  8. Django中间件执行流程

    中间件函数是 django 框架为我们预留的函数接口, 让我们可以干预请求和应答的过程 1. 获取浏览器端的IP地址: 使用 request.META[‘REMOTE_ADDR’] 2. 使用中间件 ...

  9. 搭建Hive 2.1.1 基于Hadoop 2.6.1 和 Ubuntu 16.0.4 记录

        Hadoop Hive Hbase 对应版本 Hive官网下载 我们以Hadoop版本作为参考适配Hive Hbase即可, Hadoop版本是2.6.1 所以可以选择Hive1.2.1以上版 ...

  10. Windows下OpenCV 3.1.0 在 Qt Creator 4.0.2 (Qt 5.7.0 MinGW) 中的开发环境配置

    2017-2-23 Update: 修改并添加了部分细节 最近正在学习OpenCV ,为毕业设计做准备.Windows版本的OpenCV都默认提供对VS的支持,其在VS中的配置比较简单,网上也有大批教 ...