> 文章列表 > [Ansible系列]ansible JinJia2过滤器

[Ansible系列]ansible JinJia2过滤器

[Ansible系列]ansible JinJia2过滤器

目录

一.  JinJia2简介

二.  JinJia2模板使用 

2.1  在play中使用jinjia2

2.2  template模块使用

2.3   jinjia2条件语句

2.4  jinjia2循环语句

2.5   jinjia2过滤器

2.5.1   default过滤器

2.5.2  字符串操作相关过滤器 

 2.5.3  数字操作相关过滤器

2.5.4  列表操作相关过滤器 

2.5.5   应用于文件的过滤器

2.5.6  应用于注册变量的过滤器 


一.  JinJia2简介

         Jinja2是基于python的模板引擎。那么什么是模板?

假设说现在我们需要一次性在10台主机上安装redis,这个通过playbook现在已经很容易实现。默认 情况下,所有的redis安装完成之后,我们可以统一为其分发配置文件。这个时候就面临一个问题,这 些redis需要监听的地址各不相同,我们也不可能为每一个redis单独写一个配置文件。因为这些配置 文件中,绝大部分的配置其实都是相同的。这个时候最好的方式其实就是用一个通用的配置文件来解 决所有的问题。将所有需要修改的地方使用变量替换。这个通用的配置文件就是模板。

二.  JinJia2模板使用 

2.1  在play中使用jinjia2

         以上面的redis为例,我们创建一个redis的模板,模板如下:

[root@clinet ~]# cat /etc/redis.conf |grep -v ^# |grep -v ^$
bind {{ ansible_eth0.ipv4.address }} 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes

现在我们有了一个模板文件,那么在playbook中如何来使用呢? playbook使用template模块来实现模板文件的分发,其用法与copy模块基本相同,唯一的区别是, copy模块会将原文件原封不动的复制到被控端,而template会将原文件复制到被控端,并且使用变 量的值将文件中的变量替换以生成完整的配置文件。

playbook示例:

[root@clinet yum_file]# cat jinjia2/install_redis.yml 
- hosts: testtasks:- name: configure redis max memoryset_fact:redis_mem: "{{ (ansible_memtotal_mb /2) | int }}M"- name: debug memeory debug:msg: - '{{ redis_mem }}'- name: install redis package:name: redisstate: present- name: configure redis.conftemplate:src: /root/ansible_test/ansible_2/template/redis.conf.j2dest: /etc/redis.confnotify:- restart redis- name: start redisservice:name: redisstate: startedenabled: yeshandlers:- name: restart redisservice:name: redisstate: restarted
[root@clinet yum_file]# 

2.2  template模块使用

         template模块会将原文件复制到被控端,并且使用变 量的值将文件中的变量替换以生成完整的配置文件。

关于template模块的更多参数说明:

·  backup:如果原目标文件存在,则先备份目标文件

·  dest:目标文件路径

·  force:是否强制覆盖,默认为yes

·  group:目标文件属组

·  mode:目标文件的权限

·  owner:目标文件属主

·  src:源模板文件路径

·  validate:在复制之前通过命令验证目标文件,如果验证通过则复制

2.3   jinjia2条件语句

         在上面的示例中,我们直接取了被控节点的ens33网卡的ip作为其监听地址。那么假如有些机器的网卡绑定的,那么网络连接时是bond0,这种做法就会报错。这个时候我们就需要在模板文件中定义条件语句如下:

{% if ansbile_bond is defined %}
bind {{ ansible_bond.ipv4.address }} 127.0.0.1
{% elif ansible_bond is defined % }
bind {{ ansible_ens33.ipv4.address }} 127.0.0.1
{% else %}
bind 0.0.0.0
{% endif %}maxmemory {{ redis_mem }}
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000

利用条件语句进一步配置redis主从模式:

