Ansible循环(loop)
- 简单循环
- 不用循环时编写playbook
[root@localhost ~]# cat test.yml
---
- name: test
hosts: all
tasks:
- name: apche
service:
name : httpd
state: started
- name: vsftpd
service :
name: vsftpd
state: started
当使用循环变量item编写
[root@localhost ~]# cat test.yml
---
- name: test
hosts: all
tasks:
- name: apche and vsftpd
service:
name : '{{ item }}'
state: started
loop :
- httpd
- vsftpd
将变量放入列表
[root@localhost ~]# cat test.yml
---
- name: test
hosts: all
vars:
service:
- httpd
- vsftpd
tasks:
- name: apche and vsftpd
service:
name: '{{ item }}'
state: started
loop: '{{ service }}'
2.循环散列或字典列表
---
- name: Users exist and are in the correct groups
user:
name: "{{ item.name }}"
state: present
groups: "{{ item.groups }}"
loop:
- name: jane
groups: wheel
- name: joe
groups: root
较早样式的循环关键字
with_items的示例如下所示:
vars:
data:
- user0
- user1
- user2
tasks:
- name: "with_items"
debug:
msg: "{{ item }}"
with_items: "{{ data }}"
3.注册变量与loop
---
- name: loop register test
gather_facts: no
hosts: localhost
tasks:
- name: loop echo task
shell: "echo This is my item: {{ item }}"
loop:
- one
- two
register: echo_results #注册变量
- name: Show echo results variable
debug:
var: echo_results #显示变量结果
[root@localhost ~]# cat AA.yml
---
- name: test
hosts: all
gather_facts: no
tasks:
- name: delete user
shell: "echo {{ item }}"
loop:
- one
- two
register: result
- name: print
debug:
msg: "{{ result.results }}"
Ansible条件判断(when)
条件判断:
when的值是一个条件表达式,如果条件判断成立,这个task就执行,如果判断不成立,则task不执行
常见判断符号:
等于(字符串) 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" )
组合循环和有条件的任务
- 示例:只有当vsftpd服务运行时,才能重启Apache
---
- name: 当vsftpd服务运行时,重启Apache 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
实施处理程序
处理程序是响应由其他任务触发的通知的任务
处理程序任务列表的开头:handlers
1. 示例:处理程序
只有在 template 任务通知已发生更改时才会触发
---
- name: test
hosts: all
tasks:
- name: 复制文件
template:
src: files/example.conf #需要在当前目录中编写源配置文件
dest: /etc/httpd/conf.d/example.conf
notify: #notify 语句指出该任务需要触发一个处理程序
- restart apache #程序名
- restart vsftpd
handlers: #表示处理程序任务列表的开头
- name: restart apache #被任务调用的处理程序名称
service: #处理该程序的模块
name: httpd
state: restarted
- name: restart apache
service:
name: httpd
state: restarted
使用处理程序要注意:
- 处理程序始终按照 play 的 handlers 部分指定的顺序运行,不按 notify 里的
- 处理程序通常在相关 play 中所有其他任务运行完后运行
- 处理程序名称存在于个 play 命名空间中(如果两个处理程序同名,只会运行一个)
- 如果多个任务通知处理程序,处理程序也只会运行一次
- 如果包含 notify 的语句任务没有报告 changed 结果,则处理程序不会获得通知
2. 忽略任务失败
关键字ignore_errors
通常 playbook 遇到错误会中止执行,但是有时我们想要失败时也继续执行。此时可以使用关键字ignore_errors忽略任务失败。
示例: 当要安装一个系统中不存在的软件包时,忽略任务失败
- name: Latest version of notapkg is installed
yum:
name: noaaaaabbbbbbcccccc
state: latest
ignore_errors: yes
3.任务失败后强制执行处理程序
关键字:force_handlers:yes
通常任务失败,play 会中止,那么收到 play 中止之前任务通知的处理程序将不会运行;如果要运行,需要使用关键字:force_handlers。
[root@localhost ansible]# cat AAAA.yml
---
- hosts: APP
force_handlers: yes
tasks:
- name: always notify
command: /bin/true
notify: restart apache
- name: fail task
yum:
name: noaaaabbbbbbcccc
state: latest
handlers:
- name: restart apache
service:
name: httpd
state: restarted
尽管任务失败,还是会去执行
[root@localhost ansible]# ansible-playbook -i inventory -i inventory AAAA.yml
PLAY [APP] ***************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.163.134]
TASK [always notify] *****************************************************************************************************************
changed: [192.168.163.134]
TASK [fail task] *********************************************************************************************************************
fatal: [192.168.163.134]: FAILED! => {"changed": false, "failures": ["No package noaaaabbbbbbcccc available."], "msg": "Failed to install some of the specified packages", "rc": 1, "results": []}
RUNNING HANDLER [restart apache] *****************************************************************************************************
changed: [192.168.163.134]
PLAY RECAP ***************************************************************************************************************************
192.168.163.134 : ok=3 changed=2 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
4. 指定任务失败条件
关键字:failed_when
fail 模块可以实现此效果,fail 模块可以提供明确消息
tasks:
- name: Run Script
shell: /usr/local/bin/user.sh
register: command_result
failed_when: "'failure' in command_result.stdout"
#############################使用fail 模块##############################
tasks:
- name: Run Script
shell: /usr/local/bin/user.sh
register: command_result
ignore_error: yes
- name: Report failure
fail:
msg: "Authentication failure" #fail 模块可以提供明确消息
when: "'failure' in command_result.stdout"
5. 指定任务何时报告"Changed"结果
关键字:changed_when:false
简单示例:当执行date命令时,每次都会改变而触发触发器生成changed报告,不想要changed报告就可以添加关键字
- name: get time
shell: date
changed_when: false
6.ansible块和错误处理
可以直接可以添加忽略关键字:ignore_errors: yes
也可以使用 block、rescue、always 将任务分开
- 三种关键字
(1)block:定义要运行的主要任务
(2)rescue:定义要在 block 子句中定义的任务失败时运行的任务
(3)always:定义始终独立运行的任
---
- name: Task Failure
hosts: web
vars:
web_pkg: http #此时错误仍然存在
db_pkg: mariadb-server
db_service: mariadb
tasks:
- name: Set up Web
block: #主要任务
- name: Install {{ web_pkg }} packages
yum:
name: "{{ web_pkg }}"
state: present
rescue: #在block子句中定义的任务失败时运行的任务
- name: Install {{ db_pkg }} packages
yum:
name: "{{ db_pkg }}"
state: present
always: #始终运行的任务
- name: Start {{ db_service }} service
service:
name: "{{ db_service }}"