template中的for和if

在模板文件中可以使用for和if,来实现对模板文件中的内容进行循环和判断。从而实现一个配置文件中的某一段需要被多次引用,或者做判断某一配置段是否需要。

template中的for循环

在ansible的模板文件中可以创建循环,将某配置段中需要变动的值设置为一个变量,将变量中的所有值以列表的形式定义在yaml文件中,当playbook被执行时会从文件中逐个读取值,将配置段进行循环。

template中for的使用

生成以下文件内容,每个server段的监听端口不同其余都相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server{
listen 81
server_name www.a.com
root /app/websitea/
}
server{
listen 82
server_name www.a.com
root /app/websitea/
}
server{
listen 83
server_name www.a.com
root /app/websitea/
}

1.创建模板文件

1
2
3
4
5
6
7
8
9
[root@ansible yaml]# vim templates/test1.j2
{%for i in test_ports %} #创建for循环段,定义变量列表为test_ports
server {
listen {{i}} #将需要改变的port设置为变量
server_name www.a.com
root /app/websitea
}

{%endfor%} #for循环结束

2.创建yaml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@ansible yaml]# vim test1.yaml

---
- hosts: webserver
remote_user: root
vars: #定义变量取值的列表
test_ports:
- 81
- 82
- 83

tasks:
- name: tempate
template: src=test1.j2 dest=/data/test.conf

3.执行脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@ansible yaml]# ansible-playbook test1.yaml

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.132]
ok: [192.168.73.135]
ok: [192.168.73.134]

TASK [tempate] **************************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.132 : ok=2 changed=1 unreachable=0 failed=0
192.168.73.134 : ok=2 changed=1 unreachable=0 failed=0
192.168.73.135 : ok=2 changed=1 unreachable=0 failed=0

4.验证创建出的内容所监听的端口是否为81,82,83

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@mylinuxops ~]# cat /data/test.conf
server {
listen 81
server_name www.a.com
root /app/websitea
}

server {
listen 82
server_name www.a.com
root /app/websitea
}

server {
listen 83
server_name www.a.com
root /app/websitea
}

template中for的实战应用

在上一步中已经实现了让生成的文件中监听端口不相同,在本步骤中需要实现使用for来创建出httpd中的虚拟主机配置段,配置结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server{
listen 81
server_name www.a.com
root /app/websitea
}
server{
listen 82
server_name www.b.com
root /app/websiteb
}
server{
listen 83
server_name www.a.com
root /app/websitec
}

要实现每个循环中的所有配置都不相同,需要使用字典绑定

1.修改模板

1
2
3
4
5
6
7
8
9
10
[root@ansible yaml]# vim templates/test1.j2

{%for i in vhosts %} #配置变量猎豹
server {
listen {{i.port}} #使用以"i.*"的变量,来定义端口,server_name和站点目录
server_name {{i.name}}
root {{i.dir}}
}

{%endfor%}

2.修改剧本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@ansible yaml]# vim test1.yaml
---
- hosts: webserver
remote_user: root
vars: #在变量中定义字典绑定的关系
vhosts:
- web1:
port: 81
name: www.a.com
dir: /data/websitea
- web2:
port: 82
name: www.b.com
dir: /data/websiteb
- web3:
port: 83
name: www.c.com
dir: /data/websitec

tasks:
- name: tempate
template: src=test1.j2 dest=/data/test2.conf

3.执行脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@ansible yaml]# ansible-playbook test1.yaml

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [tempate] **************************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.132 : ok=2 changed=1 unreachable=0 failed=0
192.168.73.134 : ok=2 changed=1 unreachable=0 failed=0
192.168.73.135 : ok=2 changed=1 unreachable=0 failed=0

4.验证所创建出的配置文件是否正确

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@web2 data]# vi test2.conf

server {
listen 81
server_name www.a.com
root /data/websitea
}

server {
listen 82
server_name www.b.com
root /data/websiteb
}

server {
listen 83
server_name www.c.com
root /data/websitec
}

template中的if

if可以判断变量是否定义,定了就引用,若是没有定义则不引用

if的使用方法

此处依旧以上一部为例,在模板中添加判断来创建出以下配置段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 81
root /data/websitea
}

server {
listen 82
root /data/websiteb
}

server {
listen 83
server_name www.c.com
root /data/websitec
}

要创建出没有server_name的配置段只需要对server_name所对应的变量做判断,判断此变量是否被定义,如果此变量没有被定义则不会应用此变量,输出为空。

1.修改模板

1
2
3
4
5
6
7
8
9
10
11
12
[root@ansible yaml]# vim templates/test1.j2

{%for i in vhosts %}
server {
listen {{i.port}}
{%if i.name is defined %} #在server_name段添加判断,判断变量是否被定义
server_name {{i.name}}
{%endif%}
root {{i.dir}}
}

{%endfor%}

2.修改yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@ansible yaml]# vim test1.yaml

---
- hosts: webserver
remote_user: root
vars:
vhosts:
- web1:
port: 81
#name: www.a.com #将name注释,此时变相没有设定,将不引用
dir: /data/websitea
- web2:
port: 82
#name: www.b.com
dir: /data/websiteb
- web3:
port: 83
name: www.c.com
dir: /data/websitec

tasks:
- name: tempate
template: src=test1.j2 dest=/data/test2.conf

3.执行剧本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@ansible yaml]# ansible-playbook test1.yaml

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.73.135]
ok: [192.168.73.132]
ok: [192.168.73.134]

TASK [tempate] **************************************************************************************************
changed: [192.168.73.132]
changed: [192.168.73.135]
changed: [192.168.73.134]

PLAY RECAP ******************************************************************************************************
192.168.73.132 : ok=2 changed=1 unreachable=0 failed=0
192.168.73.134 : ok=2 changed=1 unreachable=0 failed=0
192.168.73.135 : ok=2 changed=1 unreachable=0 failed=0

验证远程主机上输出的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@ansible yaml]# ansible webserver -a "cat /data/test2.conf"
192.168.73.132 | CHANGED | rc=0 >>
server {
listen 81 #输出的文件内容中梅有server_name行
root /data/websitea
}

server {
listen 82
root /data/websiteb
}

server {
listen 83
server_name www.c.com
root /data/websitec
}