实施任务控制
编写循环和条件任务
简单循环任务
1.不用循环
写一个简单的palybook
---
- name: test check
hosts: all
tasks:
- name: apache is running
service:
name: httpd
state: started
- name: vsftpd is running
service:
name: vsftpd
state: started
...
测试apache和vsftp是否是开启的状态
2.使用循环
使用循环语句先设定循环内容
---
- name: test check
hosts: all
tasks:
- name: check apache and vsftp are running
service:
name: "{{ item }}"
state: started
loop:
- httpd
- vsftpd
...
执行playbook后可以看到执行结果中 item 表示的循环分别把里面的值去依次在hosts主机上执行
3.将变量放入列表
编辑playbook时将需要测试的服务设为变量引用
---
- name: test check
hosts: all
vars:
web_service:
- httpd
- vsftpd
tasks:
- name: check apache and vsftp are running
service:
name: "{{ item }}"
state: started
loop: "{{ web_service }}"
...
实行的效果和正常的循环一样
循环散列或字典列表
编写 playbook 设置多个循环
循环里分别指定name和group,下面给出name和group的值
---
- name: User Test
user:
name: "{{ item.name }}"
state: present
groups: "{{ item.groups }}"
loop:
- name: testuser
groups: testuser
- name: redhat
groups: root
...
早些版本的循环,在2.4之前的版本
早些版本的循环使用格式是 “with_ ”
例:
---
- name: test check
hosts: all
vars:
web_service:
- httpd
- vsftpd
tasks:
- name: check apache and vsftp are running
service:
name: "with_item"
state: started
with_item: "{{ web_service }}"
register 和 loop 同时使用
写一个playbook 包含 loop 和 register 的模块
---
- name: loop register test
hosts: localhost
tasks:
- name: loop
shell: "echo This is my item: {{ item }}"
loop:
- one
- two
register: echo_results
- name: Show echo results variable
debug:
var: echo_results
...
并且我们可以看到它的输出内容在结果中都可以查看出来
如果我们只想要将结果提取出来,可以用字典的方式指定需要的结果
---
- name: loop register test
hosts: localhost
tasks:
- name: loop
shell: "echo This is my item: {{ item }}"
loop:
- one
- two
register: echo_results
- name: Show echo results variable
debug:
msg: " STDOUT is: {{ item.stdout }}"
loop: "{{ echo_results['results'] }}"
...
条件任务语法
关键字:when
我们来测试when如何来使用
测试:
---
- name: Boolean test
hosts: all
vars:
run_tasks: true
tasks:
- name: httpd is installed
yum:
name: httpd
when: run_tasks
...
执行后检测受管主机安装过httpd,如果安装过就去执行
将playbook中的 ture 参数改为 false ,执行后就是检测后跳过执行
测试 my_service 变量是否有值,有值则安装
---
- name: Boolean test
hosts: all
vars:
my_service: httpd
tasks:
- name: "{{ my_service }} is installed"
yum:
name: "{{ my_service }}"
when: my_service is defined
...
执行剧本结果是正常在执行
如果将 when 条件改为 when: my_service is not defined 那执行结果就会是跳过执行
判断条件
判断 | 表示 |
---|---|
等于(字符串) | A == “B” |
等于(数字) | A == 100 |
小于 | < |
大于 | > |
小于等于 | <= |
大于等于 | >= |
不等于 | != |
变量存在 | xxx is defined |
变量不存在 | xxx is not defined |
bool值 true | 1、true、yes |
bool值 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"
判断系统是RedHat8或者是CentOS7的
when:
( ansible_distribution == "RedHat" and
ansible_distribution_major_version == "8" )
or
( ansible_distribution == "CentOS" and
ansible_distribution_major_version == "7" )
组合循环和有条件任务
实验:当 vsftpd 运行时,可以重启 httpd
---
- name: Restart httpd when vsftpd is running
hosts: usersevers
tasks:
- name: Check vsftpd status
command: /usr/bin/systemctl is-active vsftpd
ignore_errors: yes #当出现错误时,忽略任务执行
register: result
- name: Restart httpd
service:
name: httpd
state: restarted
when: result.rc == 0 #当结果的返回值为0时执行,就是当上一条任务没有错误时,yes=1,no=0
...
当受管主机的vsftpd服务是开启时,可以正常执行
如果受管主机的vsftpd 服务关机或找不到,那任务就会自动跳过
实验:为受管主机安装数据库服务并且设置开机启动,但是需要受管主机的系统为RedHat
---
- name: Install and enbale mariadb
hosts: usersevers
vars:
mariadb_pkgs:
- mariadb-server
- python3-PyMySQL
tasks:
- name: Install mariadb
yum:
name: "{{ item }}"
state: latest
loop: "{{ mariadb_pkgs }}"
when: ansible_distribution == "RedHat"
- name: Start mariadb
service:
name: mariadb
state: started
enabled: true
...
测试执行
实施处理程序
处理程序是响应由其他任务触发的通知的任务
只有在 template 任务通知已发生更改时才会触发
---
- name: Test
hosts: usersevers
tasks:
- name: Copyt file
template:
src: files/example.conf
dest: /etc/httpd/conf.d/example.conf
notify: #notify 语句指出该任务需要触发一个处理程序
- restart apache #程序名
handlers: #表示处理程序任务列表的开头
- name: restart apache #被任务调用的处理程序名
service: #处理该程序的模块
name: httpd
state: restarted
...
编辑files/example.conf的配置文件内容
<VirtualHost *:80>
DocumentRoot /www
ServerName www.test.org
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /bbs
ServerName bbs.test.org
</VirtualHost>
然后测试执行playbook
notify 语句可以被当作数组,接入多个任务名,然后在 handlers 下去分别写任务名对应的任务内容
例:
---
- name: Test
hosts: usersevers
tasks:
- name: Copyt file
template:
src: files/example.conf
dest: /etc/httpd/conf.d/example.conf
notify:
- restart apache
- restart vsftp
handlers:
- name: restart apache
service:
name: httpd
state: restarted
- name:restart vsftp
service:
name:vsftpd
state: restarted
...
如果包含 notify 的语句任务没有报告 changed 结果,则处理程序不会获得通知