目錄
一.? JinJia2簡介
二.? JinJia2模板使用?
2.1? 在play中使用jinjia2
2.2??template模塊使用
2.3? ?jinjia2條件語句
2.4? jinjia2循環(huán)語句
2.5? ?jinjia2過濾器
2.5.1? ?default過濾器
2.5.2? 字符串操作相關(guān)過濾器?
?2.5.3? 數(shù)字操作相關(guān)過濾器
2.5.4? 列表操作相關(guān)過濾器?
2.5.5? ?應(yīng)用于文件的過濾器
2.5.6? 應(yīng)用于注冊變量的過濾器?
一.? JinJia2簡介
?????????Jinja2是基于python的模板引擎。那么什么是模板?
假設(shè)說現(xiàn)在我們需要一次性在10臺主機(jī)上安裝redis,這個(gè)通過playbook現(xiàn)在已經(jīng)很容易實(shí)現(xiàn)。默認(rèn) 情況下,所有的redis安裝完成之后,我們可以統(tǒng)一為其分發(fā)配置文件。這個(gè)時(shí)候就面臨一個(gè)問題,這 些redis需要監(jiān)聽的地址各不相同,我們也不可能為每一個(gè)redis單獨(dú)寫一個(gè)配置文件。因?yàn)檫@些配置 文件中,絕大部分的配置其實(shí)都是相同的。這個(gè)時(shí)候最好的方式其實(shí)就是用一個(gè)通用的配置文件來解 決所有的問題。將所有需要修改的地方使用變量替換。這個(gè)通用的配置文件就是模板。
二.? JinJia2模板使用?
2.1? 在play中使用jinjia2
? ? ? ? ?以上面的redis為例,我們創(chuàng)建一個(gè)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
現(xiàn)在我們有了一個(gè)模板文件,那么在playbook中如何來使用呢? playbook使用template模塊來實(shí)現(xiàn)模板文件的分發(fā),其用法與copy模塊基本相同,唯一的區(qū)別是, copy模塊會將原文件原封不動的復(fù)制到被控端,而template會將原文件復(fù)制到被控端,并且使用變 量的值將文件中的變量替換以生成完整的配置文件。
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模塊會將原文件復(fù)制到被控端,并且使用變 量的值將文件中的變量替換以生成完整的配置文件。
關(guān)于template模塊的更多參數(shù)說明:
·? backup:如果原目標(biāo)文件存在,則先備份目標(biāo)文件
·? dest:目標(biāo)文件路徑
·? force:是否強(qiáng)制覆蓋,默認(rèn)為yes
·? group:目標(biāo)文件屬組
·? mode:目標(biāo)文件的權(quán)限
·? owner:目標(biāo)文件屬主
·? src:源模板文件路徑
·? validate:在復(fù)制之前通過命令驗(yàn)證目標(biāo)文件,如果驗(yàn)證通過則復(fù)制
2.3? ?jinjia2條件語句
?????????在上面的示例中,我們直接取了被控節(jié)點(diǎn)的ens33網(wǎng)卡的ip作為其監(jiān)聽地址。那么假如有些機(jī)器的網(wǎng)卡綁定的,那么網(wǎng)絡(luò)連接時(shí)是bond0,這種做法就會報(bào)錯(cuò)。這個(gè)時(shí)候我們就需要在模板文件中定義條件語句如下:
{% 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
利用條件語句進(jìn)一步配置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節(jié)點(diǎn)不需要任何配置)
2.? 注意防火墻
2.4? jinjia2循環(huán)語句
? ? ? ? ?以nginx做負(fù)載均能,代理到后端httpd的基礎(chǔ)實(shí)驗(yàn)為例,展示基礎(chǔ)的for循環(huán)使用。
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
?總結(jié)一:
上述示例中回顧了以下知識點(diǎn):1.??pre_tasks 是在tasks之前執(zhí)行;而 post_tasks 則在tasks和handlers之后執(zhí)行;
2.? when關(guān)鍵字,playbook中的條件語句
3.? hosts:? proxy:webserver,ansible的主機(jī)匹配規(guī)則
4.? block和when的配合使用,對整塊block語句做判斷。等等
總結(jié)二:
jinjia2模板中的語法總結(jié):
1.? 變量的使用: {{ 變量名 }}? (不需要用引號包裹,與playbook中的變量使用的主要區(qū)別)
2.? 條件語句:
? ? ?{% if %}? ...? {% elif %} ... {% else %} ... {% endif %}
3.? 循環(huán)語句:
? ? ?{% for %}? ... {% endfor %}
(注意:{%%} 是jinjia2模板的語法格式)
2.5? ?jinjia2過濾器
2.5.1? ?default過濾器
?????????當(dāng)指定的變量不存在時(shí),用于設(shè)定默認(rèn)值
?示例:
‐ 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表示系統(tǒng)默認(rèn)的,也可以default(777),當(dāng)變量不存在的時(shí)候,使用777為值。
2.5.2? 字符串操作相關(guān)過濾器?
·? upper:將所有字符串轉(zhuǎn)換為大寫
·? lower:將所有字符串轉(zhuǎn)換為小寫
·? capitalize:將字符串的首字母大寫,其他字母小寫
·? reverse:將字符串倒序排列
·? first:返回字符串的第一個(gè)字符
·? last:返回字符串的最后一個(gè)字符
·? trim:將字符串開頭和結(jié)尾的空格去掉
·? center(30):將字符串放在中間,并且字符串兩邊用空格補(bǔ)齊30位
·? length:返回字符串的長度,與count等價(jià)
·? list:將字符串轉(zhuǎn)換為列表
·? shuffle:list將字符串轉(zhuǎn)換為列表,但是順序排列,shuffle同樣將字符串轉(zhuǎn)換為列表,但是會隨 機(jī)打亂字符串順序
‐ 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? 數(shù)字操作相關(guān)過濾器
·? int: 將對應(yīng)的值轉(zhuǎn)換為整數(shù)
·? float:將對應(yīng)的值轉(zhuǎn)換為浮點(diǎn)數(shù)
·? abs:獲取絕對值
·? round:小數(shù)點(diǎn)四舍五入
·? random:從一個(gè)給定的范圍中獲取隨機(jī)值
‐ hosts: test
gather_facts: no
vars:
testnum: ‐1
tasks:
‐ debug:
msg: "{{ 8+('8'|int) }}"
‐ debug:
# 默認(rèn)情況下,如果無法完成數(shù)字轉(zhuǎn)換則返回0
# 這里指定如果無法完成數(shù)字轉(zhuǎn)換則返回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中隨機(jī)返回一個(gè)數(shù)字
msg: "{{ 100|random }}"
‐ debug:
# 從5到10中隨機(jī)返回一個(gè)數(shù)字
msg: "{{ 10|random(start=5) }}"
‐ debug:
# 從4到15中隨機(jī)返回一個(gè)數(shù)字,步長為3
# 返回的隨機(jī)數(shù)只可能是:4,7,10,13中的一個(gè)
msg: "{{ 15|random(start=4,step=3) }}"
‐ debug:
# 從0到15隨機(jī)返回一個(gè)數(shù)字,步長為4
msg: "{{ 15|random(step=4) }}"
2.5.4? 列表操作相關(guān)過濾器?
·? length: 返回列表長度
·? first:返回列表的第一個(gè)值
·? last:返回列表的最后一個(gè)值
·? min:返回列表中最小的值
·? max:返回列表中最大的值
·? sort:重新排列列表,默認(rèn)為升序排列,sort(reverse=true)為降序
·? sum:返回純數(shù)字非嵌套列表中所有數(shù)字的和
·? flatten:如果列表中包含列表,則flatten可拉平嵌套的列表,levels參數(shù)可用于指定被拉平的層級
·? join:將列表中的元素合并為一個(gè)字符串
·? random:從列表中隨機(jī)返回一個(gè)元素
·? shuffle
·? upper
·? lower
·? union:將兩個(gè)列表合并,如果元素有重復(fù),則只留下一個(gè)
·? intersect:獲取兩個(gè)列表的交集
·? difference:獲取存在于第一個(gè)列表中,但不存在于第二個(gè)列表中的元素 ·? symmetric_difference:取出兩個(gè)列表中各自獨(dú)立的元素,如果重復(fù)則只留一個(gè)
2.5.5? ?應(yīng)用于文件的過濾器
·? basename:返回文件路徑中的文件名部分
·? dirname:返回文件路徑中的目錄部分
·? expanduser:將文件路徑中的~替換為用戶目錄
·? realpath:處理符號鏈接后的文件實(shí)際路徑
2.5.6? 應(yīng)用于注冊變量的過濾器?
?????????正常情況下,當(dāng)某個(gè)task執(zhí)行失敗的時(shí)候,ansible會中止運(yùn)行。此時(shí)我們可以通過 ignore_errors 來 捕獲異常以讓task繼續(xù)往下執(zhí)行。然后調(diào)用debug模塊打印出出錯(cuò)時(shí)的內(nèi)容,拿來錯(cuò)誤結(jié)果后,主動 失敗。
‐ 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
任務(wù)返回值過濾器:
·? failed: 如果注冊變量的值是任務(wù)failed則返回True
·? changed: 如果注冊變量的值是任務(wù)changed則返回True
·? success:如果注冊變量的值是任務(wù)succeeded則返回True
·? skipped:如果注冊變量的值是任務(wù)skipped則返回True文章來源:http://www.zghlxwxcb.cn/news/detail-785233.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-785233.html
到了這里,關(guān)于[Ansible系列]ansible JinJia2過濾器的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!