[toc]

Playbook条件语句

  1. 我们使用不同的系统的时候,可以通过判断系统来对软件包进行安装。
  2. 在nfs和rsync安装过程中,客户端服务器不需要推送配置文件,之前我们都是写多个play,会影响效率。
  3. 我们在源码安装nginx的时候,执行第二遍就无法执行了,此时我们就可以进行判断是否安装过。

ansible_facts[‘os_family’]自动识别系统的变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 当满足什么条件的时候执行哪些task
when # 当满足指定条件的时候执行

# 根据不同的操作系统安装apache
# 示例:
- hosts: web_group
tasks:
- name: Install CentOS Httpd
yum:
name: httpd
state: present
#官方
when: ansible_facts['os_family'] == "CentOS"
#非官方
when: ansible_distribution == "CentOS"

- name: Install Ubuntu Httpd
yum:
name: apache2
state: present
when: ansible_facts['os_family'] == "Ubuntu"

ansible_hostname自动识别主机名的变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 主机名显示范围
ansible_hostname # 只显示第一段主机名;
ansible_fqdn # 显示完整的主机名

# 根据不同的主机名安装软件
# 示例:
- hosts: rsyncd_nfs
# ather_facts: False
tasks:
- name: 安装rsync和nfs服务
yum:
name:
- rsync
- nfs-utils
state: present

- name: 推送配置文件
template:
src: /root/wordpress_ansible/rsync/rsyncd.conf
dest: /etc
when: ansible_hostname == 'backup'

使用括号对条件进行分组

