0
点赞
收藏
分享

微信扫一扫

Ansible(四)如何进行流程控制

灵魂跑者 2022-03-17 阅读 63

在​​ansible-playbook​​​中,也可以像其他编程语言一样进行条件判断、循环等流程控制。除此之外,还可以控制​​task​​的执行结果。

条件判断 WHEN

在​​ansible​​中,可以通过​​when​​语句来执行条件判断,只有符合条件,才会执行对应的​​task​​。

​when​​语句和​​task​​对齐,在​​when​​语句中,变量不需要使用​​{{ }}​​括起来。

常用判断条件

条件

示例

字符串相等

ansible_machine == "x86_64"

数值相等

max_memory == 512

小于

min_memory < 128

大于

min_memory > 128

小于等于

min_memory <=512

大于等于

min_memory >= 512

不等于

min_memory != 512

变量存在

min_memory is defined

变量不存在

min_memory is not defined

变量值为​​true​​(​​1,True,yes​​等价与​​true​​)

memory_available

变量值为​​false​​(​​0,False,no​​等价与​​false​​)

not memory_available

第一个变量值在第二个变量列表中

ansible_distribution in supported_distros

单条件判断

# when 示例
tasks:
- name: install service
yum:
name: "{{ my_service }}"
when: mysql_service is defined

多条件判断

使用​​and​​​表示且,​​or​​表示或。也可以使用列表,表示且的关系

# and 示例
tasks:
- name: add user when hosts in groups dev and user is defined
user:
name: "{{ my_user }}"
when: "'dev' in group_names and my_user is defined"

# 列表表示且示例 以下条件与上述条件等同
tasks:
- name: add user when hosts in groups dev and user is defined
user:
name: "{{ my_user }}"
when:
- "'dev' in group_names"
- my_user is defined

# or 示例
tasks:
- name: add user when hosts in groups dev and user is defined
user:
name: "{{ my_user }}"
when: "'dev' in group_names or 'test' in group_names"

循环 loop

使用​​loop​​进行循环,一般在​​loop​​中设置一个变量,这个变量是一个列表,使用​​item​​来调用​​loop​​循环中的内容。

​loop​​中的一个项目可以包含多个内容,使用​​item.name​​来调用循环中的内容。

​loop​​和​​task​​对齐

# 单列表循环示例
---
- hosts: all
vars:
packages_for_install:
- firewalld
- gcc
tasks:
- name: install pascages
yum:
name: "{{ item }}"
loop: "{{ packages_for_install }}"

# 多列表循环示例
# 下面这个loop的变量中有两项,每项都包括name和groups。只循环两次
---
- hosts: all
tasks:
- name: Users exist and are in the correct groups
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
state: present
loop:
- name: jane
groups: whell
- name: joe
groups: root

task执行结果控制

在​​ansible-playbook​​​中,我们可以通过一些方法控制​​task​​的结果。以便再特定情况下执行对应的操作

控制changed

Handlers

在某些情况下,我们可能希望只有​​task​​进行了实际改变时才执行某些操作,比如只有配置文件变更了,才重启对应的服务。​​Handlers​​提供了这种功能。

在​​handlers​​中定义要执行的操作名称,在​​task​​中使用​​notify​​指定要执行的操作名称。当​​task​​的结果为​​changed​​时,就会执行指定的​​handler​

​handlers​​和​​tasks​​对齐

​notify​​和​​task​​对齐

执行条件

只有在​​task​​中被​​notify​​,并且这个​​task​​的状态是​​changed​​,才会执行对应的​​handler​

​handlers​​只有在​​task​​s都执行成功的情况下,才会执行

多次​​notify​​的​​handler​​只会执行一次

如果​​handlers​​中定义的名称没有在​​tasks​​中​​notify​​,就不会执行

多个相同名称的​​handlers​​只会执行第一个

执行顺序

默认只有在成功执行完​​tasks​​中的所有操作后才执行​​handlers​​中的操作

​handler​​的执行顺序按照它们在​​handlers​​中定义的顺序执行,与​​notify​​的顺序无关

强制执行handlers

即使tasks中出现错误,也执行handlers中的内容。

只是忽略tasks中的错误,实际是否执行还取决于是否notify changed。

# 示例
---
- hosts: all
force_handlers: yes
tasks:
- name:
template:
src: /var/lib/templates/demo.example.conf.template
dest: /etc/httpd/conf.d/demo.example.conf
notify:
- restart mysql
- restart apache
handlers:
- name: restart apache
service:
name: httpd
state: restarted
- name: restart mysql
service:
name: mariadb
state: restarted

控制task是否更改

为了更好的使用​​handlers​​,​​ansible​​允许我们使用​​changed_when​​语句对​​task​​的结果进行变更(​​ok/changed​​)。

注意:在执行命令或脚本时,即使实际没有更改任何东西,​​task​​的结果默认也为​​changed​

---
- hosts: all
tasks:
# task的结果为ok
- name : get Kerbores credentials as 'admin'
shell: echo "{{ krb_admin_pass }}" | kinit -f admin
changed_when: false
# 只有shell命令的结果包括"Success"时结果才为changed
- shell:
cmd: /usr/local/bin/upgrade-database
register: command_result
changed_when: "'Success' in command_result.stdout"
notify:
- restart_database

handlers:
- name: restart_database
service:
name: mariadb
state: restarted

控制failed

默认情况下,如果一个​​task​​​失败了,该节点上后续的​​task​​都不会继续执行

忽略错误

要忽略失败的​​task​​​,继续执行其他的​​task​​​,可以使用​​ignore_errors​

tasks: 
- name: Run the user creation script
command: /usr/local/bin/create_users.sh
ignore_errors: yes

在出现错误时执行指定的操作

使用​​block-rescue-always​​可以执行一系列的操作

  • ​block​​ 里面可以放置多个​​task​​,可以将​​when​​语句与​​block​​对齐,将条件应用于​​block​​中的所有​​task​
  • ​rescue​​ 和​​block​​对齐,当​​block​​中的​​task​​执行失败时,执行这部分​​task​
  • ​always​​ 和​​block​​对齐,无论​​block​​中的​​task​​是否失败,都执行这部分内容
---
- hosts: all
tasks:
- block:
# 创建一个1500M的逻辑卷
- name: create lv size 1500
lvol:
vg: research
lv: np
size: 1500
rescue:
# 如果创建失败,创建个800M的逻辑卷
- name: create lv size 800
lvol:
vg: research
lv: np
size: 800
always:
# 格式化
- name: Makes a filesystem
filesystem:
device: /dev/research/np
fstype: xfs

控制task是否失败

使用​​failed_when​​控制​​task​​是否失败,当前​​task​​会执行,之后的​​task​​不会执行

使用​​fail​​模块可以使​​task​​失败并输出特定的错误消息。

---
- hosts: all
tasks:
- name : Run the user creation script
command: /usr/local/bin/create_users.sh
register: command_result
failed_when: "'Password missing' in command_result.stdout"

- name: Run the user creation script
command: /usr/local/bin/create_users.sh
register: command_result
ignore_errors: yes

- name: Report script failure
fail:
msg: "The password is missing in the output"
when: "'Password missing' in command_result.stdout"


举报

相关推荐

0 条评论