如果您需要根据不同条件执行 Ansible 任务,那么您来对地方了。 Ansible when
和其他条件 允许您评估条件,例如基于操作系统,或者如果一个任务依赖于前一个任务。
在本教程中,您将学习如何使用 Ansible when
和其他条件,以便您可以执行任务而不会搞砸事情。
让我们开始吧!
先决条件
本教程包括实际操作示例。 如果您想跟着做,请确保您已经准备好以下内容:
- 一个 Ansible 控制器主机 – 本教程使用安装在 Ubuntu 18.04.5 LTS 机器上的 Ansible v2.9.24。
- A remote computer to run commands.
- 您需要设置一个 清单文件,并已经配置一个或多个主机来运行 Ansible 命令和 playbooks。 本教程将使用一个名为 web 的清单组。
使用 Playbook 中的多个任务处理 Ansible when
执行剧本中有多个任务可能会很烦人,如果它们都没有特定的条件执行。让我们通过在 Ansible 剧本中定义具有多个任务的 Ansible when
条件来开始本教程。
1. 在 Ansible 控制器主机上打开终端。
2. 运行以下命令来创建一个目录,并将其命名为您喜欢的任何名称在您的主目录中,并导航到该目录。
对于这个示例,目录被命名为 ansible_when_condition_demo
。该目录将包含您将用于在 Ansible 任务中调用 when 条件的 剧本。
3. 在您喜欢的代码编辑器中,在 ~/ansible_when_condition_demo 目录中创建一个 YAML 文件。在本例中,文件名为 my_playbook.yml。将以下 YAML 剧本内容复制并粘贴到 my_playbook.yml 文件中。
在下面的两个任务(Task-1
和 Task-2
)中,when
条件检查每个远程主机所在的操作系统。然后将结果传递给每个任务上的 ansible_os_family
占位符变量。
如果ansible_os_family
占位符的值等于RedHat
或Debian
,那么Ansible执行安装Apache的任务之一。
4. 现在运行下面的ansible-playbook
命令来执行playbook中定义的任务(my_playbook.yml),在你现有的清单文件中定义的远程主机上。
在下面的截图中,你可以看到:
- 第一个任务返回了OK状态,这表明任务不需要任何更改。
- 第二个任务返回了跳过状态。当条件不满足时,任务将被跳过。
- 第三个任务返回了更改状态,这表明远程主机处于不正确的状态(即Apache不存在)并且已被修改以安装Apache。

5. 打开SSH会话到远程主机,该主机是Ansible playbook的目标,使用您喜欢的SSH客户端验证Apache是否已安装并正在运行。
6. 最后,运行以下service
命令验证Apache是否已安装(status apache2
)在远程主机上。
如下所示,您已在远程机器上安装了Apache服务。

使用Ansible when
和循环
之前,您根据Ansible when
执行了特定参数的任务,如ansible_os_family
。 但也许您需要检查在列表中定义的多个参数的条件。 如果是这样,请尝试在任务中添加loop
。
打开您之前创建的my_playbook.yml文件(“使用Ansible when
处理Playbook中的多个任务”下的第三步)。 将my_playbook.yml文件的内容替换为以下代码。
代码中的任务(Task-1
)运行loop
,其中when
条件检查项目值是否大于五并返回结果。
现在运行以下命令以执行之前所做的播放。
以下,您可以看到任务在条件为假时返回跳过状态,而在条件为真时返回更改状态。

when
condition for multiple parameters 使用Ansible的when
和Ansible的facts
来处理任务。
也许您想要添加多个条件以执行任务。如果是这样,请学习如何在when
条件中使用Ansible facts。Ansible facts允许您添加条件语句以基于收集到的事实执行任务,例如您的操作系统、IP地址、附加的文件系统等。
使用以下代码替换my_playbook.yml文件的内容。
在下面的代码中,两个任务(Task-1
和Task-2
)只有在以下条件之一为真时才执行(关闭系统):
- 返回的
distribution
和distribtion_major_version
都为真。 os_family
的值等于CentOS
。
像之前一样使用以下命令执行playbook。
请注意,在Ubuntu中,由于跳过状态,两个任务都不执行。任务仅在您在CentOS中时执行。

