如何在AnsiblePlaybook中使用条件
在 Ansible 中,您可以定义将在执行任务之前评估的条件。 如果不满足条件,则跳过该任务。 这是通过 when
关键字完成的,该关键字接受通常基于变量或事实的表达式。
以下示例定义了两个变量:create_user_file
和 user
。 当 create_user_file
计算为 true
时,将在 user
变量定义的用户主目录中创建一个新文件:
在 ansible-practice
目录中创建一个名为 playbook-04.yml
的新文件:
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
完成编辑内容后保存并关闭文件。
要从您的清单文件在服务器上执行此 playbook,请使用您之前在运行本系列中的其他 playbook 时使用的相同连接参数运行 ansible-playbook
。 同样,我们将使用名为 inventory
的清单文件和 sammy 用户连接到远程服务器:
ansible-playbook -i inventory playbook-04.yml -u sammy
满足条件时,您将在播放输出中看到 changed
状态:
Output... TASK [create file for user] ***************************************************************************** changed: [203.0.113.10] ...
如果将 create_user_file
的值更改为 no
,条件将被评估为 false
。 在这种情况下,您会在播放输出中看到 skipping
状态,表示任务未执行:
Output... TASK [create file for user] ***************************************************************************** skipping: [203.0.113.10] ...
在 Ansible playbook 的上下文中,条件句的一个常见用途是将它们与 register
结合起来,这是一个创建新变量并将其分配给从命令获得的输出的关键字。 这样,您可以使用任何外部命令来评估任务的执行。
需要注意的一件重要事情是,默认情况下,如果您用于评估条件的命令失败,Ansible 将中断播放。 出于这个原因,您需要在所述任务中包含设置为 yes
的 ignore_errors
指令,这将使 Ansible 继续执行下一个任务并继续播放。
以下示例将仅在用户主目录中创建一个新文件以防该文件尚不存在,我们将使用 ls
命令对其进行测试。 但是,如果文件存在,我们将使用 debug
模块显示一条消息。
在 ansible-practice
目录中创建一个名为 playbook-05.yml
的新文件:
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 时,该命令将失败,因为该文件不存在于该路径中。 然后将执行创建文件的任务,而最后一个任务将被跳过:
... [secondary_label 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
任务导致服务器发生变化,这意味着文件已创建。 现在,再次运行 playbook,你会得到不同的结果:
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 playbooks 中使用条件的信息,请参阅 官方文档 。