centos7.4之saltstack的系列(三)之state相關

1、管理對象

  saltstack系統中管理對象叫作Target,在master上能夠採用不一樣的Tatget去管理不一樣的minion。這些Target都是經過去管理和匹配Minion的ID來作一些集合。php

  1.一、正則表達式

  # salt -E '[a-z].*' test.ping  #直接就是匹配字母開頭的minionnode

  # salt -E 'a.*' test.ping    #匹配a開頭的minionmysql

  # salt -E '(a|z).*' test.ping   #匹配a或者z開頭的minion,切記是開頭而不是包含。web

  

  1.2  -L : 列表匹配

  #salt  -L  'dasha_ceshi_172.16.5.239,dasha_ceshi_172.16.5.240'  test.ping  ##同時讓多個minion去執行,多minion之間用逗號隔開(這裏只是ID,組的不行)。正則表達式

  1.3  -G : grains匹配

  minions的Grains信息時在Minions服務啓動的時候彙總給Master的,Grains是saltstack組建中很是重要的,由於在配置部署的過程當中會常用它,Grains是saltstack記錄minion的一些靜態信息的組件,grains裏面記錄着每臺minion的一些經常使用屬性如CPU、內存、操做系統類型和版本等,能夠經過grains.item查看某臺minion的全部grains信息。sql

  # salt -G 'os:CentOS' test.ping  #讓minion端操做系統是CentOS去執行,固然也支持正則表達式的方式shell

  # salt -G 'os:C*' test.ping   #如匹配操做系統是C開頭的apache

  # salt -G 'osmajorrelease:[1-9]' test.ping   #匹配系統版本是數字的。centos

  

  1.4  -N : 組匹配

cat  /etc/salt/master | grep nodegroups

  這裏還可使用正則及其餘匹配方式,我這裏寫的是最簡單,也是最繁瑣的一種。安全

nodegroups:
    ceshi1: dasha_ceshi_172.16.5.239
    ceshi2: dasha_ceshi_172.16.5.240

  #salt -N ceshi1 test.ping #測試test這組。

  1.5  -C : 複合匹配

   解釋:複合匹配的意思是,使用不一樣的判斷條件精準的在指定的minion中執行。

#salt -C 'G@os:CentOS and G@osmajorrelease:7' test.ping  #讓os是CentOS而且系統版本是7的去執行

#salt -C 'G@os:CentOS and G@osmajorrelease:7 and E@dasha_ceshi*' test.ping # 在操做系統是CentOS版本是7,而且id開頭是dasha_ceshi的機器是執行test.ping操做。

  1.6  -S : CIDR網段匹配

[root@bogon ~]# salt -S '172.16.5.0/24' test.ping  #匹配IP是172.16.5.0網段的的全部IP地址,執行test.ping操做
dasha_ceshi_172.16.5.240:
    True
dasha_ceshi_172.16.5.239:
    True
[root@bogon ~]# salt -S '172.16.5.239' test.ping #在IP是172.16.5.239服務器上執行test.ping操做。
dasha_ceshi_172.16.5.239:
    True

2、Grains介紹

   Grains上面已經介紹過了,相似於facter。簡單的說就是把minion端在啓動的時候把自身的的各類屬性信息採集彙報給master端,可使用 salt ‘id’ grains.items查看。

  2.1 grains模塊的一些命令行的使用方法:

   # salt '*' grains.ls  #能夠查看有哪些屬性能夠查看,顯示的是屬性的名字,相似於os之類的。

  #salt 'dasha_ceshi_172.16.5.239' grains.item os osrelease oscodename ##知道了屬性的名稱,咱們就能夠查看屬性的值,這裏就是查看os,osrelease,oscodename這三個屬性的值,多屬性用空格隔開。

  # salt '*' grains.items  #這種就是將全部minion端屬性以及屬性的值全打印出來,建議打印是指定某個minion id,不然打印的東西太多。

  2.2 經過minion端配置文件自定義grains:

  上面咱們說了,在master上執行grains.items能查看到不少minion的參數,可是好比設備的具體位置,業務名稱等信息就顯的力不從心了,可是有了minion自定義grains後,就沒有那麼難了。

  minion端的操做:

grains:    #以grains開頭
  roles:    #設置一個屬性叫roles,下面若是多條就像下面同樣- value值,這裏的意思是標註服務器屬於什麼業務
    - webserver
    - memcache
  deployment: bj-zb-5F   #這裏是標註所在機房的位置
  cabinet: B11    #標註所在機櫃的位置
  cab_u: 19-21   #標註所在機櫃的U位

  

  # systemctl restart salt-minion   #上面已經說了,grains信息是在minion端啓動的時候纔會發送,因此要重啓minion端。

   master端的查看:

  # salt 'dasha_ceshi_172.16.5.240'  grains.ls #用這個查看會發現咱們自定義的哪幾個grains的屬性已經出現了。

  #salt '*' grains.item roles deployment cabinet cab_u  #查看咱們在minion自定義的grains信息。

  

  2.3 命令自定義grains(前面咱們說了更改配置文件的自定義,下面咱們來講使用命令自定義)

#salt 'dasha_ceshi_172.16.5.239' grains.append  purpose  'ceshi'  #經過grains.append方法爲dasha_ceshi_172.16.5.239機器添加了一個屬性,purpose  用途,後面跟的值是ceshi,注意空格和引號。

  這種自定義的方法配置文件位置再minion的/etc/salt/grains配置文件中,永久生效,刪除的話,能夠直接去minion操做。還可使用其餘的方法,如grains.setvals來定義多個屬性,或者還能夠刪除自定義的grains。這都是立馬生效並永久生效的。

3、Pillar介紹

  Pillar是saltstack組件中很是重要的一個,是數據管理中心,常常配合states在大規模的配置管理工做中使用它,它的主要做用是存儲和定義配置管理中須要的一些數據。它的定義存儲格式跟grains相似,都是YAML格式。

  下面的操做都是在master端的操做:

# mkdir /srv/pillar #這是master配置文件裏面#pillar_roots:默認指定的路徑。默認不存在須要手工建立。

# cat /srv/pillar/top.sls  #top.sls是配置管理的入口文件,一切都是從這裏開始,這裏是默認位置,在這裏定義誰來執行那個方法或者說模塊。
base:  #top.sls 默認從 base 標籤開始解析執行,下一級是操做的目標,能夠經過正則,grain模塊,或分組名,來進行匹配,再下一級是要執行的state文件,不包換擴展名。

  '*':
    - pkgs
# cat /srv/pillar/pkgs.sls  #一個簡單的根據minion端的grains信息,動態的設置apache軟件包對應的name名稱。前面咱們學習saltstack的minion,咱們知道給客戶端定義新的屬性時候,是須要在客戶端文件加內容的,可是pillar則是在服務器給客戶端定義新屬性,並且不用重啓服務,
pkgs: 

  {% if grains['os_family'] == 'RedHat' %}  
  apache: httpd  
  {% elif grains['os_family'] == 'Debian' %}  
  apache: apache2  
  {% elif grains['os'] == 'Arch' %}  
  apache: apache  
  {% endif %} 

#  salt '*' pillar.item pkgs

  有結果來看,pillar數據是在Salt master上生成的並被安全地分佈到minions上。Salt當定義pillar的時候,沒必要限制在sls文件,也能夠從外部資源得到數據,咱們能夠把Pillar數據。pillar中最強大的抽象之一就是將states參數化的能力。

