实施任务控制
1、编写循环和条件任务
简单循环
1)不用循环
2)使用循环
---
- name: test
hosts: webservers
tasks:
- name: Apache and vdftpd are running
service:
name: "{{ item }}" #循环变量item
state: started
loop:
- httpd
- vsftpd
3)将变量放入列表
---
- name: test
hosts: webservers
vars:
web_service:
- httpd
- vsftpd
tasks:
- name: Apache and vdftpd are running
service:
name: "{{ item }}"
state: started
loop: "{{ web_service }}"
循环散列或字典列表
---
- name: User test
user:
name: "{{ item.name }}"
state: present
group: "{{ item.groups }}"
loop:
- name: student
groups: student
- name: redhat
groups: redhat
早些版本的循环,使用with_
vars:
data:
- user1
- user2
- user3
tasks:
- name: "with_items"
register和loop一起使用
迭代上面playbook的结果(即使用上面item的结果)
---
- name: loop register test
gather_facts: no
hosts: localhost
tasks:
- name: loop task
shell: "echo This is my item: {{ item }}"
loop:
- one
- two
register: echo_results #注册变量
- name: Show results
debug:
msg: "STDOUT is : {{ item.stdout }}"
loop: "{{ echo_results['results'] }}"
条件任务语法
关键字:when
使用布尔值测试
---
- name: Bool test
hosts: all
vars:
my_task: true #只有当变量为true时,才会执行
tasks:
- name: httpd is installd
yum:
name: httpd
when: my_task
测试my_service变量是否有值,有值则安装
---
- name: Bool test
hosts: all
vars:
my_service: httpd
tasks:
- name: "{{ my_service }} is installed"
yum:
name: "{{ my_service }}"
when: my_service is defined
条件
等于(字符串) A== "B"
等于(数字) A==100
小于 <
大于 >
小于等于 <=
大于等于 >=
不等于 !=
变量存在 xxx is defined
变量不存在 xxx is not defined
布尔值true 1、true、yes
布尔值false 0、false、no
第一个变量的值存在,且在第二个变量的列表中 A in B
测试多个条件
or 两个条件一个为真即可
and 两个条件必须都为真
when支持使用列表描述条件
when:
- ansible_distribution_version == "8.0"
- ansible_kernel == "4.18.0-80.1.2.el8_0.x86_64"
再如:
when:
(ansible_distribution == "RedHat" and
ansible_distribution_major_version == "8")
or
(ansible_distribution == "CentOS" and
ansible_distribution_major_version == "7")
组合循环和有条件任务
---
- name: keyword
hosts: all
tasks:
- name: install mariadb
yum:
name: mariadb-server
state: latest
loop: "{{ ansible_mounts }}" #这个变量是事实,已知的
when: item.mount == "/" and item.size_available > 300000000
---
- name: Restart apache if vsftpd is running
hosts: all
tasks:
- name: Get vsftpd status
command: /usr/bin/systemctl is-active vsftpd #判断状态
ignore_errors: yes #如果vsftpd没运行或失败,则忽略
register: result #定义变量保存结果
- name: Restart httpd
service:
name: httpd
state: restarted
when: result.rc == 0 #退出码为0,则重启httpd
一遇到错误立即退出,不会继续执行
编写循环和条件任务:
练习:
修改db.yml,条件变为受管主机使用rehdat操作系统时才执行
检测westos2组的主机系统
运行
2、实施处理程序
处理程序是响应由其他任务触发的通知的任务
只有在template任务通知已发生更改时才会触发
---
- name: Test
hosts: webservers
tasks:
- name: Copy File
template:
src: files/example.conf
dest: /etc/httpd/conf.d/example.comf
notify: #notify语句指出该任务需要触发一个处理程序
- restart apache #程序名
- restart mysql
handlers: #表示处理程序任务列表的开头
- name: restart apache #被任务调用的处理程序名称
service: #处理该程序的模块
name: httpd
state: restarted
- name: restart mysql
service:
name: mariadb
state: restarted
ansible把notify语句当作数组
使用处理程序注意:
1.处理程序始终按照play的handlers部分指定的顺序运行,不按notify里的
2.处理程序通常在相关play中所有其他任务运行完后运行
3.处理程序名称存在于个play命名空间中(如果两个处理程序同名,只会运行一个)
4.如果多个任务通知处理程序,处理程序也只会运行一次
5.如果包含notify的语句任务没有报告changed结果,则处理程序不会获得通知