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 语句可用于评估多个值。为此,可以使用 andor 关键字组合条件,或使用括号分组条件
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 子句中定义的任务都将执行:

相关内容

    暂无相关文章