ansible使用jinja2管理配置文件以及jinja2语法简介
一、Jinja2介绍
Jinja2是基于python的模板引擎,功能比较类似于PHP的smarty,J2ee的Freemarker和velocity。它能完全支持unicode,并具有集成的沙箱执行环境,应用广泛。jinja2使用BSD授权
Jinja2的语法是由variables(变量)和statement(语句)组成,如下;
1、variables:可以输出数据
{{ my_variables }}
{{ some_dudes_name | capitalize }}
2、statements: 可以用来创建条件和循环等
1
2
3
4
5
6
7
8
9
|
if 语句: {% if my_conditional %} ... {% endif %} for 语句: {% for item in all_items %} {{item}} …… {% endfor %} |
从上面第二个variables的例子中可以看出,jinja2支持使用带过滤器的Unix型管道操作符,有很多的内置过滤器可供使用。我们可以仅仅用一堆简单if和for就可以建立几乎任何的常规配置文件,不过如果你有意更进一步,jinja2 documentation (http://jinja.pocoo.org/docs/dev/)包含了很多有趣的东西可供了解。我们可以看到ansible允许在模板中使用诸如绘制时间此类的一些额外的模板变量
第一个例子:引用变量
1
2
3
4
5
6
7
8
9
10
11
|
#cd roles/template/ . ├── meta │ └── main.yml ├── tasks │ ├── template.yml │ └── main.yml ├── templates │ ├── order.j2 └── vars └── main.yml |
总调度yml文件:
1
2
3
4
5
6
7
|
#cat templates.yml --- - hosts: 10.0.90.27 user: root gather_facts: false roles: - role: template |
注意:这里 - role: template 和 - template 是一样的!
其他yml文件,如下:
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
|
#cat tasks/main.yml - include: template.yml #cat tasks/template.yml - name: create {{ PROJECT }} directory file : dest= /data/ {{ PROJECT }} state=directory - name: template transfor java dir template: src=order.j2 dest= /data/ {{ PROJECT }} /order .conf #cat templates/order.j2 project: {{ PROJECT }} switch: {{ SWITCH }} dbport: {{ DBPORT }} #cat vars/main.yml PROJECT: "JAVA" SWITCH: "ON" DBPORT: "8080" 测试: # ansible-playbook templates.yml --syntax-check playbook: templates.yml 执行: # ansible-playbook templates.yml PLAY [10.0.90.27] ************************************************************** TASK [template : include] *************************************************** included: /etc/ansible/roles/template/tasks/template .yml for 10.0.90.27 TASK [template : create JAVA directory] ************************************* changed: [10.0.90.27] TASK [template : template transfor java dir ] ******************************** changed: [10.0.90.27] PLAY RECAP ********************************************************************* 10.0.90.27 : ok=3 changed=2 unreachable=0 failed=0 到10.0.90.27查看结果 #cat /data/JAVA/order.conf project: JAVA switch: ON dbport: 8080 |
第二个例子:for 语句
为远程主机生成服务器列表,加入该列表从192.168.13.201 web01.test.com 到192.168.13.211 web11.test.com 结束,如果手动添加就很不科学了,这里需要使用jinja2语法的for循环通过模板批量生成对应的配置文件,如下:
ansible目录结构:
1
2
3
4
5
6
7
8
9
10
11
|
#cd /etc/ansible/roles/test_hosts . ├── meta │ └── main.yml ├── tasks │ ├── file1.yml │ └── main.yml ├── templates │ └── test1.j2 └── vars └── main.yml |
各个目录下yml文件内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# cat tasks/file1.yml - name: ansible jinja2 template for hosts config template: src=test1.j2 dest= /etc/httpd/conf/httpd .conf. test # cat tasks/main.yml - include: file1.yml # cat templates/test1.j2 {% for id in range(201,212) %} 192.168.13.{{ id }} web{{ "%03d" | format ( id -200) }}. test .com {% endfor %} 解释: {{ id }} 提取 for 循环中对应的变量 id 值 "%02d" 调用的是python内置的字符串格式化输出(%d格式化整数)因为是01,02这种格式,所以是保留2位,故用02 然后将结果通过管道符 “|” 传递给 format 函数做二次处理。 |
执行结果:
1
2
3
4
5
6
7
8
9
10
11
12
|
#cat httpd.conf.test 192.168.13.201 web01. test .com 192.168.13.202 web02. test .com 192.168.13.203 web03. test .com 192.168.13.204 web04. test .com 192.168.13.205 web05. test .com 192.168.13.206 web06. test .com 192.168.13.207 web07. test .com 192.168.13.208 web08. test .com 192.168.13.209 web09. test .com 192.168.13.210 web10. test .com 192.168.13.211 web11. test .com |
第三个例子:if语句
说明:如果定义端口号,就绑定定义的端口号,如果不定义端口号,就绑定默认端口号
1
2
3
4
5
6
7
8
9
10
11
|
ansible目录结果 #cd /etc/ansible/roles/mysql_cnf #tree . ├── meta │ └── main.yml ├── tasks │ └── main.yml ├── templates │ └── test3.j2 └── vars |
主要的yml文件是templates目录下面的test3.j2
1
2
3
4
5
6
|
# cat templates/test3.j2 {% if PORT %} bind_address=10.0.90.27:{{ PORT }} {% else %} bind_address=10.0.90.27:3306 {% endif %} |
playbook主文件
1
2
3
4
5
6
7
8
9
10
|
# cat jinj2_test.yml --- - hosts: 10.0.90.27 user: root gather_facts: false vars: PORT: 3136 tasks: - name: copy file to client template: src= /etc/ansible/roles/mysql_cnf/templates/test3 .j2 dest= /root/my .cnf |
执行:
1
2
3
4
5
6
|
# ansible-playbook jinj2_test.yml PLAY [10.0.90.27] ************************************************************** TASK [copy file to client] ***************************************************** changed: [10.0.90.27] PLAY RECAP ********************************************************************* 10.0.90.27 : ok=1 changed=1 unreachable=0 failed=0 |
查看
1
2
|
# cat my.cnf bind_address=10.0.90.27:3136 |
如果将vars变量去掉,执行结果:
1
2
3
4
5
6
7
8
9
10
|
# cat jinj2_test.yml --- - hosts: 10.0.90.27 user: root gather_facts: false vars: PORT: false tasks: - name: copy file to client template: src= /etc/ansible/roles/mysql_cnf/templates/test3 .j2 dest= /root/my .cnf |
查看:
1
2
|
# cat my.cnf bind_address=10.0.90.27:3306 |
3、Jinja default()设定
精通程序编码的朋友皆知,default()默认值的设定有助于程序的健壮性和简洁性。所幸Jinja也支持该功能,上面的例子中生成Mysql配置文件中的端口定义,如果指定则PORT=3136,否则PORT=3306,我们将该案例改造为使用default()试试
编辑/etc/ansible/roles/mysql_cnf/templates/test3.j2内容如下,这种方法更简介。
bind_address=10.0.90.27:{{ PORT | default(3306) }}
二、ansible使用jiaja2生成apache多主机配置
1、创建目录,创建好之后如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#cd /etc/ansible/roles/apache_conf # tree ./ ./ ├── meta │ └── main.yml ├── tasks │ ├── file .yml │ └── main.yml ├── templates │ └── apache.config.j2 └── vars └── main.yml 4 directories, 5 files |
2、创建tasks调度文件,如下:
1
2
3
4
5
|
#cat file.yml - name: ansible jinja2 template for apache config template: src=apache.config.j2 dest= /etc/httpd/conf/httpd .conf.template #cat main.yml - include: file .yml |
3、创建apache的jinja2模板文件,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#cat apache.config.j2 NameVirtualHost *:80 {% for vhost in apache_vhost %} <VirtualHost *:80> ServerName {{ vhost.servername }} DocumentRoot {{ vhost.documentroot }} {% if vhost.serveradmin is defined %} ServerAdmin {{ vhost.serveradmin }} {% endif %} <Directory "{{ vhost.documentroot }}" > AllowOverride All Options -Indexes FollowSymLinks Order allow,deny Allow from all </Directory> </VirtualHost> {% endfor %} |
4、创建变量,如下:
1
2
3
4
|
#cat vars/main.yml apache_vhost: - {servername: "apache.test1.com" , documentroot: "/data/test1/" } - {servername: "apache.test2.com" , documentroot: "/data/test2/" } |
5、创建总调度yml文件,如下:
1
2
3
4
5
6
7
|
#cat /etc/ansible/apache_test.yml --- - hosts: 10.0.90.27 user: root gather_facts: no roles: - { role: apache_conf } |
6、测试:
1
2
3
|
#ansible-playbook apache_test.yml --syntax-check playbook: apache_test.yml |
7、执行测试
1
2
3
4
5
6
7
8
|
#ansible-playbook apache_test.yml PLAY [10.0.90.27] ************************************************************** TASK [apache_conf : include] *************************************************** included: /etc/ansible/roles/apache_conf/tasks/file .yml for 10.0.90.27 TASK [apache_conf : ansible jinja2 template for apache config] ***************** changed: [10.0.90.27] PLAY RECAP ********************************************************************* 10.0.90.27 : ok=2 changed=1 unreachable=0 failed=0 |
8、到客户端查看
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#cat httpd.conf.template NameVirtualHost *:80 <VirtualHost *:80> ServerName apache.test1.com DocumentRoot /data/test1/ <Directory "/data/test1/" > AllowOverride All Options -Indexes FollowSymLinks Order allow,deny Allow from all < /Directory > < /VirtualHost > <VirtualHost *:80> ServerName apache.test2.com DocumentRoot /data/test2/ <Directory "/data/test2/" > AllowOverride All Options -Indexes FollowSymLinks Order allow,deny Allow from all < /Directory > < /VirtualHost > |
三、ansible使用jiaja2生成nginx一个模板多种不同配置
说明:为2台Nginx Proxy,1台Nginx Web通过一套模板生成对应的配置
1、ansible目录结构:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# cd roles/nginx_conf/ #tree . ├── files ├── meta │ └── main.yml ├── tasks │ ├── file .yml │ └── main.yml ├── templates │ └── nginx.conf.j2 └── vars └── main.yml |
2、tasks目录下文件内容:
1
2
3
4
5
|
#cat tasks/file.yml - name: nginx.j2 template transfer example template: src=nginx.conf.j2 dest= /etc/nginx/nginx .conf.template #cat tasks/main.yml - include: file .yml |
3、nginx模板文件
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
|
#cat templates/nginx.conf.j2 {% if nginx_use_proxy %} {% for proxy in nginx_proxies %} upstream {{ proxy.name }} #server 127.0.0.1:{{ proxy.port }}; server {{ ansible_eth0.ipv4.address }}:{{ proxy.port }}; } {% endfor %} {% endif%} server { listen 80; servername {{ nginx_server_name }}; access_log off; error_log /etc/nginx/nginx_error .log; rewrite ^ https: // $server_name$request_uri? permanent; } server { listen 443 ssl; server_name {{ nginx_server_name }}; ssl_certificate /etc/nginx/ssl/ {{ nginx_ssl_cert_name }}; ssl_certificate_key /etc/nginx/ssl/ {{ nginx_ssl_cert_key }}; root {{ nginx_web_root }}; index index.html index.html; {% if nginx_use_auth %} auth_basic "Restricted" ; auth_basic_user_file /etc/nginx/ {{ project_name }}.htpasswd; {% endif %} {% if nginx_use_proxy %} {% for proxy in nginx_proxies %} location {{ proxy.location }} { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto http; proxy_set_header X-Url-Scheme $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true ; proxy_redirect off; proxy_pass http: // {{ proxy.name }}; break ; } {% endfor %} {% endif %} {% if nginx_server_static %} location / { try_files $url $url/ =404; } {% endif %} } |
4、ansible变量文件
1
2
3
4
5
6
7
8
9
10
|
cat vars /main .yml nginx_server_name: www.testnginx.com nginx_web_root: /data/html/ nginx_proxies: - name: suspicious location: / port: 1234 - name: suspicious-api location: /api port: 4567 |
ansible主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
|
#cat nginx_test.yml ##The first roles - name: Nginx Proxy Server's Config Dynamic Create hosts: "10.0.90.25:10.0.90.26" remote_user: root vars: nginx_use_proxy: true nginx_ssl_cert_name: ifa.crt nginx_ssl_cert_key: ifa.key nginx_use_auth: true project_name: suspicious nginx_server_static: true gather_facts: true roles: - role: nginx_conf ##The second roles - name: Nginx WebServer's Config Dynamic Create hosts: 10.0.90.27 remote_user: root vars: nginx_use_proxy: false nginx_ssl_cert_name: ifa.crt nginx_ssl_cert_key: ifa.crt nginx_use_auth: false project_name: suspicious nginx_server_static: false gather_facts: false roles: - role: nginx_conf |
5、测试并执行:
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
|
#ansible-playbook nginx_test.yml --syntax-check playbook: nginx_test.yml 执行: # ansible-playbook nginx_test.yml PLAY [Nginx Proxy Server's Config Dynamic Create] ****************************** TASK [setup] ******************************************************************* ok: [10.0.90.25] ok: [10.0.90.26] TASK [nginx_conf : include] **************************************************** included: /etc/ansible/roles/nginx_conf/tasks/file .yml for 10.0.90.25, 10.0.90.26 TASK [nginx_conf : nginx.j2 template transfer example] ************************* changed: [10.0.90.26] changed: [10.0.90.25] PLAY [Nginx WebServer's Config Dynamic Create] ********************************* TASK [nginx_conf : include] **************************************************** included: /etc/ansible/roles/nginx_conf/tasks/file .yml for 10.0.90.27 TASK [nginx_conf : nginx.j2 template transfer example] ************************* changed: [10.0.90.27] PLAY RECAP ********************************************************************* 10.0.90.25 : ok=3 changed=1 unreachable=0 failed=0 10.0.90.26 : ok=3 changed=1 unreachable=0 failed=0 10.0.90.27 : ok=2 changed=1 unreachable=0 failed=0 |
6、查看检测执行结果
到Nginx Proxy 服务器查看配置文件
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
|
#cat nginx.conf.template upstream suspicious #server 127.0.0.1:1234; server 10.0.90.26:1234; } upstream suspicious-api #server 127.0.0.1:4567; server 10.0.90.26:4567; } server { listen 80; servername www.testnginx.com; access_log off; error_log /etc/nginx/nginx_error .log; rewrite ^ https: // $server_name$request_uri? permanent; } server { listen 443 ssl; server_name www.testnginx.com; ssl_certificate /etc/nginx/ssl/ifa .crt; ssl_certificate_key /etc/nginx/ssl/ifa .key; root /data/html/ ; index index.html index.html; auth_basic "Restricted" ; auth_basic_user_file /etc/nginx/suspicious .htpasswd; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto http; proxy_set_header X-Url-Scheme $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true ; proxy_redirect off; proxy_pass http: //suspicious ; break ; } location /api { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto http; proxy_set_header X-Url-Scheme $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true ; proxy_redirect off; proxy_pass http: //suspicious-api ; break ; } location / { try_files $url $url/ =404; } } |
到Nginx Web 服务器上查看配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#cat nginx.conf.template server { listen 80; servername www.testnginx.com; access_log off; error_log /etc/nginx/nginx_error .log; rewrite ^ https: // $server_name$request_uri? permanent; } server { listen 443 ssl; server_name www.testnginx.com; ssl_certificate /etc/nginx/ssl/ifa .crt; ssl_certificate_key /etc/nginx/ssl/ifa .crt; root /data/html/ ; index index.html index.html; } |
到这里,就结束了。用同样的模板通过简单的if和变量设置就可以完成不同类型主机的Nginx conf配置,所以一方面在了解Ansible强大的模板功能的同时,也需要看到模板质量的重要性。
ansible使用jinja2管理配置文件以及jinja2语法简介的更多相关文章
- Ansible 小手册系列 十三(Jinja2)
用于playbook中的jinja 2过滤器 更改数据格式,其结果是字符串 {{ some_variable | to_json }} {{ some_variable | to_yaml }} 对于 ...
- Linux centosVMware 自动化运维Ansible介绍、Ansible安装、远程执行命令、拷贝文件或者目录、远程执行脚本、管理任务计划、安装rpm包/管理服务、 playbook的使用、 playbook中的循环、 playbook中的条件判断、 playbook中的handlers、playbook实战-nginx安装、管理配置文件
一.Ansible介绍 不需要安装客户端,通过sshd去通信 基于模块工作,模块可以由任何语言开发 不仅支持命令行使用模块,也支持编写yaml格式的playbook,易于编写和阅读 安装十分简单,ce ...
- Ansible批量自动化管理工具
一,工具与环境介绍 1.1 ansible简介 批量管理服务器的工具 无需部署agent,通过ssh进行管理 流行的自动化运维工具:https://github.com/ansible/ansible ...
- Ansible批量自动化管理工具(二)
Ansible批量自动化管理工具(二) 链接:https://pan.baidu.com/s/1A3Iq3gGkGS27L_Gt37_I0g 提取码:ncy2 复制这段内容后打开百度网盘手机App,操 ...
- Ansible批量自动化管理工具 roles标准化
批量管理服务器的工具,无需部署代理,通过ssh进行管理,是python写的 ansible 常用模块 : (1)shell命令模块执行命令 (2)copy模块批量下发文件或文件夹 (3)script模 ...
- Linux 运维工作中的经典应用ansible(批量管理)Docker容器技术(环境的快速搭建)
一 Ansible自动化运维工具 Python 在运维工作中的经典应用 ansible(批量管理操作) .安装ansible(需要bese epel 2种源) wget -O /etc/yum.rep ...
- Ansible的Inventory管理
Ansible将可管理的服务器集合成为Inventory,Inventory的管理便是服务器的管理. hosts文件的位置: /etc/ansible/hosts 在命令行通过-i参数指定 通过/et ...
- spring 学习(二):spring bean 管理--配置文件和注解混合使用
spring 学习(二)spring bean 管理--配置文件和注解混合使用 相似的,创建 maven 工程,配置pom.xml 文件,具体可以参考上一篇博文: sprint 学习(一) 然后我们在 ...
- 利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model
利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model 使用场景:网站配置项目,为了便于管理,网站有几个Model类来管理配置文件, 比如ConfigWebsiteMo ...
随机推荐
- AngularJS 1.x 国际化——Angular-translate例子
可运行代码如下: <!DOCTYPE html> <html ng-app="MyApp"> <head> <meta http-equi ...
- bzoj 1367 [ Baltic 2004 ] sequence —— 左偏树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1367 好题啊!论文上的题: 论文上只给出了不下降序列的求法: 先考虑特殊情况,如果原序列上升 ...
- C++11系列-什么是C++11
什么是C++0x? C++0x是C++最新标准标准化过程中的曾用名,在这一系列文章中我们将介绍最新标准添加的一系列新的语言特性.在2011年9月份,C++0x正式由官方发布并命名C++11,现在很多编 ...
- astgo-官方功能更新日志
2014年9月 2014-9-7:更新 1.安卓.苹果客户端添加字幕广告(点击字幕跳转打开网址) 2.安卓.苹果客户端添加公告推送功能 3.修正Astgo软交换管理平台修删除充值卡.用户账号,造成整个 ...
- IOException 简单解决方法
java.lang.IllegalStateException异常解决方法 这个异常大多数是由文件读取,下载时抛出,但是偶尔也会由类型转换时异常抛出此异常. 错误:Optional int param ...
- php的类型转换
转自:http://www.tianzhigang.com/article.asp?id=280 PHP的数据类型转换属于强制转换,允许转换的PHP数据类型有: (int).(integer):转换成 ...
- Akka源码分析-深入ActorRef&ActorPath
上一节我们深入讨论了ActorRef等相关的概念及其关系,但ActorRef和ActorPath的关系还需要再加以分析说明.其实还是官网说的比较清楚. “A path in an actor syst ...
- nginx + php-fpm 运行原理
一.关于nginx 1.1 简单认知 我们都知道nginx 是web服务器. 也知道 用户访问时通过ip和端口访问 nginx. 那么nginx 是如何 通过php 获取数据并返回数据的呢? 1.2 ...
- BZOJ 4481
思路: 等比数列求和 (无穷项) +线段树找逆序对 //By SiriusRen #include <bits/stdc++.h> ; ; ],ans; struct Node{int x ...
- JavaScript 封装插件学习笔记(一)
此篇只是笔记,在借鉴.参考.模仿的过程,可能不完整,请多指教! 定义插件名称要注意命名冲突,防止全局污染. 1.第一种Javascript对象命名:(Javascript语言是“先解析,后运行”,解析 ...