{% if ansbile_bond is defined %}
bind {{ ansible_bond.ipv4.address }} 127.0.0.1
{% elif ansible_ens33 is defined %}
bind {{ ansible_ens33.ipv4.address }} 127.0.0.1
{% else %}
bind 0.0.0.0
{% endif %}{% if master_ip is defined %}
slaveof {{ master_ip }} {{ masterport | default(6379) }}
{% endif %}{% if masterpass is defined %}
masterauth {{ masterpass }}
{% endif %}{% if requirepass is defined %}
requirepass {{ requirepass }}
{% endif %}maxmemory {{ redis_mem }}
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes

注意:

1.  redis主从配置只需要在slave上配置slaveof  ip  port(master节点不需要任何配置)

2.  注意防火墙

2.4  jinjia2循环语句

         以nginx做负载均能,代理到后端httpd的基础实验为例,展示基础的for循环使用。

inventory配置如下:

[proxy]
192.168.194.132[webserver]
192.168.194.130
192.168.194.131
[root@clinet ansible_2]# 

 playbook如下:

- hosts: proxy:webservergather_facts: yespre_tasks:- name: fireword.serverservice:name: firewalldstate: stoppedenabled: nopost_tasks:- name: message infodebug:msg: 'this playbook finished'tasks:- name: install & configure ngxin blockblock:- name: install nginxpackage:name: nginxstate: present- name: configure nginx.conftemplate:src: /root/ansible_test/ansible_2/template/nginx.conf.j2dest: /etc/nginx/nginx.confbackup: yesnotify: restart nginx- name: start ngixnservice:name: nginxstate: startedenabled: yeswhen: ansible_ens33.ipv4.address in groups['proxy']- name: install & configure httpd blockblock:- name: install httpdpackage:name: httpdstate: present- name: confgure http.conftemplate:src: /root/ansible_test/ansible_2/template/index.html.j2dest: /var/www/html/index.htmlbackup: yesnotify: restart httpd- name: start httpdservice:name: httpdstate: startedenabled: yeswhen: ansible_ens33.ipv4.address in groups['webserver']handlers:- name: restart nginxservice:name: nginxstate: restarted- name: restart httpdservice:name: httpdstate: restarted

 总结一:
上述示例中回顾了以下知识点:

1.  pre_tasks 是在tasks之前执行;而 post_tasks 则在tasks和handlers之后执行;

2.  when关键字,playbook中的条件语句

3.  hosts:  proxy:webserver,ansible的主机匹配规则

4.  block和when的配合使用,对整块block语句做判断。等等

总结二:

jinjia2模板中的语法总结:

1.  变量的使用: {{ 变量名 }}  (不需要用引号包裹,与playbook中的变量使用的主要区别)

2.  条件语句:
     {% if %}  ...  {% elif %} ... {% else %} ... {% endif %}

3.  循环语句:
     {% for %}  ... {% endfor %}
(注意:{%%} 是jinjia2模板的语法格式)

2.5   jinjia2过滤器

2.5.1   default过滤器

         当指定的变量不存在时,用于设定默认值

 示例:

‐ hosts: testgather_facts: falsevars:‐ path: /tmp/testmode: 0400‐ path: /tmp/foo‐ path: /tmp/bartasks:‐ file:path: {{ item.path }}state: touchmode: {{ item.mode|default(omit)}}with_items: "{{ paths }}"

omit表示系统默认的,也可以default(777),当变量不存在的时候,使用777为值。

2.5.2  字符串操作相关过滤器 

·  upper:将所有字符串转换为大写

·  lower:将所有字符串转换为小写

·  capitalize:将字符串的首字母大写,其他字母小写

·  reverse:将字符串倒序排列

·  first:返回字符串的第一个字符

·  last:返回字符串的最后一个字符

·  trim:将字符串开头和结尾的空格去掉

·  center(30):将字符串放在中间,并且字符串两边用空格补齐30位

·  length:返回字符串的长度,与count等价

·  list:将字符串转换为列表

·  shuffle:list将字符串转换为列表,但是顺序排列,shuffle同样将字符串转换为列表,但是会随 机打乱字符串顺序