1
2
3
4
5
# 条件判断分组示例:
tasks:
- name: "shut down CentOS 6 and Debian 7 systems"
command: /sbin/shutdown -t now
when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or (ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7")

指定多条件为列表

1
2
3
4
5
6
7
# 多条件判断示例:
tasks:
- name: "shut down CentOS 6 systems"
command: /sbin/shutdown -t now
when:
- ansible_facts['distribution'] == "CentOS"
- ansible_facts['distribution_major_version'] == "6"

条件运算

1
2
3
4
# 条件运算示例:
tasks:
- shell: echo "only on Red Hat 6, derivatives, and later"
when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release']|int >= 6

playbook循环语句

传送文件、创建目录之类的操作,写两个file模块来创建2个目录,如果要创建100个目录,我们使用循环即可,减少重复性代码。

定义变量循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 常用语法
with_items: # 创建变量列表
{{ item }} # 引用变量

# 示例:
## 启动多个服务 使用items引用变量
- hosts: web_group
tasks:
- name: ensure a list of packages installed
yum:
name= "{{ item }}"
state=present
with_items:
- httpd
- httpd-tools

## 启动多个服务 使用vars引用变量
- hosts: web_group
tasks:
- name: ensure a list of packages installed
yum:
name: "{{ packages }}"
vars:
packages:
- httpd
- httpd-tools

字典循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 常用语法
with_items: # 创建变量列表
{{ item }} # 引用变量

# 示例:
## 推送文件示例
- hosts: all
tasks:
- name: 推送nginx主配置 网站配置
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
with_items:
- {src: "/root/wordpress_ansible/nginx_php/nginx.conf",dest: '/etc/nginx'}
- {src: "/root/wordpress_ansible/nginx_php/blog.xxx.com.conf",dest:/etc/nginx/conf.d}
when: ansible_hostname is match 'web*'

## 创建用户示例
- hosts: web_group
tasks:
- name: Add Users
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
state: present
with_items:
- { name: 'zls', groups: 'linux' }
- { name: 'egon', groups: 'python' }

## 拷贝文件示例
- hosts: web_group
tasks:
- name: copy conf and code
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
with_items:
- { src: "./httpd.conf", dest: "/etc/httpd/conf/", mode: "0644" }
- { src: "./upload_file.php", dest: "/var/www/html/", mode: "0600" }

playbook handlers(触发器)

什么是handlers?

handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。
在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可。

handlers(触发器)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 常用语法
notify # 监控,监控文件发生变更后引用handlers
handlers # 触发器,handlers被触发后进行的动作

# 示例:
## 推送的配置文件发生变更时重启服务
- hosts: all
tasks:
- name: 推送nginx主配置 网站配置
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
with_items:
- {src: "/root/wordpress_ansible/nginx_php/nginx.conf",dest: '/etc/nginx'}
- {src: "/root/wordpress_ansible/nginx_php/blog.xxx.com.conf",dest:/etc/nginx/conf.d}
when: ansible_hostname is match 'web*'
notify: xxx

handlers:
- name: xxx
service:
name: nginx
state: restarted
enabled: True

注意:

1.无论多少个task通知了相同的handlers,handlers仅会在所有tasks结束后运行一次。

2.Handlers只有在其所在的任务被执行时,才会被运行;如果一个任务中定义了notify调用Handlers,但是由于条件判断等原因,该任务未被执行,那么Handlers同样不会被执行。

3.Handlers只会在每一个play的末尾运行一次;如果想在一个playbook中间运行Handlers,则需要使用meta模块来实现。例如: -meta: flush_handlers。

4.如果一个play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用meta模块的–force-handlers选项来强制执行Handlers,即使Handlers所在的play中途运行失败也能执行。

5.不能使用handlers替代tasks

playbook任务标签

什么是任务标签

默认情况下,Ansible在执行一个playbook时,会执行playbook中定义的所有任务,Ansible的标签(tag)功能可以给单独任务甚至整个playbook打上标签,然后利用这些标签来指定要运行playbook中的个别任务,或不执行指定的任务。

打标签的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# 常用语法:
-t # 指定tag(调用标签)
-skip-tags # 执行--skip-tags之外的标签任务

# 对一个task打一个标签
## 创建标签
- hosts: rsyncd_nfs
tasks:
- name: 安装rsync和nfs服务
yum:
name:
- rsync
- nfs-utils
state: present
tags: useradd
## 调用标签
ansible-playbook lnmp.yml -i base/hosts -t useradd

# 对一个task打多个标签
- hosts: rsyncd_nfs
tasks:
- name: 安装rsync和nfs服务
yum:
name:
- rsync
- nfs-utils
state: present
tags:
- useradd
- adduser
## 调用标签
ansible-playbook lnmp.yml -i base/hosts -t useradd
ansible-playbook lnmp.yml -i base/hosts -t adduser

# 对多个task打一个标签
- hosts: rsyncd_nfs
tasks:
- name: 安装rsync和nfs服务
yum:
name:
- rsync
- nfs-utils
state: present
tags:
- useradd
- adduser

- hosts: backup
tasks:
- name: 推送rsyncd.conf文件
copy:
src: /root/wordpress_ansible/rsync/rsyncd.conf
dest: /etc
tags: useradd
## 调用标签
ansible-playbook lnmp.yml -i base/hosts -t useradd

playbook复用

什么是playbook复用?

在写playbook的过程中,我们发现,写多个playbook没有办法,一键执行,这样我们还要单个playbook挨个去执行,很鸡肋。所以在playbook中有一个功能,叫做include用来动态调用task任务列表。

img

playbook复用使用详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 常用语法
include_tasks # 只调用task:
include # 调用整个task文件(新版本:import_playbook)
top file # saltstack中,叫做入口文件。

# 示例:
## 主文件调用tasks
- hosts: web_group
tasks:
- include_tasks: task_install.yml
- include_tasks: task_useradd.yml

## task文件安装httpd
vim task_install.yml
- name: Install Http Server
yum:
name: httpd
state: present

## task文件创建用户
vim task_useradd.yml
- name: useradd
user:
name: yyy
uid: 777
state: present

playbook忽略错误

什么是忽略错误?

默认playbook会检测task执行的返回状态,如果遇到错误则会立即终止playbook的后续task执行,然而有些时候playbook即使执行错误了也要让其继续执行。

忽略错误实操

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 常用语法:
ignore_errors:yes # 忽略错误

# 示例:
# 即使出错也继续执行
vim ignore.yml
- hosts: web_group
tasks:
- name: Ignore False
command: /bin/false
ignore_errors: yes

- name: touch new file
file:
path: /tmp/zls.txt
state: touch

playbook错误处理

如上所述,当task执行失败时,playbook将不再继续执行,包括如果在task中设置了handler也不会被执行。 但是我们可以采取强制措施…

强制调用handler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 常用语法:
force_handlers: yes # 强制执行handler(即使出错)

# 示例
## 即使出错也执行handler
vim handler.yml
- 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

抑制changed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 常用语法:
changed_when: false

# 示例:
## 被管理主机没有发生变化,可以使用参数将change状态改为ok
vim handler.yml
- hosts: web_group
vars:
- http_port: 8080
force_handlers: yes
tasks:
- name: shell
shell: netstat -lntup|grep httpd
register: check_httpd

- name: debug
debug: msg={{ check_httpd.stdout.lines }}