ansible之template模組

wadeson發表於2017-11-25

趁著最近在搞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

可以看見使用了定義的值

相關文章