template
# 概念介绍
一种文本文件
嵌套有脚本(使用模板编程语言编写) 借助模板生成真正的文件
通过替换模板文件中的变量,生成不同的文件,实现一些简单的逻辑
使用场景:针对不同的服务器,使用不同参数的配置文件,需要建立一个文件的模板,对不同的服务变化不同的参数
使用Jinja2语言语法
- 定义字面量,有如下形式
- 字符串:使用单引号或双引号
- 数字:整数,浮点数
- 列表:[item1, item2, ...]
- 元组:(item1, item2, ...)
- 字典:{key1:value1, key2:value2, ...}
- 布尔型:true/false
- 算术运算:+, -, *, / 有小数点, // 整除 , % 取得余, ** 次方
- 比较操作:==, !=, >, >=, <, <=
- 逻辑运算:and,or,not
- 流表达式:For,If,When
- 定义字面量,有如下形式
使用ansible的template模块实现模板功能
# template模块介绍
根据模块文件动态生成对应的配置文件 注意:只能用于ansible-playbook命令,不能用于ansible命令
查看说明
ansible-doc -s template
使用说明
- template文件必须存放于templates目录下,且命名为 .j2 结尾
- yaml/yml 文件需和templates目录平级,目录结构如下
./
├── my-playbook.yml
└── templates
└── xx.j2
2
3
4
# 应用实例:安装nginx
使用创建nginx服务,示例templates的使用,不同的服务器使用不同的nginx配置
# 获取nginx配置
先在一台机器上安装nginx服务,然后查看配置文件
yum -y install nginx
查看安装目录
[root@linux101 ~]# rpm -ql nginx
/etc/logrotate.d/nginx
/etc/nginx/fastcgi.conf
/etc/nginx/fastcgi.conf.default
/etc/nginx/fastcgi_params
/etc/nginx/fastcgi_params.default
/etc/nginx/koi-utf
/etc/nginx/koi-win
...
/etc/nginx/nginx.conf
...
2
3
4
5
6
7
8
9
10
11
注意:安装nginx需要EPL源头
yum repolist # 查看是否有EPL源,给安装nginx做准备
# 如果没有,则需要安装epel
yum install -y epel-release
2
3
查看配置
- 注意worker_processes参数的配置,工作进程配置,auto是按照当前主机的内核个数配置工作进程数
[root@linux101 ~]# cat /etc/nginx/nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
启动nginx服务
- 查看 master process 和 worker process 进程个数
[root@linux101 ~]# systemctl start nginx
[root@linux101 ~]# ps aux | grep nginx
root 34236 0.0 0.0 39308 1052 ? Ss 10:17 0:00 nginx: master process /usr/sbin/nginx
nginx 34237 0.0 0.0 41780 1928 ? S 10:17 0:00 nginx: worker process
nginx 34238 0.0 0.0 41780 1940 ? S 10:17 0:00 nginx: worker process
nginx 34239 0.0 0.0 41780 1940 ? S 10:17 0:00 nginx: worker process
...
2
3
4
5
6
7
# 创建templates文件夹
创建templates文件夹,要求和playbook执行的yml文件在同一目录下
[root@linux101 ansible-demo]# mkdir templates
[root@linux101 ansible-demo]# cp /etc/nginx/nginx.conf /opt/ansible-demo/templates/nginx.conf.j2
2
# 编辑执行的yml文件
创建nginx-deploy.yml文件,如果nginx.conf.j2没有放在相对路径的templates目录下,那么src需要配置绝对路径
[root@linux101 ansible-demo]# cat nginx-deploy.yml
- hosts: app
remote_user: root
tasks:
- name: install package
yum: name=nginx
- name: copy template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
- name: start service
service: name=nginx state=started enabled=yes # enabled yes表示开机启动
2
3
4
5
6
7
8
9
10
11
# 执行安装
执行检查playbook.yml文件命令
ansible-playbook -C nginx-deploy.yml
执行
ansible-playbook nginx-deploy.yml
# 检查安装结果
ansible app -m shell -a 'rpm -q nginx'
ansible app -m shell -a 'ss -ntpl' #查看端口以及进程
ansible app -m shell -a 'ps aux | grep nginx'
2
3
# 新需求:nginx work进程是服务器内核数的一半
通过setup模块找到cpu的个数,查看属性 ansible_processor_vcpus
[root@linux101 ansible-demo]# ansible app -m setup | grep 'processor'
"ansible_processor": [
"ansible_processor_cores": 8,
"ansible_processor_count": 2,
"ansible_processor_threads_per_core": 1,
"ansible_processor_vcpus": 16,
...
2
3
4
5
6
7
编辑nginx.confi.j2
注意:需要使用//
整除,得到整数,如果使用 /
则获得的是浮点数,会导致nginx的配置文件出错
[root@linux101 templates]# cat nginx.conf.j2
...
user nginx;
worker_processes {{ ansible_processor_vcpus//2 }};
...
}
2
3
4
5
6
修改playbook,添加handler,在修改配置文件后,notify重启服务,编辑nginx-deploy.yml文件
[root@linux101 ansible-demo]# cat nginx-deploy.yml
- hosts: app
remote_user: root
tasks:
- name: install package
yum: name=nginx
- name: copy template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart service
- name: start service
service: name=nginx state=started enabled=yes
handlers:
- name: restart service
service: name=nginx state=restarted
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
重新执行
[root@linux101 ansible-demo]# ansible-playbook nginx-deploy.yml
查看进程数量
ansible app -m shell -a 'ps aux|grep nginx'
# 新需求:使用自定义变量设置端口号
在主机清单中给不同的机器设置不同的端口号,作为nginx访问使用的端口号 编辑/etc/ansible/hosts中添加端口号
[app]
192.168.10.102 http_port=8081
192.168.10.103 http_port=8082
192.168.10.104 http_port=8083
2
3
4
在templates/nignx.conf.j2中使用http_port变量
user nginx;
worker_processes {{ ansible_processor_vcpus//2 }};
...
http {
...
server {
listen {{ http_port }}; # 配置http_port
listen [::]:{{ http_port }};
server_name _;
root /usr/share/nginx/html;
...
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
执行命令
ansible-playbook nginx-deploy.yml
注意:如果nginx出现了 bind() to 0.0.0.0:8082 failed (13: Permission denied),那么需要关闭selinux,临时方式如下 如果需要永久关闭selinux,请编辑/etc/selinux/config文件,将SELINUX=disabled。之后将系统重启一下即可
[root@linux103 nginx]# getenforce
Enforcing
[root@linux103 nginx]# setenforce 0
[root@linux103 nginx]# getenforce
Permissive
2
3
4
5
查看执行结果
ansible app -m shell -a 'ss -ntpl'
如果在nginx-deploy.yml中定义变量,那么playbook的执行配置文件中优先级最高
- hosts: app
remote_user: root
vars:
- http_port: 8088
tasks:
- name: install package
yum: name=nginx
- name: copy template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart service
- name: start service
service: name=nginx state=started enabled=yes
handlers:
- name: restart service
service: name=nginx state=restarted
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在playbook的template中,针对模板文件,以.j2结尾的文件中使用
# template中使用for
语法 {% for item in vars %} xxx {% endfor %}
# 键值对
定义变量
- hosts: app
remote_user: root
vars:
nginx_vhosts:
- listen: 8080 #列表 键值对
2
3
4
5
在templates/nginx.conf.j2文件中使用
{% for vh in nginx_vhosts %}
server { #重复执行server代码
listen {{ vh.listen | default('80 default_server') }};
...
}
{% endfor %}
2
3
4
5
6
7
生成结果
server {
listen 8080
}
2
3
# 列表
定义变量
- hosts: mageduweb
remote_user: root
vars:
nginx_vhosts:
- web1
- web2
- web3
tasks:
- name: template config
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
2
3
4
5
6
7
8
9
10
在templates/nginx.conf.j2文件中使用列表变量
{% for vh in nginx_vhosts %}
server {
listen {{ vh }}
}
{% endfor %}
2
3
4
5
生成结果
server {
listen web1
}
server {
listen web2
}
server {
listen web3
}
2
3
4
5
6
7
8
9
# template中使用if
语法 {% if 判断条件 %} xxx {% endif %}
定义变量
- hosts: app
remote_user: root
vars:
nginx_vhosts:
- listen: 8080 #列表 键值对
2
3
4
5
使用变量
{% for vh in nginx_vhosts %}
server { #重复执行server代码
listen {{ vhost.listen | default('80 default_server') }};
{% if vh.server_name is defined %}
server_name {{ vhost.server_name }};
{% endif %}
{% if vh.root is defined %}
root {{ vhost.root }};
{% endif %}
}
{% endfor %}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 应用实例:使用for与if
编写playbook的执行yaml文件,app.yaml
- hosts: app
remote_user: root
vars:
nginx_vhosts:
- web1:
listen: 8080
root: '/var/www/stt/web1'
- web2:
listen: 8080
server_name: web2.stt.com
root: '/var/www/stt/web2'
- web3:
listen: 8080
server_name: web3.stt.com
root: '/var/www/stt/web3'
tasks:
- name: template config to
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
编写 nginx.conf.j2文件
{% for vh in nginx_vhosts %}
server {
listen {{ vh.listen }}
{% if vh.server_name is defined %}
server_name {{ vh.server_name }}
{% endif %}
root {{ vh.root }}
}
{% endfor %}
2
3
4
5
6
7
8
9
生成结果
server {
listen 8080
root /var/www/stt/web1/
}
server {
listen 8080
server_name: web2.stt.com
root /var/www/stt/web2/
}
server {
listen 8080
server_name: web3.stt.com
root /var/www/stt/web3/
}
2
3
4
5
6
7
8
9
10
11
12
13
14