趁著最近在搞ansible,現在學習了一波template模組的用法:
1、使用template模組在jinja2中引用變數,先來目錄結構樹
[root@master ansible]# tree
.
├── ansible.cfg
├── hosts
├── roles
│ └── temp
│ ├── tasks
│ │ └── main.yaml
│ ├── templates
│ │ ├── test_if.j2
│ │ └── test.j2
│ └── vars
│ └── main.yaml
└── work_dir
├── copy_configfile.retry
└── copy_configfile.yaml
開啟定義好的變數:
[root@master ansible]# cat roles/temp/vars/main.yaml master_ip: 192.168.101.14 master_hostname: master node1_ip: 192.168.101.15 node1_hostname: node1
開啟hosts檔案檢視節點資訊:
[root@master ansible]# egrep -v "^#|^$" hosts [nodes] 192.168.101.14 192.168.101.15
現在通過定義好的變數在templates目錄下建立j2檔案:
[root@master ansible]# cat roles/temp/templates/test.j2 ExecStart=/usr/local/bin/etcd --name {{ master_hostname }} --initial-advertise-peer-urls http://{{ master_ip }}:2380
檢視tasks主任務定義:
[root@master ansible]# cat roles/temp/tasks/main.yaml - name: copy configfile to nodes template: src: test.j2 dest: /tmp/test.conf
檢視工作目錄下面的執行yaml:
[root@master ansible]# cat work_dir/copy_configfile.yaml - hosts: nodes remote_user: root roles: - temp
在tasks目錄下面的main.yaml定義使用了template模組,呼叫templates目錄下面的test.j2檔案
執行:
[root@master ansible]# ansible-playbook work_dir/copy_configfile.yaml
然後在兩個節點檢視:
[root@master ~]# cat /tmp/test.conf ExecStart=/usr/local/bin/etcd --name master --initial-advertise-peer-urls http://192.168.101.14:2380
[root@node1 ~]# cat /tmp/test.conf ExecStart=/usr/local/bin/etcd --name master --initial-advertise-peer-urls http://192.168.101.14:2380
可以看見在各個節點的tem目錄下面的檔案都用變數替換了
2、使用template模組呼叫的j2檔案使用{% if %} {% endif %}進行控制:
[root@master ansible]# cat roles/temp/templates/test_if.j2 {% if ansible_hostname == master_hostname %} ExecStart=/usr/local/bin/etcd --name {{ master_hostname }} --initial-advertise-peer-urls http://{{ master_ip }}:2380 {% elif ansible_hostname == node1_hostname %} ExecStart=/usr/local/bin/etcd --name {{ node1_hostname }} --initial-advertise-peer-urls http://{{ node1_ip }}:2380 {% endif %}
在上面中使用if進行了判斷,如果ansible_hostname變數與定義的master_hostname變數值相等,那麼將此檔案copy到節點上就使用條件1,而過不滿足條件1那麼執行條件2
ansible_hostname這個變數是setup模組中的值,是節點的固定值
[root@master ~]# ansible all -m setup -a "filter=ansible_hostname" 192.168.101.15 | SUCCESS => { "ansible_facts": { "ansible_hostname": "node1" }, "changed": false, "failed": false } 192.168.101.14 | SUCCESS => { "ansible_facts": { "ansible_hostname": "master" }, "changed": false, "failed": false }
現在檢視tasks下面的檔案:
[root@master ansible]# cat roles/temp/tasks/main.yaml - name: copy configfile to nodes template: src: test_if.j2 dest: /tmp/test.conf
將上面的test.j2改為了if條件的j2,然後執行:
[root@master ansible]# ansible-playbook work_dir/copy_configfile.yaml
檢視各節點生成的檔案內容:
[root@master ~]# cat /tmp/test.conf ExecStart=/usr/local/bin/etcd --name master --initial-advertise-peer-urls http://192.168.101.14:2380
[root@node1 ~]# cat /tmp/test.conf ExecStart=/usr/local/bin/etcd --name node1 --initial-advertise-peer-urls http://192.168.101.15:2380
可以看見生成的檔案內容不一樣,於是這樣就可以將節點的不同內容進行分離開了
當然還可以使用另外的方式隔離節點的不同:
ExecStart=/usr/local/bin/etcd --name {{ ansible_hostname }} --initial-advertise-peer-urls http://{{ ansible_ens33.ipv4.address }}:2380
因為各個節點的ansible_hostname和ip都是固定的所以也可以根據上面進行區分不同(不過這種方式限制了一定的範圍)
3、使用template模組呼叫j2檔案使用for迴圈:
建立jinja關於for的檔案:
[root@master ansible]# cat roles/temp/templates/test_for.j2 {% for i in range(1,10) %} test{{ i }} {% endfor %}
[root@master ansible]# cat roles/temp/tasks/main.yaml - name: copy configfile to nodes template: src: test_for.j2 dest: /tmp/test.conf
執行該角色:
[root@master ansible]# ansible-playbook work_dir/copy_configfile.yaml
驗證兩節點的檔案內容:
[root@master ~]# cat /tmp/test.conf test1 test2 test3 test4 test5 test6 test7 test8 test9
[root@node1 ~]# cat /tmp/test.conf test1 test2 test3 test4 test5 test6 test7 test8 test9
4、使用default()預設值
當我們定義了變數的值時,採用變數的值,當我們沒有定義變數的值時,那麼使用預設給定的值:
首先檢視定義的變數:
[root@master ansible]# cat roles/temp/vars/main.yaml master_ip: 192.168.101.14 master_hostname: master node1_ip: 192.168.101.15 node1_hostname: node1
然後檢視jinja2的檔案:
[root@master ansible]# cat roles/temp/templates/test_default.j2 Listen: {{ server_port|default(80) }}
可以看見並沒有定義server_port這個變數
檢視tasks檔案:
[root@master ansible]# cat roles/temp/tasks/main.yaml - name: copy configfile to nodes template: src: test_default.j2 dest: /tmp/test.conf
執行完成後,檢視檔案內容:
[root@master ~]# cat /tmp/test.conf Listen: 80
現在向vars/main.yaml中定義server_port變數,並給定值:
[root@master ansible]# cat roles/temp/vars/main.yaml master_ip: 192.168.101.14 master_hostname: master node1_ip: 192.168.101.15 node1_hostname: node1 server_port: 8080
再次執行,然後檢視檔案內容:
[root@master ~]# cat /tmp/test.conf Listen: 8080
可以看見使用了定義的值