4、States介紹

  States是SaltStack中的配置語言,在平常進行配置管理時須要編寫大量的States文件。如安裝軟件啊,更改配置啊等,就須要編寫states sls文件(描述狀態配置的文件)去描述和實現這些功能。編寫states sls文件通常是是YAML語法格式,也支持使用Python語言來編寫。

  4.1 相關的states內容

  #salt 'dasha_ceshi_172.16.5.239' sys.list_state_modules  ##查看minion支持的全部states列表。

  1 - acl
  2     - alias
  3     - alternatives
  4     - archive
  5     - artifactory
  6     - beacon
  7     - bigip
  8     - blockdev
  9     - buildout
 10     - ceph
 11     - chronos_job
 12     - cloud
 13     - cmd
 14     - composer
 15     - cron
 16     - cryptdev
 17     - csf
 18     - disk
 19     - elasticsearch
 20     - elasticsearch_index
 21     - elasticsearch_index_template
 22     - environ
 23     - esxdatacenter
 24     - etcd
 25     - ethtool
 26     - event
 27     - file
 28     - firewall
 29     - firewalld
 30     - gem
 31     - glassfish
 32     - gnomedesktop
 33     - gpg
 34     - grafana4_dashboard
 35     - grafana4_datasource
 36     - grafana4_org
 37     - grafana4_user
 38     - grains
 39     - group
 40     - highstate_doc
 41     - hipchat
 42     - host
 43     - http
 44     - incron
 45     - infoblox_a
 46     - infoblox_cname
 47     - infoblox_host_record
 48     - infoblox_range
 49     - ini
 50     - ipset
 51     - iptables
 52     - jboss7
 53     - jenkins
 54     - junos
 55     - k8s
 56     - kernelpkg
 57     - keyboard
 58     - kmod
 59     - ldap
 60     - libcloud_dns
 61     - libcloud_loadbalancer
 62     - libcloud_storage
 63     - locale
 64     - logrotate
 65     - loop
 66     - lxc
 67     - marathon_app
 68     - modjk
 69     - modjk_worker
 70     - module
 71     - mount
 72     - msteams
 73     - network
 74     - nexus
 75     - openstack_config
 76     - opsgenie
 77     - pagerduty
 78     - pagerduty_escalation_policy
 79     - pagerduty_schedule
 80     - pagerduty_service
 81     - pagerduty_user
 82     - pkg
 83     - pkgbuild
 84     - pkgng
 85     - pkgrepo
 86     - powerpath
 87     - process
 88     - pushover
 89     - pyenv
 90     - rbenv
 91     - rvm
 92     - salt
 93     - salt_proxy
 94     - schedule
 95     - serverdensity_device
 96     - service
 97     - slack
 98     - smtp
 99     - solrcloud
100     - sqlite3
101     - ssh_auth
102     - ssh_known_hosts
103     - stateconf
104     - status
105     - statuspage
106     - supervisord
107     - sysctl
108     - syslog_ng
109     - telemetry_alert
110     - test
111     - timezone
112     - tuned
113     - uptime
114     - user
115     - vault
116     - vbox_guest
117     - virtualenv
118     - winrepo
119     - zenoss
全部的state_modules

  #salt 'dasha_ceshi_172.16.5.239' sys.list_state_functions file host   ##查看file和host的全部function,多模塊用空格隔開

 1 dasha_ceshi_172.16.5.239:
 2     - file.absent
 3     - file.accumulated
 4     - file.append
 5     - file.blockreplace
 6     - file.cached
 7     - file.comment
 8     - file.copy
 9     - file.decode
10     - file.directory
11     - file.exists
12     - file.line
13     - file.managed
14     - file.missing
15     - file.mknod
16     - file.mod_run_check_cmd
17     - file.not_cached
18     - file.patch
19     - file.prepend
20     - file.recurse
21     - file.rename
22     - file.replace
23     - file.retention_schedule
24     - file.sdecode
25     - file.serialize
26     - file.shortcut
27     - file.symlink
28     - file.touch
29     - file.uncomment
30     - host.absent
31     - host.only
32     - host.present
詳細

  4.2查看相關的states內容的方法

  # salt 'agent1.salt' sys.list_state_modules  #查看minion支持的全部states列表。

  # salt 'agent1.salt' sys.list_state_functions file host  #查看file和host的全部function,多模塊用空格隔開

  # salt 'agent1.salt' sys.state_doc file #查看指定模塊的function的用法與例子,平常編寫states按照例子編寫即可。

  # salt 'agent1.salt' sys.state_doc file.managed #查看file.managed的詳細用法與例子,這也是咱們常常用到的function。

  4.2 編寫一個簡單的sls文件並執行

  如今咱們有個需求,往minion的特定目錄下傳一個配置文件,前面咱們說過使用cp.get_file方法就能夠傳文件,可是咱們常常要給某些minion傳特定的配置文件的話,使用state的文件傳送就很方便。

  首先咱們先來看一下master裏面state路徑定義的方法,咱們一共定義了三個路徑,base是必需要有的,剩下的隨意,注意空格。注意:salt://這幾個字符分別表明了裏面的三個路徑,好比salt://file/test,絕對路徑就是/srv/salt/base/file/test,/srv/salt/prod/file/test,/srv/salt/test/file/test。

  

  分別建立配置文件裏面的三個路徑,最後完成後必定要重啓master服務。

  如今咱們來看看寫法,首先你要定義個須要傳送到客戶端的文件,能夠新建,隨便寫點內容便可,首先咱們分析一下基本環境,只須要看你標紅位置便可。

  我在base裏面又新建了一個目錄files,我把my.cnf配置文件放在了這裏面,而後我在base下面新建了衣蛾cp_file.sls文件,在這個文件中寫了點傳送文件的內容。

  

  基本寫法介紹:

cp-file-my.cnf:   #惟一表示ID
  file.managed:  #方法,我用哪一個方法,這裏用file.managed方法傳送文件
    - name: /root/my.cnf   #目標機器上的哪一個文件,必定要加文件名。
    - source: salt://files/my.cnf   #master端的路徑,上線咱們說過,這裏的絕對路徑是/srv/salt/base/files/my.cnf
    - user: root   #文件屬主
    - group: root #文件屬組
    - mode: 644  #文件權限

注意:salt全部配置文件裏面禁止用tab鍵,層級關係用兩個空格隔開,-符號後面還有個空格,例如- name: 冒號後面也得有空格。

  寫好具體要作什麼之後,這裏要發送了

#state.sls是用state.sls這個方法,cp_file是隻cp_file.sls這個文件,這裏去掉文件.後面的內容便可,test=True指先測試一下,若是肯定要發送的話,去掉test=True便可。
salt '*'  state.sls cp_file  test=True

這裏可能有同窗要說了,好麻煩啊,我直接scp過去就ok了,你這裏還得寫這麼東東西,彆着急,若是有1000臺機器,你也一個一個scp麼,而這裏我只須要匹配哪些服務器須要便可。

#若是你源文件沒有發生改變,再次執行的話,Comment會提示你這個文件是正確的。Changes:下面沒內容。Succeeded: 1,這就是區別,也就是不更新

 

5、SLS文件介紹

SLS(表明SaLt State文件)是Salt State系統的核心。SLS描述了系統的目標狀態,由格式簡單的數據構成。這常常被稱做配置管理,簡單的講就說你寫了那麼多的路徑和sls文件,到底要讓誰來執行top裏面能夠寫誰來執行哪些sls文件。

5.1 YAML編寫技巧

由於咱們用YAML格式來編寫sls文件,因此掌握編寫技巧利於後面少出錯。

5.1.1 什麼是YAML?

YAML 語言(發音 /ˈjæməl/ )的設計目標,就是方便人類讀寫。它實質上是一種通用的數據串行化格式。語法很簡單,結構經過空格來展現,項目使用「-」來表明,鍵值對使用「:」分隔。
它的基本語法規則以下:
大小寫敏感,以「:」來分隔key和value。對象:鍵值對的集合,又稱爲映射(mapping)/ 哈希(hashes) / 字典(dictionary)。

使用固定的縮進風格表示層級關係。縮進時不容許使用Tab鍵,只容許使用空格,通常每一個縮進級別由兩個空格組成。
# 表示註釋,從這個字符一直到行尾,都會被解析器忽略。

想要表示列表項,使用一個短橫槓加一個空格。多個項目使用一樣的縮進級別做爲同一列表的一部分。列表能夠做爲一個鍵值對的value。

5.2 top.sls

top.sls是配置管理的入口文件,這個很重要在生產中很重要,默認存放在/srv/salt/目錄.默認從base標籤開始解析執行,下一級是操做的目標也就是要對哪些主機進行操做,能夠經過正則、grain模塊或分組名等來進行匹配,而後再下一級是要執行的state文件(不包含.sls擴展名)。

  需求分析:   

  這裏須要說明一下,好比須要裝一個LAMP環境,我分別在新建了/srv/salt/base,/srv/salt/prod/連個salt路徑,我在prod裏面又新建了web,php,mysql三個目錄,分別在三個目錄裏面寫我要作的事情。而後呢?咱們要怎麼傳給所需的minion呢?難道要像上面講的一個一個去執行麼,No!太費事了,我在top文件裏面定義好,誰要幹什麼活,而後執行top文件就行,這樣一條命令解決。那問題來了,top裏面若是去匹配哪些minion呢?下面有幾種不一樣的配置方法。

5.2.1 正則匹配示例:

  基本寫法1:

  首先top文件必須寫在base環境下,必需要叫top.sls,而後咱們看一下基本寫法:

base:  #下面的sls在哪一個路徑這裏就寫什麼
  'dasha_ceshi_172.16.5.239'  #哪一個minion去執行
    - cp_file  #執行哪一個方法

  基本寫法2:

base:  
  'dasha_ceshi_172.16.5.239'  
    - cp_file 
  'dasha_ceshi_172.16.5.240' 
    - cp_file 

  正則寫法1:

base:  #下面的sls在哪一個路徑這裏就寫什麼
  'dasha_ceshi*'  #哪一個minion去執行,不會正則的同窗能夠去看看
    - cp_file  #執行哪一個方法

5.2.2 經過分組名進行匹配示例:

# cat /srv/salt/base/top.sls 
base:
   centosgroups:  #這裏就是咱們上面在master配置文件裏面定義的那個組名
   - match: nodegroup  #這句話是必需要有的,指定以組匹配
   - cp_file 

 

5.2.3 經過grain模塊匹配的示例:

# cat /srv/salt/base/top.sls   #同上-match: grain也是必需要帶的,指定讓其按照grain進行匹配,指定讓os是Centos的操做系統來執行。    
base:
    'os:CentOS':
      - match: grain
      - cp_file 

 

5.2.4 經過複合匹配的示例:

# cat /srv/salt/base/top.sls #上面的grain模塊匹配可能知足不了咱們的匹配條件,我想要更加精確的讓全部Centos6.4的操做系統去執行,就是我下面的設置。
base:
    'G@os:CentOS and G@osrelease:6.4':
        - match: compound
        - cp_file 

 

5.2.5 某一個網段匹配示例:

# cat /srv/salt/base/top.sls 
base:
    '192.168.1.0/24':
        - match: ipcidr
        - cp_file

5.3 state.highstate

# salt '*' state.highstate  #master將會指導全部的目標minions運行 state.highstate。當minion執行highstate,它將會下載top文件中匹配的內容,minion將表達式中匹配的內容下載、編譯、執行。一旦完成,minion將返回全部的動做執行結果和全部更改。基本意思就是誰來執行什麼操做,去看top文件裏面是怎麼寫的,就怎麼執行。

# salt '*' state.highstate test=True  #只是測試執行,相似於模擬,不會在minion真正執行,便於咱們編寫測試時使用,建議每次執行都測試一下。

 

5.5 state的層級關係

  include:將別的SLS添加到當前文件中,因此能夠require或watch被引用的SLS中定義的內容,還能夠extend覆蓋其內容。include語句使得state能夠跨文件引用。使用include至關於把被引用的內容文件添加到自身。

  extend:擴展被引用的SLS數據。不須要重頭寫新的SLS,能夠先直接include sls文件,而後在其基礎上增長或者覆蓋內容。

include(包含):

  首先說應用場景,如今我在prod下面新建了三個目錄web,php,mysql,裏面分別寫了init.sls(初始化環境配置),按照上面的寫法,我須要一鍵執行的話,首先須要在top裏面把它們加進去,以下圖

  

  top.sls

  

  這樣的話,若是我要安裝的環境特別的多,這裏都直接下載top裏面就比較亂了,因此爲了醒目,我在prod下直接新建一個lamp.sls文件,而後把這些操做文件都寫進去,而後就方便了,而後只須要在top文件裏面寫上lamp就oK了,是否是很方便。

  

  這裏只會一種用法,生產中還有不少種用法。

extend(擴展):

   環境需求,若是已經寫好了lamp的安裝配置環境了,而後忽然發現還有安裝一個軟件,這個時候直接去改文件就顯的有點粗暴了,這裏能夠直接在include的裏面寫,例如,這裏我須要給lamp環境下安裝一個tree的包。

  其它的什麼都不須要動,只須要在lamp下添加extend便可。

  這裏注意,既然是擴展,那就得知道給誰擴展,include的中咱們已經標註了要執行的操做是web,php,mysql下的init操做。可是擴展的還怎麼寫呢?extend:是標準寫法,層級關係是兩個空格,那這個id怎麼寫呢?有人說隨便寫,你寫個試試,確定不行。既然是擴展你得指定給誰擴展。我在php裏面的init文件中寫過php-install這個id,這裏我指定是給它擴展,因此必須得把它的id寫在這裏,而後再寫是什麼方法,要幹什麼。這裏須要注意的就是這個id寫法,其實也不難理解,既然是擴展,確定是要寫給誰擴展的,不然不是亂套了。

  

