如何在 Ansible Playbook 中使用 when 条件语句

如果您具有编程或脚本背景,那么您应该熟悉名为 “条件语句”. 条件语句允许您根据条件结果执行代码。 同样在 可靠的你可以使用 “当条件语句” 执行任务。 如果条件被评估为真,任务将运行,否则任务将被跳过。

的语法 when 条件语句如下。 您将在后续部分中学习如何将条件语句应用于任务。

Play definition  tasks:      Task 1     when: condition       Task 2     when: condition 

内容

  1. 带有 Ansible Facts 的“何时”条件语句
  2. 带有逻辑 AND/OR 运算符的 Ansible ‘When’ 条件语句
  3. 带有成员资格运算符的 Ansible ‘When’ 条件语句
  4. 带有 Ansible 变量的“何时”条件语句
  5. 带有 Ansible 寄存器的“何时”条件语句
  6. 带有循环的“何时”条件语句
  7. 结论

When‘ 带有 Ansible Facts 的条件语句

事实 是 ansible 使用受管节点上的 setup 模块收集的系统相关信息。 在某些情况下,您必须根据收集到的事实做出决定。

如果您对事实一无所知,我们有一篇关于事实的简短文章,您可以使用下面的链接访问它。

  • 用例子解释 Ansible 事实

在下面的剧本中,我编写了一个任务来安装 epel-释放 存储库使用 dnf 模块。 使用事实(ansible_distribution),我已经编写了条件语句来仅在“rocky”Linux 上安装该软件包。 我用过 金嘎2 大小写转换过滤器(低)将 ansible_distribution 输出转换为小写。

--- - name: Installing packages   hosts: all   become: true   gather_facts: true    # By default it is set to true    tasks:     - name: Install epel-release      dnf:        pkg: epel-release        state: present      when: ansible_distribution | lower == "rocky"

当我运行剧本时, 当条件 将仅在 Rocky Linux 上评估和运行任务。 对于所有其他发行版,任务将被跳过。

$ ansible-playbook when_condition_test.yml   PLAY [Installing packages] ********************************************************  TASK [Gathering Facts] ************************************************************ ok: [rocky.anslab.com] ok: [ubuntu.anslab.com]  TASK [Install epel-release] *********************************************************************************** skipping: [ubuntu.anslab.com] ok: [rocky.anslab.com]  PLAY RECAP *********************************************************************************** rocky.anslab.com           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0    ubuntu.anslab.com          : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

安西布尔’When‘ 带有逻辑 AND/OR 运算符的条件语句

您可以使用逻辑 AND/OR 运算符来评估多个条件。 我使用的是相同的剧本,但根据事实又添加了一个条件。 由于我正在运行的发行版是 8 并且我正在检查条件,因此将跳过此播放 针对版本 9.

   - name: Logical AND Testing      dnf:        pkg: htop        state: present      when: ansible_distribution | lower == "rocky" and ansible_distribution_major_version == "9"

样本输出:

TASK [Gathering Facts] ********************************************************************************************************************* ok: [rocky.anslab.com] ok: [ubuntu.anslab.com]  TASK [Logical AND Testing] ***************************************************************************************************************** skipping: [ubuntu.anslab.com] skipping: [rocky.anslab.com]

您还可以使用 YAML 列表格式。

   - name: Logical AND using List syntax      dnf:        pkg: htop        state: present      when:        - ansible_distribution | lower == "rocky"        - ansible_distribution_major_version == "9"

当我对逻辑 OR 运算符运行相同的剧本时,该任务将运行良好。

TASK [Gathering Facts] ********************************************************************************************************************* ok: [ubuntu.anslab.com] ok: [rocky.anslab.com]  TASK [Logical OR Testing] ****************************************************************************************************************** skipping: [ubuntu.anslab.com] ok: [rocky.anslab.com]

当您有多个表达式要评估时,您可以将它们放在括号内。 这里我使用 JINJA2 语法(int >= 8) 来评估分发版本是否大于或等于 8。

   - name: Multiple conditions      dnf:        pkg: epel-release        state: present      when: (ansible_distribution | lower == "centos" or ansible_distribution | lower == "rocky") and ansible_distribution_major_version | int >= 8

安西布尔’When‘ 带有成员资格运算符的条件语句

您可以使用 运算符根据值列表评估表达式。 在下面的剧本中,我创建了一个在基于 RHEL 的发行版上运行的任务。

   - name: Membership Operator      dnf:        pkg: epel-release        state: present      when: ansible_distribution | lower in ["centos","rocky"]

样本输出:

TASK [Gathering Facts] ********************************************************************************** ok: [ubuntu.anslab.com] ok: [rocky.anslab.com]  TASK [Membership Operator] *********************************************************************************** skipping: [ubuntu.anslab.com] ok: [rocky.anslab.com]

When‘ 带有 Ansible 变量的条件语句

您可以根据魔术变量、主机变量、组变量评估条件。

如果您对 ansible 变量一无所知,可以使用下面的链接查看我们的文章。

  • 如何在 Ansible Playbook 中使用变量

在下面的剧本中,我创建了一个名为 trigger_pipeline 并将其设置为否。 条件设置为任务仅在以下情况下运行 trigger_pipeline 被设定为 执行.

--- - name: Pipeline call  hosts: all  gather_facts: false   vars:    trigger_pipeline: no   tasks:     - name: Trigger Pipeline      debug:        msg: Running pipeline      when: trigger_pipeline == "execute"

当我运行剧本时,将跳过此任务。

TASK [Trigger Pipeline] ********************************************************* skipping: [rocky.anslab.com]

我可以覆盖变量 trigger_pipeline 从命令行运行以下命令。

$ ansible-playbook when_condition_test.yml -e trigger_pipeline=execute  TASK [Trigger Pipeline] ********************************************************************************** ok: [rocky.anslab.com] => {     "msg": "Running pipeline" }

使用 IS 运算符,您可以检查是否在条件语句中声明了变量。

when: trigger_pipeline is defined          # TRUE only when var is defined when: trigger_pipeline is undefined        # TRUE only when var is not defined

When‘ 带有 Ansible Register 的条件语句

登记 指令用于存储任务的输出。 它类似于将结果存储到变量中,然后使用它进行进一步处理。 根据寄存器变量中存储的数据,可以编写条件语句。

在下面的任务中,我创建了两个任务,第一个任务将使用 模块并运行 /bin/true. 输出将存储在变量寄存器中,该寄存器用于第二个打印任务。

 tasks:     - name: set to true      shell: /bin/true      register: result     - name: print result      debug:        var: result

样本输出:

ok: [rocky.anslab.com] => {     "result": {         "ansible_facts": {             "discovered_interpreter_python": "/usr/libexec/platform-python"         },         "changed": true,         "cmd": "/bin/true",         "delta": "0:00:00.003477",         "end": "2022-05-23 17:13:15.056197",         "failed": false,         "msg": "",         "rc": 0,         "start": "2022-05-23 17:13:15.052720",         "stderr": "",         "stderr_lines": [],         "stdout": "",         "stdout_lines": []     } }

您可以使用这些值中的任何一个来创建条件。 假设您只想在 rc 被设定为 ,那么你可以写出如下的条件。

when: result.rc == 0

同样,根据可用的值,您可以根据用例编写尽可能多的条件。 以下是基于结果变量输出的一些条件。

when: result.stdout != ""             # Checking if stdout is not empty when: result.failed == "false"        # checking if failed is set to false when: changed == "true"               # Checking if the status of changed is true

When‘ 带循环的条件语句

您可以将条件语句与 循环. 在这种情况下,对于循环条件语句中的每一项,都将根据给定的表达式进行评估。

下面一起来看看这部剧吧。 我正在创建两个名为 ubuntu多岩石的 使用 用户模块. loop 指令将针对用户名变量进行循环。 这里的条件写成 ubuntu 用户只能在 ubuntu Linux 主机中创建,而 rocky 用户应该在 rocky Linux 主机中创建。

- name: Create Users   hosts: all   gather_facts: true   become: true   vars:    username:      - ubuntu      - rocky   tasks:     - name: Create the user      user:        name: "{{ item }}"        state: present        password: "{{  item | password_hash('sha512') }}"      loop: "{{ username }}"      when: (item == "ubuntu" and ansible_distribution | lower == "ubuntu") or (item == "rocky" and ansible_distribution | lower == "rocky")

从下面的输出中可以看出,用户是根据条件在各自的分布中创建的。

TASK [Create the user] ******************************************************************************** skipping: [rocky.anslab.com] => (item=ubuntu)  changed: [ubuntu.anslab.com] => (item=ubuntu) skipping: [ubuntu.anslab.com] => (item=rocky)  changed: [rocky.anslab.com] => (item=rocky)

结论

在本文中,我们了解了什么是条件语句,以及如何使用 Ansible 中的 when 条件语句来评估条件并根据结果运行任务。

当您学习角色、导入、包含等高级概念时,您将更多地了解条件语句以及如何更有效地使用它们。

资源:

  • Ansible 条件

AnsibleAnsible 命令Ansible FactsAnsible PlaybooksAnsible 系列Ansible 教程Ansible 变量Ansible When 条件语句DevOpsIT 自动化Linux 管理When 条件语句