Ansible之templates模板

  1、jinja2簡介解python

  Jinja2是Python下一個被普遍應用的模版引擎,他的設計思想來源於Djanjo的模板引擎,並擴展了其語法和一系列強大的功能。ansible的模板配置文件就是用jinja2這種模板編程語言寫的,其中jinja2使用字面量有以下形式nginx

  1)字符串:使用單引號或雙引號引發來的部分web

  2)數字:支持整數,浮點數(小數)shell

  3)列表:和python裏的列表同樣,用中括號括起來,每一個元素之間用逗號隔開,如[item1,item2,....]編程

  4)元組:和python裏的元組同樣,小括號括起來,每一個元素之間用逗號隔開,如(item1,item2,....)vim

  5)字典:同python裏的字典同樣,大括號括起來,每一個k/v(鍵值對)用逗號隔開,鍵和值用":"冒號隔開,如{key1:value1,key2:value2,....}centos

  6)布爾型:同其餘語言布爾型同樣,ture/falsebash

  7)支持算數運算:+,-,*,/,//(整除,地板除),%(取模,取餘數),**(冪運算)dom

  8)支持比較操做:==(比較兩個值是否相等),!=(不等),>,>=(大於等於),<,<=(小於等於)編程語言

  9)支持邏輯運算:and(與),or(或),not(非)

  10)支持for(循環) ,if(判斷),when(當某一條件知足纔開始執行when所在的代碼塊,做用相似if)

  除此之外,jinja2還支持「test」測試語句,好比咱們要判斷某個變量是否認義,可使用defined來判斷,如 vars is defined ,若是vars定義則表達式返回true,相反返回false。相似的還有undefined(與defined相反),equalto(與「==」做用等效),even(判斷對象是不是偶數),iterable(判斷對象是否可迭代)

  2、jinja2語法

jinja2有以下語法:

  1)控制結構,它和咱們寫別的語言的控制結構相似,惟一不一樣的是它的for循環要用」{%%}「給括起來,且必須寫在兩個百分號之間,後面結束有一個{%endfor$}來表示for循環的結束,一樣if語句也是,必須寫在"{%%}" 兩個百分號之間,後面結束也有個{%endif%}來表示if語句的結束,固然if語句支持elif ,else  這個同python裏的if用法同樣。

  2)變量引用,jinja2的變量引用同ansible的變量應用相似,都是用"{{}}" 雙大括號來表示中間括起來的內容表示變量

  3)註釋用"{#"開始,中間部分表示註釋,以"#}"結束表示註釋結束,支持多行註釋和當行註釋

示例:

  1)for循環使用

{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
}
{% endfor %}

  說明:以上模板表示,從nginx_vhosts列表裏去循環,nginx_vhosts裏有幾個元素,它將循環幾回,每次循環取的值用vhost變量代替,它的用法類型shell裏的for循環和python裏的for循環

  2)if單分支選擇使用

{% if vhost.server_name is defined %}
    server_name {{ vhost.server_name }}
{% endif %}

  3)if多分支選擇使用

{%if vhost.port is undefined %}
    http_port=80
{%elif vhost.port == 81%}
    http_port=81
{%else%}
    http_port = 83
{%endif%}

  4)單行註釋

{#% for i in list %#}

  5)多行註釋

{#
    {% for i in list %}
         i+=i
      {% endfor %}
#}

  3、playbook中使用模板

templates是ansible的一個模塊,其功能是根據模板文件動態生成配置文件,templates文件必須存放於templates目錄下,且命名爲".j2"結尾,yaml/yml文件須要和templates目錄平級,這樣咱們在yml文件中調用模板的時候,就不須要寫模板文件的路徑,不然須要描述模板文件的路徑,由於template模塊會自動去找templates目錄下的模板文件。目錄結構以下

.
├── temnginx.yml
└── templates
   └── nginx.conf.j2

示例:playbook中template變量替換

  利用tamplates同步nginx配置文件,其中修改nginx.conf.j2(worker_processes {{ ansible_processor_vcpus }};)指定其worker進程的個數由遠程主機的cpu個數決定

[root@test ~]#ll
總用量 4
-rw-r--r-- 1 root root 212 11月 18 14:08 temnginx.yml
drwxr-xr-x 2 root root  27 11月 18 14:05 templates
[root@test ~]#tree
.
├── temnginx.yml
└── templates
    └── nginx.conf.j2

1 directory, 2 files
[root@test ~]#head templates/nginx.conf.j2 
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes {{ ansible_processor_vcpus }};
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
[root@test ~]#cat temnginx.yml 
---
- hosts: websers
  remote_user: root

  tasks:
    - name: install nginx
      yum: name=nginx 
    - name: template config to remote hosts
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
 
[root@test ~]#

  說明:以上playbook裏是使用template模板去動態生成的配置文件,不是拷貝,拷貝是將文件原封不動的拷貝過去,還須要注意的是template模塊不能在ad-hoc命令行裏使用,只能在playbook裏使用,且模板文件必須是".j2"結尾的

示例:playbook中template算數運算

仍是以上的示例,咱們能夠這樣寫

vim nginx.conf.j2
worker_processes {{ ansible_processor_vcpus**2 }};

  說明:咱們能夠用ansible內置變量作算術運算後的值做爲模板文件的值,在playbook中仍是用template模塊去調用就行了

示例:模板文件中 for循環的用法

[root@test ~]#tree
.
├── temnginx.yml
└── templates
    └── nginx.conf.j2

1 directory, 2 files
[root@test ~]#cat templates/nginx.conf.j2 
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
}
{% endfor %}
[root@test ~]#cat temnginx.yml 
---
- hosts: websers
  remote_user: root
  vars:
    nginx_vhosts:
      - listen: 8080
  tasks:
    - name: install nginx
      yum: name=nginx 
    - name: template config to remote hosts
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
 
[root@test ~]#  

生成結果:

[root@test ~]#ansible-playbook  temnginx.yml   

PLAY [websers] ******************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.128]
ok: [192.168.0.218]

TASK [install nginx] ************************************************************************************************
changed: [192.168.0.128]
changed: [192.168.0.218]

TASK [template config to remote hosts] ******************************************************************************
changed: [192.168.0.128]
changed: [192.168.0.218]

PLAY RECAP **********************************************************************************************************
192.168.0.128              : ok=3    changed=2    unreachable=0    failed=0   
192.168.0.218              : ok=3    changed=2    unreachable=0    failed=0   

[root@test ~]#ansible websers -m shell -a 'cat /etc/nginx/nginx.conf'
192.168.0.128 | SUCCESS | rc=0 >>
server {
listen 8080
}

192.168.0.218 | SUCCESS | rc=0 >>
server {
listen 8080
}

[root@test ~]#

  示例:模板文件中if的用法

[root@test ~]#tree
.
├── temnginx.yml
└── templates
    └── nginx.conf.j2

1 directory, 2 files
[root@test ~]#cat temnginx.yml 
---
- hosts: websers
  remote_user: root
  vars:
    nginx_vhosts:
      - web1:
        listen: 8080
        server_name: "web1.test.com"
        root: "/var/www/nginx/web1/"
      - web2:
        listen: 8080
        root: "/var/www/nginx/web2/"
      - web3:
        listen: 8080
        server_name: "web2.test.com"
        root: "var/www/nginx/web3/" 
  tasks:
    - name: template config to remote hosts
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
 
[root@test ~]#cat templates/nginx.conf.j2 
{% for vhost in nginx_vhosts %}
        server {
                listen {{ vhost.listen }}
                {% if vhost.server_name is defined %}
                server_name {{ vhost.server_name }}
                {% endif %}
                root {{ vhost.root }}
        }
{% endfor %}
[root@test ~]#

生成結果:

[root@test ~]#ansible-playbook temnginx.yml 

PLAY [websers] ******************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.128]
ok: [192.168.0.218]

TASK [template config to remote hosts] ******************************************************************************
changed: [192.168.0.128]
changed: [192.168.0.218]

PLAY RECAP **********************************************************************************************************
192.168.0.128              : ok=2    changed=1    unreachable=0    failed=0   
192.168.0.218              : ok=2    changed=1    unreachable=0    failed=0   

[root@test ~]#ansible websers -m shell -a 'cat /etc/nginx/nginx.conf'
192.168.0.128 | SUCCESS | rc=0 >>
server {
        listen 8080
                server_name web1.test.com
                root /var/www/nginx/web1/
}
server {
        listen 8080
                root /var/www/nginx/web2/
}
server {
        listen 8080
                server_name web2.test.com
                root var/www/nginx/web3/
}

192.168.0.218 | SUCCESS | rc=0 >>
server {
        listen 8080
                server_name web1.test.com
                root /var/www/nginx/web1/
}
server {
        listen 8080
                root /var/www/nginx/web2/
}
server {
        listen 8080
                server_name web2.test.com
                root var/www/nginx/web3/
}

[root@test ~]#

  說明:能夠看到第二個server裏是沒有server_name,由於定義的變量列表裏web2沒有定義server_name

  4、playbook中使用when條件測試

  條件測試:若是須要根據變量、facts或此前任務的執行結果來做爲某task執行與否的前提時須要用到條件測試,經過when語句實現,在task中使用jinja2的語法格式,when語句支持jinja2表達式語法;

示例:

[root@test ~]#cat test.yml 
---
- hosts: all 
  remote_user: root

  tasks:
    - name: set hostname centos6
      hostname: name=ansible_centos6
      when: ansible_distribution_major_version == "6"
    - name: set hostname centos7
      hostname: name=ansible_centos7
      when: ansible_distribution_major_version == "7" 
[root@test ~]#ansible all -m shell -a 'hostname'
192.168.0.128 | SUCCESS | rc=0 >>
localhost

192.168.0.218 | SUCCESS | rc=0 >>
localhost.localdomain

192.168.0.217 | SUCCESS | rc=0 >>
centos7

[root@test ~]#ansible-playbook test.yml 

PLAY [all] **********************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.128]
ok: [192.168.0.218]
ok: [192.168.0.217]

TASK [set hostname centos6] *****************************************************************************************
skipping: [192.168.0.217]
changed: [192.168.0.218]
changed: [192.168.0.128]

TASK [set hostname centos7] *****************************************************************************************
skipping: [192.168.0.128]
skipping: [192.168.0.218]
changed: [192.168.0.217]

PLAY RECAP **********************************************************************************************************
192.168.0.128              : ok=2    changed=1    unreachable=0    failed=0   
192.168.0.217              : ok=2    changed=1    unreachable=0    failed=0   
192.168.0.218              : ok=2    changed=1    unreachable=0    failed=0   

[root@test ~]#ansible all -m shell -a 'hostname'
192.168.0.128 | SUCCESS | rc=0 >>
ansible_centos6

192.168.0.218 | SUCCESS | rc=0 >>
ansible_centos6

192.168.0.217 | SUCCESS | rc=0 >>
ansible_centos7

[root@test ~]#

  說明:以上playbook利用when語句判斷系統版本號,實現了經過不一樣的系統版本號,設置不一樣的主機名。

  5、playbook迭代with_items

  迭代:當有須要重複性執行的任務時,可以使用迭代機制;對迭代項的引用,ansible有固定不變的變量,名爲「item」;要在task中使用with_items給定要迭代的元素列表,列表格式能夠爲字符串、字典。

示例:批量建立用戶

[root@test ~]#cat adduser.yml 
---
- hosts: websers
  remote_user: root
  
  tasks:
    - name: add users
      user: name={{ item }} state=present home=/home/{{ item }} groups=root,bin,wheel
      with_items:
        - user1
        - user2
        - user3
[root@test ~]#ansible-playbook adduser.yml

PLAY [websers] ******************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.128]
ok: [192.168.0.218]

TASK [add users] ****************************************************************************************************
changed: [192.168.0.128] => (item=user1)
changed: [192.168.0.218] => (item=user1)
changed: [192.168.0.128] => (item=user2)
changed: [192.168.0.218] => (item=user2)
changed: [192.168.0.128] => (item=user3)
changed: [192.168.0.218] => (item=user3)

PLAY RECAP **********************************************************************************************************
192.168.0.128              : ok=2    changed=1    unreachable=0    failed=0   
192.168.0.218              : ok=2    changed=1    unreachable=0    failed=0   

[root@test ~]#ansible websers -m shell -a 'tail -3 /etc/passwd'
192.168.0.128 | SUCCESS | rc=0 >>
user1:x:503:503::/home/user1:/bin/bash
user2:x:504:504::/home/user2:/bin/bash
user3:x:505:505::/home/user3:/bin/bash