‐ hosts: testgather_facts: novars:teststr: "abc123ABC"teststr1: " abc "teststr2: "123456789"teststr3: "sfacb1335@#$%"tasks:‐ debug:msg: "{{ teststr | upper }}"‐ debug:msg: "{{ teststr | lower }}"‐ debug:msg: "{{ teststr | capitalize }}"‐ debug:msg: "{{ teststr | reverse }}"‐ debug:msg: "{{ teststr|first }}"‐ debug:msg: "{{ teststr|last }}"‐ debug:msg: "{{ teststr1 | trim }}"‐ debug:msg: "{{ teststr2 | center(30) }}"‐ debug:msg: "{{ teststr2 | length }}"‐ debug:msg: "{{ teststr3 | list }}"‐ debug:msg: "{{ teststr3 | shuffle }}"

 2.5.3  数字操作相关过滤器

·  int: 将对应的值转换为整数

·  float:将对应的值转换为浮点数

·  abs:获取绝对值

·  round:小数点四舍五入

·  random:从一个给定的范围中获取随机值

‐ hosts: testgather_facts: novars:testnum: ‐1tasks:‐ debug:msg: "{{ 8+('8'|int) }}"‐ debug:# 默认情况下,如果无法完成数字转换则返回0# 这里指定如果无法完成数字转换则返回6msg: "{{ 'a'|int(default=6) }}"‐ debug:msg: "{{ '8'|float }}"‐ debug:msg: "{{ 'a'|float(8.88)' }}"‐ debug:msg: "{{ testnum|abs }}"‐ debug:msg: "{{ 12.5|round }}"‐ debug:msg: "{{ 3.1415926 | round(5) }}"‐ debug:# 从0到100中随机返回一个数字msg: "{{ 100|random }}"‐ debug:# 从5到10中随机返回一个数字msg: "{{ 10|random(start=5) }}"‐ debug:# 从4到15中随机返回一个数字,步长为3# 返回的随机数只可能是:4,7,10,13中的一个msg: "{{ 15|random(start=4,step=3) }}"‐ debug:# 从0到15随机返回一个数字,步长为4msg: "{{ 15|random(step=4) }}"

2.5.4  列表操作相关过滤器 

·  length: 返回列表长度

·  first:返回列表的第一个值

·  last:返回列表的最后一个值

·  min:返回列表中最小的值

·  max:返回列表中最大的值

·  sort:重新排列列表,默认为升序排列,sort(reverse=true)为降序

·  sum:返回纯数字非嵌套列表中所有数字的和

·  flatten:如果列表中包含列表,则flatten可拉平嵌套的列表,levels参数可用于指定被拉平的层级

·  join:将列表中的元素合并为一个字符串

·  random:从列表中随机返回一个元素

·  shuffle

·  upper

·  lower

·  union:将两个列表合并,如果元素有重复,则只留下一个

·  intersect:获取两个列表的交集

·  difference:获取存在于第一个列表中,但不存在于第二个列表中的元素 ·  symmetric_difference:取出两个列表中各自独立的元素,如果重复则只留一个

2.5.5   应用于文件的过滤器

·  basename:返回文件路径中的文件名部分

·  dirname:返回文件路径中的目录部分

·  expanduser:将文件路径中的~替换为用户目录

·  realpath:处理符号链接后的文件实际路径

2.5.6  应用于注册变量的过滤器 

         正常情况下,当某个task执行失败的时候,ansible会中止运行。此时我们可以通过 ignore_errors 来 捕获异常以让task继续往下执行。然后调用debug模块打印出出错时的内容,拿来错误结果后,主动 失败。

‐ name: Run myprogcommand: /opt/myprogregister: resultignore_errors: True
‐ debug:var: result‐ debug:msg: "Stop running the playbook if myprog failed"failed_when: result|failed

任务返回值过滤器:

·  failed: 如果注册变量的值是任务failed则返回True

·  changed: 如果注册变量的值是任务changed则返回True

·  success:如果注册变量的值是任务succeeded则返回True

·  skipped:如果注册变量的值是任务skipped则返回True