学习b记 · 第二阶段
十六、Ansible流程控制
1 、playbook条件语句
不管是shell还是各大编程语言中,流程控制,条件判断这些都是必不可少的,在我们使用Ansible的过程中,条件判断的使用频率极其高。
例如:
1 )我们使用不同的系统的时候,可以通过判断系统来对软件包进行安装。
2 )在nfs和rsync安装过程中,客户端服务器不需要推送配置文件,之前我们都是写多个play,会影响效率。
3 )我们在源码安装nginx的时候,执行第二遍就无法执行了,此时我们就可以进行判断是否安装过。
1 、vim
- hosts: webs
tasks:
- name: Yum
yum:
name: wget
state: absent
when: ansible_hostname == "web01"
[ root@m01 ansible]
playbook: when.yml
[ root@m01 ansible]
PLAY [ webs] **********************************************************************************************************
TASK [ Gathering Facts] ***********************************************************************************************
ok: [ 172.16 .1.202]
ok: [ 172.16 .1.204]
TASK [ Yum] ***********************************************************************************************************
skipping: [ 172.16 .1.204]
changed: [ 172.16 .1.202]
PLAY RECAP ***********************************************************************************************************
172.16 .1.202 : ok = 2 changed = 1 unreachable = 0 failed = 0 skipped = 0 rescued = 0 ignored = 0
172.16 .1.204 : ok = 1 changed = 0 unreachable = 0 failed = 0 skipped = 1 rescued = 0 ignored = 0
when判断语法:
when: ansible_hostname == "web01"
when: ansible_hostname != "web01"
when: ansible_hostname is match "web"
when: ansible_hostname is search "web"
when: ansible_hostname is not match "web01"
when: ansible_default_ipv4.address is match "172.16.1.202"
when: ( ansible_default_ipv4.address is match "172.16.1.202" ) or ( ansible_hostname == "web02" )
( ansible_default_ipv4.address is match "172.16.1.202" ) and ( ansible_hostname == "web02" )
when:
- ansible_default_ipv4.address is match "172.16.1.202"
- ansible_hostname == "web02"
when: ansible_facts.distribution_major_version > "6"
[ root@m01 ansible]
- hosts: webs
tasks:
- name: nginx -t
shell: nginx -t
register: result
ignore_errors: yes
- name: print
debug:
msg: "{{ result.rc }}"
- name: Register Nginx Server
systemd:
name: nginx
state: restarted
when: result.rc == "0"
字典循环
在之前的学习过程中,我们经常会有传送文件,创建目录之类的操作,创建2个目录就要写两个file模块来创建,如果要创建100个目录只要有循环即可,减少重复性代码。
1 、[ root@m01 ansible]
- hosts: webs
tasks:
- name: Yum
yum:
name: "{{ item }}"
state: present
loop:
- wget
- tree
2 、[ root@m01 ansible]
- hosts: webs
tasks:
- name: create file
file:
path: /test
state: directory
- name: create file
file:
path: /test/{ { item.name } }
owner: "{{ item.owner }}"
state: touch
loop:
- { name: 1 .txt, owner: www}
- { name: 2 .txt, owner: root}
handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。
在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可。
[ root@m01 ansible]
- name: nginx
hosts: web01
tasks:
- name: configure nginx
copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
notify: Restart Nginx Server
- name: check nginx configure
shell: nginx -t
register: result
ignore_errors: yes
- name: print
debug:
msg: "{{ result }}"
handlers:
- name: Restart Nginx Server
systemd:
name: nginx
state: restarted
when: result is search "ok"
[ root@m01 ansible]
- hosts: webs
tasks:
- include_tasks: a.yml
when: ansible_hostname == "web01"
- include_tasks: b.yml
when: ansible_hostname == "web02"
[ root@m01 ansible]
- name: install present
yum:
name: tree
state: absent
[ root@m01 ansible]
- name: install nfs
yum:
name: nfs-utils
state: absent
被管理主机没有发生变化,可以使用参数将change状态改为ok
[ root@m01 ~]
- hosts: web_group
vars:
- http_port: 8080
force_handlers: yes
tasks:
- name: shell
shell: netstat -lntup| grep httpd
register: check_httpd
changed_when: false
- name: debug
debug: msg = { { check_httpd.stdout.lines } }
[ root@m01 project2]
- hosts: webservers
vars:
- http_port: 8080
tasks:
- name: configure httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf/httpd.conf
notify: Restart Httpd Server
- name: Check HTTPD
shell: /usr/sbin/httpd -t
register: httpd_check
changed_when:
- httpd_check.stdout.find( 'OK' )
- false
- name: start httpd server
service:
name: httpd
state: started
enabled: yes
handlers:
- name: Restart Httpd Server
systemd:
name: httpd
state: restarted
playbook任务标签
默认情况下,Ansible在执行一个playbook时,会执行playbook中定义的所有任务,Ansible的标签( tag) 功能可以给单独任务甚至整个playbook打上标签,然后利用这些标签来指定要运行playbook中的个别任务,或不执行指定的任务。
打标签的方式
1 .对一个task打一个标签
2 .对一个task打多个标签
3 .对多个task打一个标签
打完标签如何使用
-t:执行指定的tag标签任务
–skip-tags:执行–skip-tags之外的标签任务
使用-t指定tag
[ root@m01 m01]
- hosts: web_group
vars:
- http_port: 8080
tasks:
- name: Install Http Server
yum:
name: httpd
state: present
tags:
- install_httpd
- httpd_server
- name: configure httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf/httpd.conf
notify: Restart Httpd Server
tags:
- config_httpd
- httpd_server
- name: start httpd server
service:
name: httpd
state: started
enabled: yes
tags: service_httpd
handlers:
- name: Restart Httpd Server
systemd:
name: httpd
state: restarted
[ root@m01 m01]
[ root@m01 m01]
[ root@m01 m01]
[ root@m01 m01]
playbook忽略错误
默认playbook会检测task执行的返回状态,如果遇到错误则会立即终止playbook的后续task执行,然鹅有些时候playbook即使执行错误了也要让其继续执行。
加入参数:ignore_errors:yes 忽略错误
[ root@m01 ~]
---
- hosts: web_group
tasks:
- name: Ignore False
command: /bin/false
ignore_errors: yes
- name: touch new file
file:
path: /tmp/qxl.txt
state: touch
playbook错误处理
如上所述,当task执行失败时,playbook将不再继续执行,包括如果在task中设置了handler也不会被执行。
但是我们可以采取强制措施…
强制调用handler
[ root@m01 ~]
- hosts: web_group
vars:
- http_port: 8080
force_handlers: yes
tasks:
- name: config httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf
notify:
- Restart Httpd Server
- Restart PHP Server
- name: Install Http Server
yum:
name: htttpd
state: present
- name: start httpd server
service:
name:httpd
state: started
enabled: yes
handlers:
- name: Restart Httpd Server
systemd:
name: httpd
state: restarted
- name: Restart PHP Server
systemd:
name: php-fpm
state: restarted