5.6 state的邏輯關係 

  match   : 配模某個模塊,好比 match: grain match: nodegroup
  require: 依賴某個state,在運行此state前,先運行依賴的state,依賴能夠有多個,被誰依賴是require_in
  watch  : 在某個state變化時運行此模塊,watch除具有require功能外,還增了關注狀態的功能,被誰依賴是watch_in。

  order   : 優先級比require和watch低,有order指定的state比沒有order指定的優先級高,假如一個state模塊內安裝多個服務,或者其餘依賴關係,可使用

 require和require_in示例:

   應用場景,首先咱們是肯定哪些操做都作了之後才能執行此操做,好比全部的安裝操做都完成,最後要重啓一些服務,就可使用此參數

  以下,若是file這個模塊下的id是apache-config這個操做成功的話,就執行id是apache-service操做,若是有enable就是重啓,若是有reload的參數就是重載配置。

  require:

  

  require_in:

  寫法以下,能夠理解爲被誰依賴,以下,若是我這個文件操做成功的話就執行service這個模塊的id是apache-service的操做。

  

watch和watch_in示例:

   這個就NB了,它具有require的特性。應用場景,若是咱們服務都安裝完了,這個時候我須要給全部的minion修改一下配置文件,修改完成後從新加載配置文件,用watch就能夠解決,用法和require如出一轍。

  若是file這個模塊下的id是apache-config這個操做成功(首先是從source這個路徑傳送到minino端的name路徑下後,從新加載httpd這個服務)。watch_in用法恰好相反,相似於require_in0。

  

 

6、jinja2的基本使用

  6.一、介紹

  Jinja2 是一個現代的,設計者友好的,仿照 Django 模板的 Python 模板語言。 它速度快,被普遍使用,而且提供了可選的沙箱模板執行環境保證安全:

  參考地址:http://docs.jinkan.org/docs/jinja2/

  Jinja的使用分爲三個步驟:

    1. File狀態使用template參數 - template: jinja。

    2. 模板文件裏面變量使用{{名稱}},好比{{PORT}}.

    3. File狀態模塊裏面指定變量列表。

  6.二、jinji的基本使用

  環境介紹,爲了區分,我在master配置文件中新加一個/srv/salt/jiaja2的模塊。

  

  基本寫法

{% set iplist= grains['ipv4'] %}  #申明變量名稱
/files/minion.conf:  #定義傳輸文件id
  file.managed:   #執行方法
    - name: /root/minion.conf   #目的路徑
    - source: salt://files/minion.conf.jinja   #文件存放位置
    - template: jinja    #申請只用jinja模板
    - defaults:    #定義默認將值傳遞給模板
        IP_ADDR: {{iplist[1]}}  #獲取iplist這個變量的值,由於返回的是一個列表,因此咱們須要取第2個值。

  cat files/minion.conf.jinja 這裏爲了明顯,我只寫了一個值,

  ipaddr:{{IP_ADDR}}

  minion效果

  

  總結,這就很厲害了,好比我定義安裝minion客戶端的某個服務要根據寫入本身的ip地址或者固定端口,就能夠在這裏定義多個變量defaults下面新加就行。它不但能夠寫變量還支持條件判斷和循環。

  6.三、邏輯判斷

  Jinja還主要用來給狀態增長邏輯關係,如for循環,或者if判斷,也是常用到的。

  salt,grains,pillar是salt中jinja裏面的三個特殊字典,salt是包含全部salt函數對象的字典,grains是包含minion上grains的字典,pillar是包含minion上pillar的字典。上面已經介紹瞭如何使用了。

  if...elif...endif的示例:

  # cat /srv/pillar/pkgs.sls

apache:
  pkg.installed: #這是根據系統的不一樣,判斷安裝的軟件名稱。若是有變量就放到{{}}中
  {% if grains['os_family'] == 'RedHat' %}  #jinja中判斷,循環等標籤是放在{% %}中
    - name: httpd  
  {% elif grains['os_family'] == 'Debian' %}  
    - name: apache2  
  {% elif grains['os'] == 'Arch' %}  
    - name: apache  
  {% endif %}   #也會有結束標籤{% end** %}

  #固然還支持:{% if %}...{% elif %}...{% else %}...{% endif %}之類的寫法。

  for循環的示例:

{% set userlist = ['yunwei','cacti','www'] %}
{% for user in userlist %}
{{ user }}:
 user.present:
   - shell: /bin/bash
   - home: /home/{{ user }}
{% endfor %}

  參考地址:http://www.51niux.com/?id=117

相關文章
相關標籤/搜索