5-1·Ansible的流程控制、错误判断、Handlers,ansiblehandlers
5-1·Ansible的流程控制、错误判断、Handlers,ansiblehandlers
一·构建流控制(Flow Control)
1)Ansible 循环:
- Ansible 支持许多循环格式,以迭代一个数组中定义的一组值 要将循环作为参数传递,需要将 item 关键字用于 Ansible
来解析该数组
2)Ansible 支持的循环:
- 简单循环:简单循环是 Ansible 读取并迭代的一组项目。它们通过将一组项目提供给 with_items 关键字来定义 hash
- 列表:将数组作为参数传递时,数组可以是 hash 列表 嵌套循环:嵌套循环即在循环内部通过 with_nested
- 关键字调用的循环。使用嵌套循环时,Ansible 将迭代第一个数组,只要其中包含有值
- 若要捕获数组模块的输出,可将 register 关键字用于数组。Ansible 会将输出保存在变量中。管理员可以使用它检查模块的执行结果
- 条件: Ansible 可以利用条件在符合特定条件时执行任务 管理员可利用条件来区分不同的受管主机,并根据它们所符合的条件来分配功能角色
Playbook 变量、注册的变量和 Ansible 事实都可通过条件来进行测试 可以使用字符串比较、数学运算符和布尔运算等各种运算符
以下示例为 Ansible 可以使用条件:
- 可以在变量中定义硬限制(如 min_memory)并将它与受管主机上的可用内存进行比较
- Ansible 可以捕获命令的输出,以确定某一任务在执行进一步操作前是否已经完成。例如,如果某一程序失败,则将需要跳过批处理
- 可以利用 Ansible 事实来确定受管主机网络配置,并且决定要发送的模板文件(如,网络绑定或中继)
- 可以评估 CPU 的数量,来确定如何调节某一 Web 服务器
- 注册的变量可以和定义的变量进行比较,来检查服务变化。例如,可以用这来验证文件的 MD5
3)Ansible 条件运算符:
注意:用于测试条件中相等的 == 运算符不可与变量赋值的 = 运算符混淆
4)Ansible when 语句:
- 要对元素实施条件,必须使用 when 语句,后面接上要测试的条件 存在此语句时,Ansible 先对它进行评估,然后再执行任务
多个条件:
一个 when 语句可用于评估多个值。为此,可以使用 and 和 or 关键字组合条件,或使用括号分组条件
ansible_kernel == 3.10.0-327.el7.x86_64 and inventory_hostname in groups['staging’]
ansible_distribution == "RedHat" or ansible_distribution == “Fedora"
(ansible_distribution == "RedHat" and ansible_distribution_major_version == 7) or (ansible_distribution == "Fedora" and ansible_distribution_major_version == 23)
循环和条件还可以组合使用。注意:在组合使用 when 和 with_items 时,请注意 when 语句将对每一项目进行处理
5)使用布尔运算:
布尔运算是取两个可能值之一的变量,可以表达为:
- True 或 Yes 或1
- False 或 No 或0
布尔运算可用作启用或停用任务的简易开关
二·实施处理程序(Handlers)
1)Ansible 的 handlers 程序:
- Ansible 模块设计为 idempotent 模式。这表示,在正确编写的 playbook 中,playbook
- 及其任务可以运行多次而不会改变受管主机,除非需要进行更改使受管主机进入所需的状态
- 但有时,在任务更改系统时,可能需要运行进一步的任务。例如,更改服务配置文件时可能要求重新加载该服务以使更改的配置生效 handler
- 程序响应由其他任务触发通知的任务。每一处理程序具有全局唯一的名称,在 playbook 中任务块的末尾触发。如果没有任务通知
- handler 程序,它就不会运行。如果有一个或多个任务通知 handler 程序,它会在 play 中所有其他任务完成后仅运行一次 因为
- handler 程序就是任务,所以管理员可以在 handler 程序中使用各种模块。通常,handler
- 程序被用于重新引导主机和重新启动服务 handler 程序可视为非活动任务,只有在使用 notify 语句显式调用时才会被触发。
- 在下列代码片段中,只有配置文件更新并且通知了该任务时,restart_apache 任务才会重新启动 Apache
- 服务器。restart_apache 处理程序只有在从 copy 任务获得发生更改通知时才会触发。一个任务可以在其 notify
- 部分中调用多个处理程序。Ansible 将 notify 语句视为数组
2)使用 handler 程序的注意事项:
- handler 程序始终按照它们在 play 的 handlers 部分中编写的顺序来运行 处理程序在相关 play
- 中的所有其他任务完成后运行 处理程序名称存在于全局命名空间中。如果两个处理程序被错误地给予相同的名称,则仅会运行一个 在 include
- 内定义的处理程序无法获得通知 即使有多个任务通知处理程序,该处理程序依然仅运行一次。如果没有任务通知处理程序,它就不会运行 如果包含
- notify 的任务没有执行(例如,软件包已经安装),则 handler 程序不会获得通知。handler
- 程序将被跳过,直到有其他任务通知它。只有相关任务获得了 CHANGED 状态,Ansible 才会通知处理程序 handler
- 程序设计为仅在任务执行时处理操作,它们不应当用于取代任务
三·实施标记(Tags)
1)Tag Ansible 资源:
- 对于篇幅较长的 playbook,如果能够运行 playbook 中任务的子集会很有帮助 可以将 tag
- 设置到特定的资源上作为文本标签。tag 资源仅需要使用 tags 关键字,再加上要应用的 tag 列表 为 play 添加 tag
- 后,可将 –tags 选项用于 ansible-playbook,使 playbook 过滤为仅执行加有特定标记的 play
标记可用于下列资源:
在 playbook 中,每一个任务都可使用 tags 关键字添加标记
当任务文件包含在 playbook 中时,该任务可以添加标记,允许管理员为 include 语句设置全局标记
为某一 role 或 include 语句添加标记时,它们定义的所有任务也都会加上标记
管理标记的资源:
- 当标记应用至资源后,可以将 ansible-playbook 命令与 –tags 或 –skip-tags 参数搭配使用,
- 以执行带标记的资源或防止带标记的资源被包含在 play 中 以下 playbook 含有两个任务:第一个任务带有 production
标记,另一个任务则未关联任何标记
若要仅运行第一个任务,可以使用 –tags 参数
因为指定了 –tags 选项,该 playbook 仅运行一个任务,即带有 production
- 标记的任务。要跳过第一个任务而仅运行第二个任务,可使用 –skip-tags 选项
特殊标记:
- Ansible 拥有一个可在 playbook 中分配的特殊标记:always 此标记使得任务始终被执行,即便是使用了
- –skip-tags 选项,除非通过 –skip-tags always 选项来明确跳过 可以在命令行中通过 –tags 选项使用三种特殊标记:
0. tagged 关键字用于运行任何带标记的资源
0. untagged 关键字的作用与 tagged 关键字相反,从 play 中排除所有带标记的资源
0. all 关键字允许管理员包含 play 中的所有任务。这是命令行的默认行为
四·处理错误
1)play 中的错误:
- Ansible 会评估模块和命令的返回代码,从而确定任务是成功还是失败。通常而言,当任务失败时,Ansible 将立即中止 play
- 但有些时候,管理员可能希望即使在任务失败时也继续执行 playbook。例如,可能会预期到某一特定命令将失败
- 有多种 Ansible 功能可用于改善任务错误的管理
2)忽略失败的任务 Ignore the failed task:
- 默认情况下,如果某一任务失败,play 将中止,可以通过跳过失败的任务来覆盖此行为 需要在任务中使用 ignore_errors 关键字
- 下列代码片段演示了如何使用 ignore_errors 即使在任务失败时也继续执行 playbook。例如,如果 notapkg
- 软件包不存 在,yum 模块将失败,但若将 ignore_errors 设为 yes,则执行将继续
3)强制执行处理程序 Force execution of handlers:
- 默认情况下,如果通知处理程序的任务失败,则该处理程序也会被跳过 管理员可以在任务中使用 force_handlers 关键字来覆盖此行为
- 这会强制调用该处理程序,即使相关的任务失败 下列代码片段演示了在任务中使用 force_handlers
关键字,而从在任务失败时强制执行相应的处理程序
4)覆盖 failed 状态 Override the failed state:
- 任务本身可以成功,但管理员可能希望基于特定的标准将任务标记为失败 为此,可以将 failed_when 关键字用于任务
- 这通常用于执行远程命令并且捕获变量中的输出的模块
- 例如,管理员可以运行输出错误消息的脚本,并使用该消息定义任务的失败状态。下列代码片段演示了如何在任务中使用 failed_when 关键字
5)覆盖 changed 状态 Override the changed state:
- 当任务更新受管主机时,它将获取 changed 状态。但是,如果任务不在受管主机上执行任何更改,处理程序会被跳过 changed_when
- 关键字可用于覆盖触发 changed 状态的默认行为 例如,如果管理员希望在每次运行 playbook 时重新启动某一服务,可以将
- changed_when 关键字添加到相应任务中。下列代码片段演示了如果通过强制 changed 状态来每次都触发处理程序
6)Ansible blocks 和错误处理:
- 在 playbook 中, blocks 是囊括了任务的子句
blocks 允许对任务进行逻辑分组,并可用于控制任务的执行方式 - 例如,管理员可以定义一组主要任务和一组附加任务,附加任务仅在第一组失败时执行
为此,可利用三个关键字在 playbook 中使用块:
- block:定义要运行的主要任务
- rescue:定义将在 block 子句中定义的任务失败时运行的任务
- always:定义始终都独立运行的任务,不论 block 和 rescue 子句中定义的任务是成功还是失败
- 下例演示了如何在 playbook 中实施块。即使 block 子句中定义的任务失败,rescue 和 always 子句中定义的任务都将执行:
评论暂时关闭