目录

一.  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: test

tasks:

- name: configure redis max memory

set_fact:

redis_mem: "{{ (ansible_memtotal_mb /2) | int }}M"

- name: debug memeory

debug:

msg:

- '{{ redis_mem }}'

- name: install redis

package:

name: redis

state: present

- name: configure redis.conf

template:

src: /root/ansible_test/ansible_2/template/redis.conf.j2

dest: /etc/redis.conf

notify:

- restart redis

- name: start redis

service:

name: redis

state: started

enabled: yes

handlers:

- name: restart redis

service:

name: redis

state: 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:webserver

gather_facts: yes

pre_tasks:

- name: fireword.server

service:

name: firewalld

state: stopped

enabled: no

post_tasks:

- name: message info

debug:

msg: 'this playbook finished'

tasks:

- name: install & configure ngxin block

block:

- name: install nginx

package:

name: nginx

state: present

- name: configure nginx.conf

template:

src: /root/ansible_test/ansible_2/template/nginx.conf.j2

dest: /etc/nginx/nginx.conf

backup: yes

notify: restart nginx

- name: start ngixn

service:

name: nginx

state: started

enabled: yes

when: ansible_ens33.ipv4.address in groups['proxy']

- name: install & configure httpd block

block:

- name: install httpd

package:

name: httpd

state: present

- name: confgure http.conf

template:

src: /root/ansible_test/ansible_2/template/index.html.j2

dest: /var/www/html/index.html

backup: yes

notify: restart httpd

- name: start httpd

service:

name: httpd

state: started

enabled: yes

when: ansible_ens33.ipv4.address in groups['webserver']

handlers:

- name: restart nginx

service:

name: nginx

state: restarted

- name: restart httpd

service:

name: httpd

state: 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: test

gather_facts: false

vars:

‐ path: /tmp/test

mode: 0400

‐ path: /tmp/foo

‐ path: /tmp/bar

tasks:

‐ file:

path: {{ item.path }}

state: touch

mode: {{ 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: test

gather_facts: no

vars:

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: test

gather_facts: no

vars:

testnum: ‐1

tasks:

‐ debug:

msg: "{{ 8+('8'|int) }}"

‐ debug:

# 默认情况下,如果无法完成数字转换则返回0

# 这里指定如果无法完成数字转换则返回6

msg: "{{ '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随机返回一个数字,步长为4

msg: "{{ 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 myprog

command: /opt/myprog

register: result

ignore_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

 

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: