Jinjia2模板
前面說到playbook組成的時候,有介紹到template模塊,而template模塊對模板文件進行渲染時,使用的就是jinja2模板引擎,jinja2本身就是基于python的模板引擎,所以下面先來了解一下jinjia2模板的一些用法
基礎語法
{{?? }} 用來裝載表達式,比如變量、運算表達式、比較表達式等。(%?? %)用來裝載控制語句,比如 if 控制結構,for循環控制結構。(#??? #)用來裝載注釋,模板文件被渲染后,注釋不會包含在最終生成的文件中。
該模板支持的一些數據類型和表達式
字符串:使用單引號或雙引號;數字:整數,浮點數;列表:[list1, list2, ...]元組:(item1, item2, ...)字典:{key1:value1, key2:value2, ...}布爾型:true/false算術運算:+, -, *, /, //, %, **比較操作:==, !=, >, >=, <, <=邏輯運算:and, or, not
條件判斷
Jinjia2模板本身就是基于python的,所以它if語句也支持多條件判斷,嵌套等
與python一樣,具有if(如果),elif(在如果),else(否則),只不過結尾變成了endif表示條件的結束
常見的縮進方式為4格,也可以使用 2 個空格或制表符,但要保持一致。
單條件:{% if? 表達式 %}執行的內容{% endif %}
雙條件:{% if 表達式 %}執行內容{% else %}執行內容{% endif %}
多條件:{% if 表達式 %}執行內容{% elif 表達式 %}執行內容{% else %}
執行內容{% endif %}
嵌套:{% if??表達式 %}執行的內容{% if 表達式 %}執行內容{% else %}執行內容{% endif %}{% endif %}
循環
循環同樣也具有條件判斷的類似操作,這里就不過多舉例了。
可以使用{% for %}和{% endfor %}塊來實現一個基本的循環。
{% for i in 表達式 %}執行內容{% endfor %}
需要注意的是ansible默認不支持break(跳出循環)和continue(繼續)的。
其他控制結構
你會發現jinjia2模板沒有函數,但是,jinjia2模板有類似函數的用法,叫做宏,主要用于在模板渲染過程中生成動態的內容。一般有兩種用法定義{% macro %}和調用{% call %},jinjia2還支持其他的控制結構如{% include %}用于包含其他模板文件。
定義宏:{% macro one(text = '這是一段默認文本') %}{{ text }}{% endmacro %}
這里one是宏的名稱,text為參數,{{text}}則是宏輸出的內容
過濾器
Jinja2也支持過濾器,可以使用過濾器來對變量進行操作。
Lookup過濾器
在 Ansible 中,lookup過濾器是一種強大的工具,用于從外部數據源檢索數據。
語法格式:{{ lookup(‘插件名稱’, ‘插件參數’)}}
常用插件:
file: 用于讀取配置文件、腳本、密鑰文件等各種文件類型的內容。
env: 用于獲取環境變量的值
password: 用于從密碼存儲(如ansible-vault)中獲取密碼
#獲取/etc/testfile文件內容{{ lookup('file','/etc/testfile') }}#獲取PATH環境的變量值{{ lookup('env','PATH') }}
Default過濾器
default過濾器用于在變量未定義或者為假(例如空字符串、False、None、空列表等)的情況下提供一個默認值。
Set是用來設置變量的,想當于聲明一個變量
如果variable變量未定義,那么就會把”定義的變量”這個值賦予給它
set default_value=”定義的變量”database_host:{{ variable | default("default_value") }}
template模塊
?template模塊與copy模塊的用法十分類似,只是更多用于jinja2模板的渲染,也就是模板文件中可以引用變量,實現對不同主機有定制化的配置。
參數 | 解析 |
src | 指定本地jinja2模板文件的位置 |
dest | 指定目標遠程主機路徑 |
backup | 指定是否備份,默認值no |
mode | 設置權限 |
user | 設置用戶 |
group | 設置用戶組 |
Jinjia2模板示例
jinjia2模板好用的地方在于它支持多種文件可以是html,xml,conf等等,這就極大的方便用template模塊使用jinjia2模板對一些服務的配置文件進行修改
安裝redis服務:
把需要修改的配置信息寫入模板中[root@web01 ansible]# cat redis.conf.j2bind {{ ansible_host }} 127.0.0.1? #? 引用了facts組件內置變量port {{ redis_port }}????????? ?#這是play文件里定義的變量protected-mode notcp-backlog 511timeout 0tcp-keepalive 300daemonize yessupervised nopidfile /var/run/redis_6379.pidloglevel notice
編寫play文件
[root@web01 ansible]# cat redis.yml---- name: 部署redsi服務hosts: web01vars:redis_port: 6379 #指定redis的端口tasks:- name: install redisyum:name: redisstate: present- name: start redisservice:name: redisstate: startednotify: restart- name: upload redis.conftemplate:src: /etc/ansible/redis.conf.j2dest: /etc/redis.confhandlers:- name: restartservice:name: redisstate: restarted
執行命令
[root@web01 ansible]# ansible-playbook redis.yml
查詢配置文件是否修改
[root@web01 ansible]# grep [^a-Z$] /etc/redis.confbind 192.168.143.161 127.0.0.1port 6379protected-mode notcp-backlog 511timeout 0tcp-keepalive 300daemonize yessupervised nopidfile /var/run/redis_6379.pidloglevel notice
可以看到此時配置文件和我們模板中寫的配置文件內容一致