如何在 Ansible Playbooks 中使用条件


该系列的一部分:
如何编写 Ansible Playbooks

Ansible 是一种现代配置管理工具,不需要在远程节点上使用代理软件,仅使用 SSH 和 Python 在托管服务器上进行通信和执行命令。本系列将带您了解可用于编写服务器自动化剧本的主要 Ansible 功能。最后,我们将看到一个实际示例,说明如何创建剧本以自动设置远程 Nginx Web 服务器并向其部署静态 HTML 网站。

在 Ansible 中,您可以定义将在执行任务之前评估的条件。当不满足条件时,则跳过该任务。这是通过when关键字完成的,它接受通常基于变量或事实的表达式。

以下示例定义了两个变量:create_user_fileusercreate_user_file被评估为 时true,将在由user变量定义的用户的主目录中创建一个新文件

playbook-04.yml在您的ansible-practice目录中创建一个名为的新文件

  • nano ~/ansible-practice/playbook-04.yml

然后将以下行添加到新的剧本文件中:

~/ansible-practice/playbook-04.yml
---
- hosts: all
  vars:
    - create_user_file: yes
    - user: sammy  
  tasks:
    - name: create file for user
      file:
        path: /home/{{ user }}/myfile
        state: touch
      when: create_user_file

完成编辑内容后保存并关闭文件。

要从您的清单文件在服务器上执行此剧本,ansible-playbook请使用您之前在运行本系列中的其他剧本时使用的相同连接参数运行。同样,我们将使用名为清单文件inventory萨米用户连接到远程服务器:

  • ansible-playbook -i inventory playbook-04.yml -u sammy

当条件满足时,您将changed在播放输出中看到一个状态:

Output
... TASK [create file for user] ***************************************************************************** changed: [203.0.113.10] ...

如果将 的值更改create_user_fileno,则条件将评估为false在这种情况下,您将skipping在播放输出中看到一个状态,表明该任务未执行:

Output
... TASK [create file for user] ***************************************************************************** skipping: [203.0.113.10] ...

Ansible playbook 上下文中条件语句的一个常见用途是将它们与 结合register,这是一个创建新变量并将其分配给从命令获得的输出的关键字。这样,您可以使用任何外部命令来评估任务的执行情况。

需要注意的一件重要事情是,默认情况下,如果您用来评估条件的命令失败,Ansible 将中断播放。出于这个原因,您需要在所述任务中包含一个ignore_errors设置为指令yes,这将使 Ansible 继续执行下一个任务并继续播放。

下面的示例只会在用户主目录中创建一个新文件,以防该文件尚不存在,我们将使用ls命令进行测试但是,如果文件存在,我们将使用该debug模块显示一条消息

playbook-05.yml在您的ansible-practice目录中创建一个名为的新文件

  • nano ~/ansible-practice/playbook-05.yml

然后将以下内容添加到新的 playbook 文件中:

~/ansible-practice/playbook-05.yml
---
- hosts: all
  vars:
    - user: sammy
  tasks:
    - name: Check if file already exists
      command: ls /home/{{ user }}/myfile
      register: file_exists
      ignore_errors: yes

    - name: create file for user
      file:
        path: /home/{{ user }}/myfile
        state: touch
      when: file_exists is failed

    - name: show message if file exists
      debug:
        msg: The user file already exists.
      when: file_exists is succeeded

完成后保存并关闭文件。

然后,ansible-playbook使用与前面示例相同的连接参数运行在这里,我们使用了一个名为 的清单文件inventory和一个名为 的用户sammy,但您应该相应地更改这些值:

  • ansible-playbook -i inventory playbook-05.yml -u sammy

第一次运行此 playbook 时,该命令将失败,因为该文件不存在于该路径中。然后将执行创建文件的任务,而将跳过最后一个任务:

Output
... TASK [Check if file already exists] ********************************************************************* fatal: [203.0.113.10]: FAILED! => {"changed": true, "cmd": ["ls", "/home/sammy/myfile"], "delta": "0:00:00.004258", "end": "2020-10-22 13:10:12.680074", "msg": "non-zero return code", "rc": 2, "start": "2020-10-22 13:10:12.675816", "stderr": "ls: cannot access '/home/sammy/myfile': No such file or directory", "stderr_lines": ["ls: cannot access '/home/sammy/myfile': No such file or directory"], "stdout": "", "stdout_lines": []} ...ignoring TASK [create file for user] ***************************************************************************** changed: [203.0.113.10] TASK [show message if file exists] ********************************************************************** skipping: [203.0.113.10] ...

从输出中,您可以看到该create file for user任务导致服务器发生更改,这意味着该文件已创建。现在,再次运行剧本,你会得到不同的结果:

  • ansible-playbook -i inventory playbook-05.yml -u sammy
Output
... TASK [Check if file already exists] ********************************************************************* changed: [203.0.113.10] TASK [create file for user] ***************************************************************************** skipping: [203.0.113.10] TASK [show message if file exists] ********************************************************************** ok: [203.0.113.10] => { "msg": "The user file already exists." } ...

如果您想了解有关在 Ansible playbook 中使用条件的更多信息,请参阅官方文档

觉得文章有用?

点个广告表达一下你的爱意吧 !😁