学习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