Ansible之templates模板
一、jinja2简介解
Jinja2是Python下一个被广泛应用的模版引擎,他的设计思想来源于Djanjo的模板引擎,并扩展了其语法和一系列强大的功能。ansible的模板配置文件就是用jinja2这种模板编程语言写的,其中jinja2使用字面量有如下形式
1)字符串:使用单引号或双引号引起来的部分
2)数字:支持整数,浮点数(小数)
3)列表:和python里的列表一样,用中括号括起来,每个元素之间用逗号隔开,如[item1,item2,....]
4)元组:和python里的元组一样,小括号括起来,每个元素之间用逗号隔开,如(item1,item2,....)
5)字典:同python里的字典一样,大括号括起来,每个k/v(键值对)用逗号隔开,键和值用":"冒号隔开,如{key1:value1,key2:value2,....}
6)布尔型:同其他语言布尔型一样,ture/false
7)支持算数运算:+,-,*,/,//(整除,地板除),%(取模,取余数),**(幂运算)
8)支持比较操作:==(比较两个值是否相等),!=(不等),>,>=(大于等于),<,<=(小于等于)
9)支持逻辑运算:and(与),or(或),not(非)
10)支持for(循环) ,if(判断),when(当某一条件满足才开始执行when所在的代码块,作用类似if)
除此以外,jinja2还支持“test”测试语句,比如我们要判断某个变量是否定义,可以使用defined来判断,如 vars is defined ,如果vars定义则表达式返回true,相反返回false。类似的还有undefined(与defined相反),equalto(与“==”作用等效),even(判断对象是否是偶数),iterable(判断对象是否可迭代)
二、jinja2语法
jinja2有如下语法:
1)控制结构,它和我们写别的语言的控制结构类似,唯一不同的是它的for循环要用”{%%}“给括起来,且必须写在两个百分号之间,后面结束有一个{%endfor$}来表示for循环的结束,同样if语句也是,必须写在"{%%}" 两个百分号之间,后面结束也有个{%endif%}来表示if语句的结束,当然if语句支持elif ,else 这个同python里的if用法一样。
2)变量引用,jinja2的变量引用同ansible的变量应用类似,都是用"{{}}" 双大括号来表示中间括起来的内容表示变量
3)注释用"{#"开始,中间部分表示注释,以"#}"结束表示注释结束,支持多行注释和当行注释
示例:
1)for循环使用
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
}
{% endfor %}
说明:以上模板表示,从nginx_vhosts列表里去循环,nginx_vhosts里有几个元素,它将循环几次,每次循环取的值用vhost变量代替,它的用法类型shell里的for循环和python里的for循环
2)if单分支选择使用
{% if vhost.server_name is defined %}
server_name {{ vhost.server_name }}
{% endif %}
3)if多分支选择使用
{%if vhost.port is undefined %}
http_port=80
{%elif vhost.port == 81%}
http_port=81
{%else%}
http_port = 83
{%endif%}
4)单行注释
{#% for i in list %#}
5)多行注释
{#
{% for i in list %}
i+=i
{% endfor %}
#}
三、playbook中使用模板
templates是ansible的一个模块,其功能是根据模板文件动态生成配置文件,templates文件必须存放于templates目录下,且命名为".j2"结尾,yaml/yml文件需要和templates目录平级,这样我们在yml文件中调用模板的时候,就不需要写模板文件的路径,否则需要描述模板文件的路径,因为template模块会自动去找templates目录下的模板文件。目录结构如下
.
├── temnginx.yml
└── templates
└── nginx.conf.j2
示例:playbook中template变量替换
利用tamplates同步nginx配置文件,其中修改nginx.conf.j2(worker_processes {{ ansible_processor_vcpus }};)指定其worker进程的个数由远程主机的cpu个数决定
[root@test ~]#ll
总用量 4
-rw-r--r-- 1 root root 212 11月 18 14:08 temnginx.yml
drwxr-xr-x 2 root root 27 11月 18 14:05 templates
[root@test ~]#tree
.
├── temnginx.yml
└── templates
└── nginx.conf.j2 1 directory, 2 files
[root@test ~]#head templates/nginx.conf.j2
# 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 {{ ansible_processor_vcpus }};
error_log /var/log/nginx/error.log;
pid /run/nginx.pid; # Load dynamic modules. See /usr/share/nginx/README.dynamic.
[root@test ~]#cat temnginx.yml
---
- hosts: websers
remote_user: root tasks:
- name: install nginx
yum: name=nginx
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf [root@test ~]#
说明:以上playbook里是使用template模板去动态生成的配置文件,不是拷贝,拷贝是将文件原封不动的拷贝过去,还需要注意的是template模块不能在ad-hoc命令行里使用,只能在playbook里使用,且模板文件必须是".j2"结尾的
示例:playbook中template算数运算
还是以上的示例,我们可以这样写
vim nginx.conf.j2
worker_processes {{ ansible_processor_vcpus**2 }};
说明:我们可以用ansible内置变量做算术运算后的值作为模板文件的值,在playbook中还是用template模块去调用就好了
示例:模板文件中 for循环的用法
[root@test ~]#tree
.
├── temnginx.yml
└── templates
└── nginx.conf.j2 1 directory, 2 files
[root@test ~]#cat templates/nginx.conf.j2
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
}
{% endfor %}
[root@test ~]#cat temnginx.yml
---
- hosts: websers
remote_user: root
vars:
nginx_vhosts:
- listen: 8080
tasks:
- name: install nginx
yum: name=nginx
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf [root@test ~]#
生成结果:
[root@test ~]#ansible-playbook temnginx.yml PLAY [websers] ****************************************************************************************************** TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.128]
ok: [192.168.0.218] TASK [install nginx] ************************************************************************************************
changed: [192.168.0.128]
changed: [192.168.0.218] TASK [template config to remote hosts] ******************************************************************************
changed: [192.168.0.128]
changed: [192.168.0.218] PLAY RECAP **********************************************************************************************************
192.168.0.128 : ok=3 changed=2 unreachable=0 failed=0
192.168.0.218 : ok=3 changed=2 unreachable=0 failed=0 [root@test ~]#ansible websers -m shell -a 'cat /etc/nginx/nginx.conf'
192.168.0.128 | SUCCESS | rc=0 >>
server {
listen 8080
} 192.168.0.218 | SUCCESS | rc=0 >>
server {
listen 8080
} [root@test ~]#
示例:模板文件中if的用法
[root@test ~]#tree
.
├── temnginx.yml
└── templates
└── nginx.conf.j2 1 directory, 2 files
[root@test ~]#cat temnginx.yml
---
- hosts: websers
remote_user: root
vars:
nginx_vhosts:
- web1:
listen: 8080
server_name: "web1.test.com"
root: "/var/www/nginx/web1/"
- web2:
listen: 8080
root: "/var/www/nginx/web2/"
- web3:
listen: 8080
server_name: "web2.test.com"
root: "var/www/nginx/web3/"
tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf [root@test ~]#cat templates/nginx.conf.j2
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
{% if vhost.server_name is defined %}
server_name {{ vhost.server_name }}
{% endif %}
root {{ vhost.root }}
}
{% endfor %}
[root@test ~]#
生成结果:
[root@test ~]#ansible-playbook temnginx.yml PLAY [websers] ****************************************************************************************************** TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.128]
ok: [192.168.0.218] TASK [template config to remote hosts] ******************************************************************************
changed: [192.168.0.128]
changed: [192.168.0.218] PLAY RECAP **********************************************************************************************************
192.168.0.128 : ok=2 changed=1 unreachable=0 failed=0
192.168.0.218 : ok=2 changed=1 unreachable=0 failed=0 [root@test ~]#ansible websers -m shell -a 'cat /etc/nginx/nginx.conf'
192.168.0.128 | SUCCESS | rc=0 >>
server {
listen 8080
server_name web1.test.com
root /var/www/nginx/web1/
}
server {
listen 8080
root /var/www/nginx/web2/
}
server {
listen 8080
server_name web2.test.com
root var/www/nginx/web3/
} 192.168.0.218 | SUCCESS | rc=0 >>
server {
listen 8080
server_name web1.test.com
root /var/www/nginx/web1/
}
server {
listen 8080
root /var/www/nginx/web2/
}
server {
listen 8080
server_name web2.test.com
root var/www/nginx/web3/
} [root@test ~]#
说明:可以看到第二个server里是没有server_name,因为定义的变量列表里web2没有定义server_name
四、playbook中使用when条件测试
条件测试:如果需要根据变量、facts或此前任务的执行结果来作为某task执行与否的前提时需要用到条件测试,通过when语句实现,在task中使用jinja2的语法格式,when语句支持jinja2表达式语法;
示例:
[root@test ~]#cat test.yml
---
- hosts: all
remote_user: root tasks:
- name: set hostname centos6
hostname: name=ansible_centos6
when: ansible_distribution_major_version == "6"
- name: set hostname centos7
hostname: name=ansible_centos7
when: ansible_distribution_major_version == "7"
[root@test ~]#ansible all -m shell -a 'hostname'
192.168.0.128 | SUCCESS | rc=0 >>
localhost 192.168.0.218 | SUCCESS | rc=0 >>
localhost.localdomain 192.168.0.217 | SUCCESS | rc=0 >>
centos7 [root@test ~]#ansible-playbook test.yml PLAY [all] ********************************************************************************************************** TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.128]
ok: [192.168.0.218]
ok: [192.168.0.217] TASK [set hostname centos6] *****************************************************************************************
skipping: [192.168.0.217]
changed: [192.168.0.218]
changed: [192.168.0.128] TASK [set hostname centos7] *****************************************************************************************
skipping: [192.168.0.128]
skipping: [192.168.0.218]
changed: [192.168.0.217] PLAY RECAP **********************************************************************************************************
192.168.0.128 : ok=2 changed=1 unreachable=0 failed=0
192.168.0.217 : ok=2 changed=1 unreachable=0 failed=0
192.168.0.218 : ok=2 changed=1 unreachable=0 failed=0 [root@test ~]#ansible all -m shell -a 'hostname'
192.168.0.128 | SUCCESS | rc=0 >>
ansible_centos6 192.168.0.218 | SUCCESS | rc=0 >>
ansible_centos6 192.168.0.217 | SUCCESS | rc=0 >>
ansible_centos7 [root@test ~]#
说明:以上playbook利用when语句判断系统版本号,实现了通过不同的系统版本号,设置不同的主机名。
五、playbook迭代with_items
迭代:当有需要重复性执行的任务时,可使用迭代机制;对迭代项的引用,ansible有固定不变的变量,名为“item”;要在task中使用with_items给定要迭代的元素列表,列表格式可以为字符串、字典。
示例:批量创建用户
[root@test ~]#cat adduser.yml
---
- hosts: websers
remote_user: root tasks:
- name: add users
user: name={{ item }} state=present home=/home/{{ item }} groups=root,bin,wheel
with_items:
- user1
- user2
- user3
[root@test ~]#ansible-playbook adduser.yml PLAY [websers] ****************************************************************************************************** TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.128]
ok: [192.168.0.218] TASK [add users] ****************************************************************************************************
changed: [192.168.0.128] => (item=user1)
changed: [192.168.0.218] => (item=user1)
changed: [192.168.0.128] => (item=user2)
changed: [192.168.0.218] => (item=user2)
changed: [192.168.0.128] => (item=user3)
changed: [192.168.0.218] => (item=user3) PLAY RECAP **********************************************************************************************************
192.168.0.128 : ok=2 changed=1 unreachable=0 failed=0
192.168.0.218 : ok=2 changed=1 unreachable=0 failed=0 [root@test ~]#ansible websers -m shell -a 'tail -3 /etc/passwd'
192.168.0.128 | SUCCESS | rc=0 >>
user1:x:503:503::/home/user1:/bin/bash
user2:x:504:504::/home/user2:/bin/bash
user3:x:505:505::/home/user3:/bin/bash 192.168.0.218 | SUCCESS | rc=0 >>
user1:x:1213:1213::/home/user1:/bin/bash
user2:x:1214:1214::/home/user2:/bin/bash
user3:x:1215:1215::/home/user3:/bin/bash [root@test ~]#ansible websers -m shell -a 'id user1'
192.168.0.218 | SUCCESS | rc=0 >>
uid=1213(user1) gid=1213(user1) 组=1213(user1),0(root),1(bin),10(wheel) 192.168.0.128 | SUCCESS | rc=0 >>
uid=503(user1) gid=503(user1) 组=503(user1),0(root),1(bin),10(wheel) [root@test ~]#
示例:迭代嵌套子变量
[root@test ~]#cat adduser2.yml
---
- hosts: websers
remote_user: root tasks:
- name: create groups
group: name={{ item }}
with_items:
- group1
- group2
- group3
- name: create users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- {name: 'test1',group: 'group1'}
- {name: 'test2',group: 'group2'}
- {name: 'test3',group: 'group3'}
[root@test ~]#ansible-playbook adduser2.yml PLAY [websers] ****************************************************************************************************** TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.128]
ok: [192.168.0.218] TASK [create groups] ************************************************************************************************
changed: [192.168.0.128] => (item=group1)
changed: [192.168.0.218] => (item=group1)
changed: [192.168.0.128] => (item=group2)
changed: [192.168.0.218] => (item=group2)
changed: [192.168.0.128] => (item=group3)
changed: [192.168.0.218] => (item=group3) TASK [create users] *************************************************************************************************
changed: [192.168.0.128] => (item={u'group': u'group1', u'name': u'test1'})
changed: [192.168.0.218] => (item={u'group': u'group1', u'name': u'test1'})
changed: [192.168.0.128] => (item={u'group': u'group2', u'name': u'test2'})
changed: [192.168.0.218] => (item={u'group': u'group2', u'name': u'test2'})
changed: [192.168.0.128] => (item={u'group': u'group3', u'name': u'test3'})
changed: [192.168.0.218] => (item={u'group': u'group3', u'name': u'test3'}) PLAY RECAP **********************************************************************************************************
192.168.0.128 : ok=3 changed=2 unreachable=0 failed=0
192.168.0.218 : ok=3 changed=2 unreachable=0 failed=0 [root@test ~]#ansible websers -m shell -a 'tail -3 /etc/passwd'
192.168.0.128 | SUCCESS | rc=0 >>
test1:x:506:506::/home/test1:/bin/bash
test2:x:507:507::/home/test2:/bin/bash
test3:x:508:508::/home/test3:/bin/bash 192.168.0.218 | SUCCESS | rc=0 >>
test1:x:1216:1216::/home/test1:/bin/bash
test2:x:1217:1217::/home/test2:/bin/bash
test3:x:1218:1218::/home/test3:/bin/bash [root@test ~]#ansible websers -m shell -a 'id test1'
192.168.0.218 | SUCCESS | rc=0 >>
uid=1216(test1) gid=1216(group1) 组=1216(group1) 192.168.0.128 | SUCCESS | rc=0 >>
uid=506(test1) gid=506(group1) 组=506(group1) [root@test ~]#ansible websers -m shell -a 'id test2'
192.168.0.128 | SUCCESS | rc=0 >>
uid=507(test2) gid=507(group2) 组=507(group2) 192.168.0.218 | SUCCESS | rc=0 >>
uid=1217(test2) gid=1217(group2) 组=1217(group2) [root@test ~]#ansible websers -m shell -a 'id test3'
192.168.0.128 | SUCCESS | rc=0 >>
uid=508(test3) gid=508(group3) 组=508(group3) 192.168.0.218 | SUCCESS | rc=0 >>
uid=1218(test3) gid=1218(group3) 组=1218(group3) [root@test ~]#
说明:以上playbook实现了对应用户创建时加入对应的组里
Ansible之templates模板的更多相关文章
- Templates 模板:
Templates 模板: ########################温金 $template wj-flow01,"/data01/applog_backup/winfae_log/ ...
- python测试开发django-2.templates模板与html页
前言 Django 中的视图的概念是一类具有相同功能和模板的网页的集合.通俗一点来说,就是你平常打开浏览器,看到浏览器窗口展示出来的页面内容,那就是视图.前面一章通过浏览器访问http://127.0 ...
- django templates模板
Django templates模板 HTML代码可以被直接硬编码在views视图代码中,虽然这样很容易看出视图是怎么工作的,但直接将HTML硬编码到视图里却并不是一个好主意. 让我们来看一下为什么: ...
- python测试开发django-69.templates模板过滤器filter
前言 templates 模板里面过滤器 filter 的作用是对变量的出来,比如小写转大写,替换一些特殊字符,对列表取值,排序等操作. 内置的过滤器有很多,本篇拿几个常用的过滤器做案例讲解下相关的功 ...
- python测试开发django-67.templates模板变量取值
前言 django 的模板里面变量取值是通过句点语法来取值,就是一个点(.)符号.取值的对象也可以是字符串,int类型,list列表,字典键值对,也可以是一个类的实例对象. views视图 比如我在 ...
- 自动化运维工具-Ansible之6-Jinja2模板
自动化运维工具-Ansible之6-Jinja2模板 目录 自动化运维工具-Ansible之6-Jinja2模板 Ansible Jinja2模板概述 Ansible Jinja2模板使用 Ansib ...
- Django web框架-----Django templates模板
说明:mytestsite是django框架下的项目,quicktool是mytestsite项目中的应用 一般的变量之类的用 {{ }}(变量),功能类的比如循环.条件判断是用 {% %}(标签) ...
- 11、Django实战第11天:templates模板继承
Django模板的继承,它首先定义一个整体的框架(父类),然后动态的部分(子类)只需要重写自己本身的代码就可以了. 1.在templates目录下创建base.html 2.把org-list.htm ...
- Django之templates模板
模板渲染: 官方文档:https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#std:templatetag-for 模板渲染两种 ...
随机推荐
- 就个人银行账户管理程序谈谈C++和Java的异同
4_9 同: Java和C++都是面向对象的语言.都有数据成员,方法,访问权限的概念. 异: 访问权限上,非private时Java的默认访问权限是包.而C++的默认访问权限是private.Java ...
- spring源码系列8:AOP源码解析之代理的创建
回顾 首先回顾: JDK动态代理与CGLIB动态代理 Spring中的InstantiationAwareBeanPostProcessor和BeanPostProcessor的区别 我们得知 JDK ...
- 用JavaScript制作banner轮播图
JavaScript_banner轮播图 让我们一起来学习一下用js怎么实现banner轮播图呢? 直接看代码: <!DOCTYPE html> <html> <head ...
- [JZOJ5773]【NOIP2008模拟】简单数学题
Description 话说, 小X是个数学大佬,他喜欢做数学题.有一天,小X想考一考小Y.他问了小Y一道数学题.题目如下: 对于一个正整数N,存在一个正整数T(0<T&l ...
- Spring容器启动源码解析
1. 前言 最近搭建的工程都是基于SpringBoot,简化配置的感觉真爽.但有个以前的项目还是用SpringMvc写的,看到满满的配置xml文件,却有一种想去深入了解的冲动.折腾了好几天,决心去写这 ...
- CSP考场Emacs使用指南[原创]
前言: 据说,CSP考试,之后不再支持windows了呢. windows用户真得劲! 那用什么系统? Ubuntu上场了 Ubuntu编译指南 进入Ubuntu系统,在你想存的文件夹中新建一个空白文 ...
- Nginx初学(一)安装与运行
1.下载nginx安装包 nginx-1.6.3.tar.gz并复制安装包到 /usr/local/software中 2.安装依赖包,命令如下: yum -y install gcc-c++(需要等 ...
- 简单多层神经网络实现异或XOR
最近在看<Neural Network Design_Hagan> 然后想自己实现一个XOR 的网络. 由于单层神经网络不能将异或的判定分为两类. 根据 a^b=(a&~b)|(~ ...
- 第二篇:版本控制git之分支
有人把 Git 的分支模型称为它的`‘必杀技特性’',也正因为这一特性,使得 Git 从众多版本控制系统中脱颖而出. 为何 Git 的分支模型如此出众呢? Git 处理分支的方式可谓是难以置信的轻量, ...
- 给自己网站配置 https,http2 ,gzip压缩
https 需要购买域名ssl证书 注意事项: 1.要开启HTTP/2协议支持,需要在nginx 1.10以上版本并且需要openssl库的版本在1.0.2及以上编译. 2.http2.0只支持开启了 ...