使用基于已注册值的 Ansible `when`
根据剧本中先前任务的结果执行或跳过任务是时常需要的。例如,您可能希望在之前的任务升级后配置一个服务。在这种情况下,使用一个已注册变量。已注册变量允许您将先前任务的结果注册为一个变量,并将其用作下一个任务的输入。
1. 创建一个名为/home/ubuntu/hello的空目录。
2. 将my_playbook.yml文件的内容替换为下面的代码,执行以下操作:
第一个任务(任务-1
)在内存中列出/etc/hosts
目录的内容(文件和子目录),并通过register
命令将结果保存到contents1
变量中。
第二个任务(任务-2
)在内存中列出/home/ubuntu/hello目录的内容(当前为空),并将该列表保存到contents2
变量中。
第三个任务(任务-3
)检查并在contents1
或contents2
变量的注册结果为空时打印“目录为空”消息。
contents1
和contents2
变量的stdout
属性是运行任务命令的结果的保存的shell输出。
3. 最后,使用以下 ansible-playbook
命令执行 Playbook。
如下所示,由于 contents2
变量的注册结果为空,第三个任务返回 目录为空 消息。

Ansible when
based on registered values 使用 Ansible 中的 when
处理 Ansible 角色
在这个最终的例子中,您将学习 Ansible 中 when
在 Ansible roles
内部的工作原理。Ansible roles
允许您重用标准配置并实现更快的部署。继续阅读,了解任务仅在 Ansible when
条件为真时调用 Ansible roles
的方法。
1. 运行以下命令在您的主目录中创建一个名为~/ansible_role_when_demo的目录,并切换到该文件夹作为工作目录。~/ansible_role_when_demo目录将保存此示例的演示文件。
2. 接下来,运行以下命令创建一个~/ansible_role_when_demo/roles和~/ansible_role_when_demo/roles/java/tasks目录。
下面是每个目录包含的内容:
- ~/ansible_role_when_demo/roles目录将包含您需要部署的角色。
默认情况下,Ansible在两个位置查找角色:在playbook所在目录中的名为roles/的目录中,或在/etc/ansible/roles中。如果希望将角色存储在不同的路径,请使用
- role:
参数在playbook中声明路径。
- ~/ansible_role_when_demo/roles/java/tasks文件夹将包含一个main.yml文件,您需要部署一个角色。
现在,在 ~/ansible_role_when_demo/roles/java/tasks 目录下创建一个名为 main.yml 的文件,然后将下面的剧本代码复制粘贴到 main.yml 文件中。
下面的剧本在远程节点上使用 apt 模块安装 Java。
4. 创建另一个以您喜欢的名称命名的 YAML 文件,并复制/粘贴下面的代码。例如,文件名为 ~/ansible_role_when_demo/java-setup.yml。
下面的代码将 Ansible role
(java
) 部署到具有管理员访问权限的远程用户 (ubuntu
),仅当远程用户位于 Debian 操作系统上时才执行。
5. 运行tree
命令,验证在~/ansible_role_when_demo目录中存在所有必需的文件夹和文件。

6. 最后,使用下面的ansible-playbook
命令执行playbook。ansible-playbook java-setup.yml
下面,任务返回了一个changed状态,表示Java已成功安装,因为远程节点是Debian操作系统。 使用
Ansible when
和Ansible角色运行Ansible playbook

Ansible when
with Ansible roles 结论
在本教程中,您学习了使用Ansiblewhen
和其他条件的不同方式。您还学习了如何应用Ansiblewhen
条件,从利用Ansiblefacts
执行基本任务到部署Ansibleroles
。
现在您如何建立在这些新知识上?也许在应用Ansiblewhen
条件的同时,使用Ansible模板节省配置多个服务器的时间?