设为首页 收藏本站
查看: 798|回复: 0

[经验分享] Ansible使用jinja2管理配置文件以及jinja2语法简介

[复制链接]

尚未签到

发表于 2018-7-30 08:46:13 | 显示全部楼层 |阅读模式
  一、Jinja2介绍
  Jinja2是基于python的模板引擎,功能比较类似于PHP的smarty,J2ee的Freemarker和velocity。它能完全支持unicode,并具有集成的沙箱执行环境,应用广泛。jinja2使用BSD授权
  Jinja2的语法是由variables(变量)和statement(语句)组成,如下;
  1、variables:可以输出数据
  ` my_variables `
  {{ some_dudes_name | capitalize }}
  2、statements: 可以用来创建条件和循环等
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允许在模板中使用诸如绘制时间此类的一些额外的模板变量
  第一个例子:引用变量
#cd roles/template/  
.
  
├── meta
  
│   └── main.yml
  
├── tasks
  
│   ├── template.yml
  
│   └── main.yml
  
├── templates
  
│   ├── order.j2
  
└── vars
  
    └── main.yml
  总调度yml文件:
#cat templates.yml  
---
  
- hosts: 10.0.90.27
  
  user: root
  
  gather_facts: false
  
  roles:
  
   - role: template
  注意:这里 - role: template 和 - template 是一样的!
  其他yml文件,如下:
#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目录结构:
#cd /etc/ansible/roles/test_hosts  
.
  
├── meta
  
│   └── main.yml
  
├── tasks
  
│   ├── file1.yml
  
│   └── main.yml
  
├── templates
  
│   └── test1.j2
  
└── vars
  
    └── main.yml
  各个目录下yml文件内容:
# 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 函数做二次处理。
  执行结果:
#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语句
  说明:如果定义端口号,就绑定定义的端口号,如果不定义端口号,就绑定默认端口号
ansible目录结果  
#cd /etc/ansible/roles/mysql_cnf
  
#tree
  
.
  
├── meta
  
│   └── main.yml
  
├── tasks
  
│   └── main.yml
  
├── templates
  
│   └── test3.j2
  
└── vars
  主要的yml文件是templates目录下面的test3.j2
# cat templates/test3.j2  
{% if PORT %}
  
bind_address=10.0.90.27:{{ PORT }}
  
{% else %}
  
bind_address=10.0.90.27:3306
  
{% endif %}
  playbook主文件
# 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
  执行:
# 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
  查看
# cat my.cnf  
bind_address=10.0.90.27:3136
  如果将vars变量去掉,执行结果:
# 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
  查看:
# 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、创建目录,创建好之后如下:
#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调度文件,如下:
#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模板文件,如下:
#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、创建变量,如下:
#cat vars/main.yml  
apache_vhost:
  
- {servername: "apache.test1.com", documentroot: "/data/test1/"}
  
- {servername: "apache.test2.com", documentroot: "/data/test2/"}
  5、创建总调度yml文件,如下:
#cat /etc/ansible/apache_test.yml  
---
  
- hosts: 10.0.90.27
  
  user: root
  
  gather_facts: no
  
  roles:
  
   - { role: apache_conf }
  6、测试:
#ansible-playbook apache_test.yml --syntax-check  

  
playbook: apache_test.yml
  7、执行测试
#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、到客户端查看
#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目录结构:
# cd roles/nginx_conf/  
#tree
  
.
  
├── files
  
├── meta
  
│   └── main.yml
  
├── tasks
  
│   ├── file.yml
  
│   └── main.yml
  
├── templates
  
│   └── nginx.conf.j2
  
└── vars
  
    └── main.yml
  2、tasks目录下文件内容:
#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模板文件
#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变量文件
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文件
#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、测试并执行:
#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 服务器查看配置文件
#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 服务器上查看配置文件
#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强大的模板功能的同时,也需要看到模板质量的重要性。
  参考链接:http://mp.weixin.qq.com/s?__biz=MzIyMDA1MzgyNw==&mid=2651968051&idx=1&sn=922b6cc8c8e6ff6e1c4b822e78ea31c3&scene=0#wechat_redirect   一个很好地ansible微信公众号,欢迎关注共同学习。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-543332-1-1.html 上篇帖子: Ansible nginx管理配置文件 下篇帖子: ansible学习记录之ansible安装
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表