在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"
网友评论