192.168.0.218 | SUCCESS | rc=0 >>
user1:x:1213:1213::/home/user1:/bin/bash
user2:x:1214:1214::/home/user2:/bin/bash
user3:x:1215:1215::/home/user3:/bin/bash

[root@test ~]#ansible websers -m shell -a 'id user1'           
192.168.0.218 | SUCCESS | rc=0 >>
uid=1213(user1) gid=1213(user1) 組=1213(user1),0(root),1(bin),10(wheel)

192.168.0.128 | SUCCESS | rc=0 >>
uid=503(user1) gid=503(user1) 組=503(user1),0(root),1(bin),10(wheel)

[root@test ~]# 

示例:迭代嵌套子變量

[root@test ~]#cat adduser2.yml 
---
- hosts: websers
  remote_user: root
  
  tasks:
    - name: create groups
      group: name={{ item }}
      with_items:
        - group1
        - group2
        - group3
    - name: create users
      user: name={{ item.name }} group={{ item.group }} state=present
      with_items:
        - {name: 'test1',group: 'group1'}
        - {name: 'test2',group: 'group2'}
        - {name: 'test3',group: 'group3'}
[root@test ~]#ansible-playbook adduser2.yml

PLAY [websers] ******************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [192.168.0.128]
ok: [192.168.0.218]

TASK [create groups] ************************************************************************************************
changed: [192.168.0.128] => (item=group1)
changed: [192.168.0.218] => (item=group1)
changed: [192.168.0.128] => (item=group2)
changed: [192.168.0.218] => (item=group2)
changed: [192.168.0.128] => (item=group3)
changed: [192.168.0.218] => (item=group3)

TASK [create users] *************************************************************************************************
changed: [192.168.0.128] => (item={u'group': u'group1', u'name': u'test1'})
changed: [192.168.0.218] => (item={u'group': u'group1', u'name': u'test1'})
changed: [192.168.0.128] => (item={u'group': u'group2', u'name': u'test2'})
changed: [192.168.0.218] => (item={u'group': u'group2', u'name': u'test2'})
changed: [192.168.0.128] => (item={u'group': u'group3', u'name': u'test3'})
changed: [192.168.0.218] => (item={u'group': u'group3', u'name': u'test3'})

PLAY RECAP **********************************************************************************************************
192.168.0.128              : ok=3    changed=2    unreachable=0    failed=0   
192.168.0.218              : ok=3    changed=2    unreachable=0    failed=0   

[root@test ~]#ansible websers -m shell -a 'tail -3 /etc/passwd'
192.168.0.128 | SUCCESS | rc=0 >>
test1:x:506:506::/home/test1:/bin/bash
test2:x:507:507::/home/test2:/bin/bash
test3:x:508:508::/home/test3:/bin/bash

192.168.0.218 | SUCCESS | rc=0 >>
test1:x:1216:1216::/home/test1:/bin/bash
test2:x:1217:1217::/home/test2:/bin/bash
test3:x:1218:1218::/home/test3:/bin/bash

[root@test ~]#ansible websers -m shell -a 'id test1'           
192.168.0.218 | SUCCESS | rc=0 >>
uid=1216(test1) gid=1216(group1) 組=1216(group1)

192.168.0.128 | SUCCESS | rc=0 >>
uid=506(test1) gid=506(group1) 組=506(group1)

[root@test ~]#ansible websers -m shell -a 'id test2'
192.168.0.128 | SUCCESS | rc=0 >>
uid=507(test2) gid=507(group2) 組=507(group2)

192.168.0.218 | SUCCESS | rc=0 >>
uid=1217(test2) gid=1217(group2) 組=1217(group2)

[root@test ~]#ansible websers -m shell -a 'id test3'
192.168.0.128 | SUCCESS | rc=0 >>
uid=508(test3) gid=508(group3) 組=508(group3)

192.168.0.218 | SUCCESS | rc=0 >>
uid=1218(test3) gid=1218(group3) 組=1218(group3)

[root@test ~]#

  說明:以上playbook實現了對應用戶建立時加入對應的組裏

相關文章
相關標籤/搜索