天天看點

Ansible之Playbook

Playbook與ad-hoc相比,是一種完全不同的運用ansible的方式,類似與saltstack的state狀态檔案。ad-hoc無法持久使用,playbook可以持久使用。

playbook是由一個或多個play組成的清單,play的主要功能在于将事先歸并為一組的主機裝扮成事先通過ansible中的task定義好的角色。從根本上來講,所謂的task無非是調用ansible的一個module。将多個play組織在一個playbook中,即可以讓它們聯合起來按事先編排的機制完成某一任務

Playbook核心元素

#

  • Hosts 執行的遠端主機清單
  • Tasks 任務集
  • Varniables 内置變量或自定義變量在playbook中調用
  • Templates 模闆,即使用模闆文法的檔案,比如配置檔案等
  • Handlers 和notity結合使用,由特定條件觸發的操作,滿足條件方才執行,否則不執行
  • tags 标簽,指定某條任務執行,用于選擇運作playbook中的部分代碼。

Playbook文法

playbook使用yaml文法格式,字尾可以是yaml,也可以是yml。

  • 在單一一個playbook檔案中,可以連續三個連子号(---)區分多個play。還有選擇性的連續三個點好(...)用來表示play的結尾,也可省略。
  • 次行開始正常寫playbook的内容,一般都會寫上描述該playbook的功能。
  • 使用#号注釋代碼。
  • 縮進必須統一,不能空格和tab混用。
  • 縮進的級别也必須是一緻的,同樣的縮進代表同樣的級别,程式判别配置的級别是通過縮進結合換行實作的。
  • YAML檔案内容和Linux系統大小寫判斷方式保持一緻,是區分大小寫的,k/v的值均需大小寫敏感
  • k/v的值可同行寫也可以換行寫。同行使用:分隔。
  • v可以是個字元串,也可以是一個清單
  • 一個完整的代碼塊功能需要最少元素包括 name: task

一個簡單的示例

# 建立playbook檔案 [root@ansible ~]# cat playbook01.yml--- #固定格式- hosts: 192.168.1.31 #定義需要執行主機 remote_user: root #遠端使用者 vars: #定義變量 http_port: 8088 #變量 tasks: #定義一個任務的開始 - name: create new file #定義任務的名稱 file: name=/tmp/playtest.txt state=touch #調用子產品,具體要做的事情 - name: create new user user: name=test02 system=yes shell=/sbin/nologin - name: install package yum: name=httpd - name: config httpd template: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf notify: #定義執行一個動作(action)讓handlers來引用執行,與handlers配合使用 - restart apache #notify要執行的動作,這裡必須與handlers中的name定義内容一緻 - name: copy index.html copy: src=/var/www/html/index.html dest=/var/www/html/index.html - name: start httpd service: name=httpd state=started handlers: #處理器:更加tasks中notify定義的action觸發執行相應的處理動作 - name: restart apache #要與notify定義的内容相同 service: name=httpd state=restarted #觸發要執行的動作 #測試頁面準備 [root@ansible ~]# echo "<h1>playbook test file</h1>" >>/var/www/html/index.html #配置檔案準備 [root@ansible ~]# cat httpd.conf |grep ^Listen Listen {{ http_port }} #執行playbook, 第一次執行可以加-C選項,檢查寫的playbook是否ok [root@ansible ~]# ansible-playbook playbook01.yml PLAY [192.168.1.31] *********************************************************************************************TASK [Gathering Facts] ******************************************************************************************ok: [192.168.1.31] TASK [create new file] ******************************************************************************************changed: [192.168.1.31] TASK [create new user] ******************************************************************************************changed: [192.168.1.31] TASK [install package] ******************************************************************************************changed: [192.168.1.31] TASK [config httpd] *********************************************************************************************changed: [192.168.1.31] TASK [copy index.html] ******************************************************************************************changed: [192.168.1.31] TASK [start httpd] **********************************************************************************************changed: [192.168.1.31] PLAY RECAP ******************************************************************************************************192.168.1.31 : ok=7 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 # 驗證上面playbook執行的結果 [root@ansible ~]# ansible 192.168.1.31 -m shell -a 'ls /tmp/playtest.txt && id test02'192.168.1.31 | CHANGED | rc=0 >> /tmp/playtest.txt uid=990(test02) gid=985(test02) 組=985(test02) [root@ansible ~]# curl 192.168.1.31:8088<h1>playbook test file</h1>

Playbook的運作方式

通過ansible-playbook指令運作

格式:ansible-playbook <filename.yml> ... [options]

[root@ansible PlayBook]# ansible-playbook -h #ansible-playbook常用選項:--check or -C #隻檢測可能會發生的改變,但不真正執行操作--list-hosts #列出運作任務的主機--list-tags #列出playbook檔案中定義所有的tags--list-tasks #列出playbook檔案中定義的是以任務集--limit #主機清單 隻針對主機清單中的某個主機或者某個組執行-f #指定并發數,預設為5個-t #指定tags運作,運作某一個或者多個tags。(前提playbook中有定義tags)-v #顯示過程 -vv -vvv更詳細

Playbook中元素屬性

主機與使用者

在一個playbook開始時,最先定義的是要操作的主機和使用者

--- - hosts: 192.168.1.31 remote_user: root

除了上面的定義外,還可以在某一個tasks中定義要執行該任務的遠端使用者

tasks: - name: run df -h remote_user: test shell: name=df -h

還可以定義使用sudo授權使用者執行該任務

tasks: - name: run df -h sudo_user: test sudo: yes shell: name=df -h

tasks任務清單

每一個task必須有一個名稱name,這樣在運作playbook時,從其輸出的任務執行資訊中可以很清楚的辨識是屬于哪一個task的,如果沒有定義 name,action的值将會用作輸出資訊中标記特定的task。

每一個playbook中可以包含一個或者多個tasks任務清單,每一個tasks完成具體的一件事,(任務子產品)比如建立一個使用者或者安裝一個軟體等,在hosts中定義的主機或者主機組都将會執行這個被定義的tasks。

tasks: - name: create new file file: path=/tmp/test01.txt state=touch - name: create new user user: name=test001 state=present

Handlers與Notify

很多時候當我們某一個配置發生改變,我們需要重新開機服務,(比如httpd配置檔案檔案發生改變了)這時候就可以用到handlers和notify了;

(當發生改動時)notify actions會在playbook的每一個task結束時被觸發,而且即使有多個不同task通知改動的發生,notify actions隻會被觸發一次;比如多個resources指出因為一個配置檔案被改動,是以apache需要重新開機,但是重新啟動的操作隻會被執行一次。

[root@ansible ~]# cat httpd.yml #用于安裝httpd并配置啟動--- - hosts: 192.168.1.31 remote_user: root tasks: - name: install httpd yum: name=httpd state=installed - name: config httpd template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf notify: - restart httpd - name: start httpd service: name=httpd state=started handlers: - name: restart httpd service: name=httpd state=restarted #這裡隻要對httpd.conf配置檔案作出了修改,修改後需要重新開機生效,在tasks中定義了restart httpd這個action,然後在handlers中引用上面tasks中定義的notify。

Playbook中變量的使用

環境說明:這裡配置了兩個組,一個apache組和一個nginx組

[root@ansible PlayBook]# cat /etc/ansible/hosts [apache]192.168.1.36192.168.1.33 [nginx]192.168.1.3[1:2]

指令行指定變量

執行playbook時候通過參數-e傳入變量,這樣傳入的變量在整個playbook中都可以被調用,屬于全局變量

[root@ansible PlayBook]# cat variables.yml --- - hosts: all remote_user: root tasks: - name: install pkg yum: name={{ pkg }} #執行playbook 指定pkg [root@ansible PlayBook]# ansible-playbook -e "pkg=httpd" variables.yml

hosts檔案中定義變量

在/etc/ansible/hosts檔案中定義變量,可以針對每個主機定義不同的變量,也可以定義一個組的變量,然後直接在playbook中直接調用。注意,組中定義的變量沒有單個主機中的優先級高。

# 編輯hosts檔案定義變量 [root@ansible PlayBook]# vim /etc/ansible/hosts [apache]192.168.1.36 webdir=/opt/test #定義單個主機的變量192.168.1.33[apache:vars] #定義整個組的統一變量 webdir=/web/test [nginx]192.168.1.3[1:2] [nginx:vars] webdir=/opt/web # 編輯playbook檔案 [root@ansible PlayBook]# cat variables.yml --- - hosts: all remote_user: root tasks: - name: create webdir file: name={{ webdir }} state=directory #引用變量 # 執行playbook [root@ansible PlayBook]# ansible-playbook variables.yml

playbook檔案中定義變量

編寫playbook時,直接在裡面定義變量,然後直接引用,可以定義多個變量;注意:如果在執行playbook時,又通過-e參數指定變量的值,那麼會以-e參數指定的為準。

# 編輯playbook [root@ansible PlayBook]# cat variables.yml --- - hosts: all remote_user: root vars: #定義變量 pkg: nginx #變量1 dir: /tmp/test1 #變量2 tasks: - name: install pkg yum: name={{ pkg }} state=installed #引用變量 - name: create new dir file: name={{ dir }} state=directory #引用變量 # 執行playbook [root@ansible PlayBook]# ansible-playbook variables.yml # 如果執行時候又重新指定了變量的值,那麼會已重新指定的為準 [root@ansible PlayBook]# ansible-playbook -e "dir=/tmp/test2" variables.yml

調用setup子產品擷取變量

setup子產品預設是擷取主機資訊的,有時候在playbook中需要用到,是以可以直接調用。常用的參數

參考

# 編輯playbook檔案 [root@ansible PlayBook]# cat variables.yml --- - hosts: all remote_user: root tasks: - name: create file file: name={{ ansible_fqdn }}.log state=touch #引用setup中的ansible_fqdn # 執行playbook [root@ansible PlayBook]# ansible-playbook variables.yml

獨立的變量YAML檔案中定義

為了友善管理将所有的變量統一放在一個獨立的變量YAML檔案中,laybook檔案直接引用檔案調用變量即可。

# 定義存放變量的檔案 [root@ansible PlayBook]# cat var.yml var1: vsftpd var2: httpd # 編寫playbook [root@ansible PlayBook]# cat variables.yml --- - hosts: all remote_user: root vars_files: #引用變量檔案 - ./var.yml #指定變量檔案的path(這裡可以是絕對路徑,也可以是相對路徑) tasks: - name: install package yum: name={{ var1 }} #引用變量 - name: create file file: name=/tmp/{{ var2 }}.log state=touch #引用變量 # 執行playbook [root@ansible PlayBook]# ansible-playbook variables.yml

Playbook中标簽的使用

一個playbook檔案中,執行時如果想執行某一個任務,那麼可以給每個任務集進行打标簽,這樣在執行的時候可以通過-t選擇指定标簽執行,還可以通過--skip-tags選擇除了某個标簽外全部執行等。

# 編輯playbook [root@ansible PlayBook]# cat httpd.yml --- - hosts: 192.168.1.31 remote_user: root tasks: - name: install httpd yum: name=httpd state=installed tags: inhttpd - name: start httpd service: name=httpd state=started tags: sthttpd - name: restart httpd service: name=httpd state=restarted tags: - rshttpd - rs_httpd # 正常執行的結果 [root@ansible PlayBook]# ansible-playbook httpd.yml PLAY [192.168.1.31] ************************************************************************************************************************** TASK [Gathering Facts] ***********************************************************************************************************************ok: [192.168.1.31] TASK [install httpd] *************************************************************************************************************************ok: [192.168.1.31] TASK [start httpd] ***************************************************************************************************************************ok: [192.168.1.31] TASK [restart httpd] *************************************************************************************************************************changed: [192.168.1.31] PLAY RECAP ***********************************************************************************************************************************192.168.1.31 : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

1)通過-t選項指定tags進行執行

# 通過-t指定tags名稱,多個tags用逗号隔開 [root@ansible PlayBook]# ansible-playbook -t rshttpd httpd.yml PLAY [192.168.1.31] ************************************************************************************************************************** TASK [Gathering Facts] ***********************************************************************************************************************ok: [192.168.1.31] TASK [restart httpd] *************************************************************************************************************************changed: [192.168.1.31] PLAY RECAP ***********************************************************************************************************************************192.168.1.31 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

2)通過--skip-tags選項排除不執行的tags

[root@ansible PlayBook]# ansible-playbook --skip-tags inhttpd httpd.yml PLAY [192.168.1.31] ************************************************************************************************************************** TASK [Gathering Facts] ***********************************************************************************************************************ok: [192.168.1.31] TASK [start httpd] ***************************************************************************************************************************ok: [192.168.1.31] TASK [restart httpd] *************************************************************************************************************************changed: [192.168.1.31] PLAY RECAP ***********************************************************************************************************************************192.168.1.31 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Playbook中模闆的使用

template模闆為我們提供了動态配置服務,使用jinja2語言,裡面支援多種條件判斷、循環、邏輯運算、比較操作等。其實說白了也就是一個檔案,和之前配置檔案使用copy一樣,隻是使用copy,不能根據伺服器配置不一樣進行不同動态的配置。這樣就不利于管理。

說明:

1、多數情況下都将template檔案放在和playbook檔案同級的templates目錄下(手動建立),這樣playbook檔案中可以直接引用,會自動去找這個檔案。如果放在别的地方,也可以通過絕對路徑去指定。

2、模闆檔案字尾名為.j2。

循環參考

示例:通過template安裝httpd

1)playbook檔案編寫

[root@ansible PlayBook]# cat testtmp.yml #模闆示例--- - hosts: all remote_user: root vars: - listen_port: 88 #定義變量 tasks: - name: Install Httpd yum: name=httpd state=installed - name: Config Httpd template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf #使用模闆 notify: Restart Httpd - name: Start Httpd service: name=httpd state=started handlers: - name: Restart Httpd service: name=httpd state=restarted

2)模闆檔案準備,httpd配置檔案準備,這裡配置檔案端口使用了變量

[root@ansible PlayBook]# cat templates/httpd.conf.j2 |grep ^Listen Listen {{ listen_port }}

3)檢視目錄結構

# 目錄結構 [root@ansible PlayBook]# tree . . ├── templates │   └── httpd.conf.j2 └── testtmp.yml 1 directory, 2 files

4)執行playbook,由于192.168.1.36那台機器是6的系統,模闆檔案裡面的配置檔案是7上面預設的httpd配置檔案,httpd版本不一樣(6預設版本為2.2.15,7預設版本為2.4.6),是以拷貝過去後啟動報錯。下面使用playbook中的判斷語句進行處理;此處先略過

[root@ansible PlayBook]# ansible-playbook testtmp.yml PLAY [all] ****************************************************************************************** TASK [Gathering Facts] ******************************************************************************ok: [192.168.1.36] ok: [192.168.1.32] ok: [192.168.1.33] ok: [192.168.1.31] TASK [Install Httpd] ********************************************************************************ok: [192.168.1.36] ok: [192.168.1.33] ok: [192.168.1.32] ok: [192.168.1.31] TASK [Config Httpd] *********************************************************************************changed: [192.168.1.31] changed: [192.168.1.33] changed: [192.168.1.32] changed: [192.168.1.36] TASK [Start Httpd] **********************************************************************************fatal: [192.168.1.36]: FAILED! => {"changed": false, "msg": "httpd: Syntax error on line 56 of /etc/httpd/conf/httpd.conf: Include directory '/etc/httpd/conf.modules.d' not found\n"} changed: [192.168.1.32] changed: [192.168.1.33] changed: [192.168.1.31] RUNNING HANDLER [Restart Httpd] *********************************************************************changed: [192.168.1.31] changed: [192.168.1.32] changed: [192.168.1.33] PLAY RECAP ******************************************************************************************192.168.1.31 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.1.32 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.1.33 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 192.168.1.36 : ok=3 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

template之when

when語句參考

條件測試:如果需要根據變量、facts或此前任務的執行結果來做為某task執行與否的前提時要用到條件測試,通過when語句執行,在task中使用jinja2的文法格式、

when語句:

在task後添加when子句即可使用條件測試;when語句支援jinja2表達式文法。

類似這樣:

tasks: - command: /bin/false register: result ignore_errors: True - command: /bin/something when: result|failed - command: /bin/something_else when: result|success - command: /bin/still/something_else when: result|skipped

示例:通過when語句完善上面的httpd配置

1)準備兩個配置檔案,一個centos6系統httpd配置檔案,一個centos7系統httpd配置檔案。

[root@ansible PlayBook]# tree templates/templates/├── httpd6.conf.j2 #6系統2.2.15版本httpd配置檔案 └── httpd7.conf.j2 #7系統2.4.6版本httpd配置檔案 0 directories, 2 files

2)修改playbook檔案,通過setup子產品擷取系統版本去判斷。

setup常用子產品

[root@ansible PlayBook]# cat testtmp.yml #when示例--- - hosts: all remote_user: root vars: - listen_port: 88 tasks: - name: Install Httpd yum: name=httpd state=installed - name: Config System6 Httpd template: src=httpd6.conf.j2 dest=/etc/httpd/conf/httpd.conf when: ansible_distribution_major_version == "6" #判斷系統版本,為6便執行上面的template配置6的配置檔案 notify: Restart Httpd - name: Config System7 Httpd template: src=httpd7.conf.j2 dest=/etc/httpd/conf/httpd.conf when: ansible_distribution_major_version == "7" #判斷系統版本,為7便執行上面的template配置7的配置檔案 notify: Restart Httpd - name: Start Httpd service: name=httpd state=started handlers: - name: Restart Httpd service: name=httpd state=restarted

3)執行playbook

[root@ansible PlayBook]# ansible-playbook testtmp.yml PLAY [all] ****************************************************************************************** TASK [Gathering Facts] ******************************************************************************ok: [192.168.1.31] ok: [192.168.1.32] ok: [192.168.1.33] ok: [192.168.1.36] TASK [Install Httpd] ********************************************************************************ok: [192.168.1.32] ok: [192.168.1.33] ok: [192.168.1.31] ok: [192.168.1.36] TASK [Config System6 Httpd] *************************************************************************skipping: [192.168.1.33] skipping: [192.168.1.31] skipping: [192.168.1.32] changed: [192.168.1.36] TASK [Config System7 Httpd] *************************************************************************skipping: [192.168.1.36] changed: [192.168.1.33] changed: [192.168.1.31] changed: [192.168.1.32] TASK [Start Httpd] **********************************************************************************ok: [192.168.1.36] ok: [192.168.1.31] ok: [192.168.1.32] ok: [192.168.1.33] RUNNING HANDLER [Restart Httpd] *********************************************************************changed: [192.168.1.33] changed: [192.168.1.31] changed: [192.168.1.32] changed: [192.168.1.36] PLAY RECAP ******************************************************************************************192.168.1.31 : ok=5 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 192.168.1.32 : ok=5 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 192.168.1.33 : ok=5 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 192.168.1.36 : ok=5 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0

template之with_items

with_items疊代,當有需要重複性執行的任務時,可以使用疊代機制。

對疊代項的引用,固定變量名為“item”,要在task中使用with_items給定要疊代的元素清單。

清單格式:

  字元串

  字典

示例1:通過with_items安裝多個不同軟體

編寫playbook

[root@ansible PlayBook]# cat testwith.yml # 示例with_items--- - hosts: all remote_user: root tasks: - name: Install Package yum: name={{ item }} state=installed #引用item擷取值 with_items: #定義with_items - httpd - vsftpd - nginx

上面tasks寫法等同于:

--- - hosts: all remote_user: root tasks: - name: Install Httpd yum: name=httpd state=installed - name: Install Vsftpd yum: name=vsftpd state=installed - name: Install Nginx yum: name=nginx state=installed

示例2:通過嵌套子變量建立使用者并加入不同的組

1)編寫playbook

[root@ansible PlayBook]# cat testwith01.yml # 示例with_items嵌套子變量--- - hosts: all remote_user: root tasks: - name: Create New Group group: name={{ item }} state=present with_items: - group1 - group2 - group3 - name: Create New User user: name={{ item.name }} group={{ item.group }} state=present with_items: - { name: 'user1', group: 'group1' } - { name: 'user2', group: 'group2' } - { name: 'user3', group: 'group3' }

2)執行playbook并驗證

# 執行playbook [root@ansible PlayBook]# ansible-playbook testwith01.yml # 驗證是否成功建立使用者及組 [root@ansible PlayBook]# ansible all -m shell -a 'tail -3 /etc/passwd'192.168.1.36 | CHANGED | rc=0 >>user1:x:500:500::/home/user1:/bin/bash user2:x:501:501::/home/user2:/bin/bash user3:x:502:502::/home/user3:/bin/bash 192.168.1.32 | CHANGED | rc=0 >>user1:x:1001:1001::/home/user1:/bin/bash user2:x:1002:1002::/home/user2:/bin/bash user3:x:1003:1003::/home/user3:/bin/bash 192.168.1.31 | CHANGED | rc=0 >>user1:x:1002:1003::/home/user1:/bin/bash user2:x:1003:1004::/home/user2:/bin/bash user3:x:1004:1005::/home/user3:/bin/bash 192.168.1.33 | CHANGED | rc=0 >>user1:x:1001:1001::/home/user1:/bin/bash user2:x:1002:1002::/home/user2:/bin/bash user3:x:1003:1003::/home/user3:/bin/bash

template之for if

通過使用for,if可以更加靈活的生成配置檔案等需求,還可以在裡面根據各種條件進行判斷,然後生成不同的配置檔案、或者伺服器配置相關等。

示例1

[root@ansible PlayBook]# cat testfor01.yml # template for 示例--- - hosts: all remote_user: root vars: nginx_vhost_port: - 81 - 82 - 83 tasks: - name: Templage Nginx Config template: src=nginx.conf.j2 dest=/tmp/nginx_test.conf

2)模闆檔案編寫

# 循環playbook檔案中定義的變量,依次指派給port [root@ansible PlayBook]# cat templates/nginx.conf.j2 {% for port in nginx_vhost_port %} server{ listen: {{ port }}; server_name: localhost; } {% endfor %}

3)執行playbook并檢視生成結果

[root@ansible PlayBook]# ansible-playbook testfor01.yml # 去到一個節點看下生成的結果發現自動生成了三個虛拟主機 [root@linux ~]# cat /tmp/nginx_test.conf server{ listen: 81; server_name: localhost; } server{ listen: 82; server_name: localhost; } server{ listen: 83; server_name: localhost; }

示例2

[root@ansible PlayBook]# cat testfor02.yml # template for 示例--- - hosts: all remote_user: root vars: nginx_vhosts: - web1: listen: 8081 server_name: "web1.example.com" root: "/var/www/nginx/web1" - web2: listen: 8082 server_name: "web2.example.com" root: "/var/www/nginx/web2" - web3: listen: 8083 server_name: "web3.example.com" root: "/var/www/nginx/web3" tasks: - name: Templage Nginx Config template: src=nginx.conf.j2 dest=/tmp/nginx_vhost.conf

[root@ansible PlayBook]# cat templates/nginx.conf.j2 {% for vhost in nginx_vhosts %} server{ listen: {{ vhost.listen }}; server_name: {{ vhost.server_name }}; root: {{ vhost.root }}; } {% endfor %}

[root@ansible PlayBook]# ansible-playbook testfor02.yml # 去到一個節點看下生成的結果發現自動生成了三個虛拟主機 [root@linux ~]# cat /tmp/nginx_vhost.conf server{ listen: 8081; server_name: web1.example.com; root: /var/www/nginx/web1; } server{ listen: 8082; server_name: web2.example.com; root: /var/www/nginx/web2; } server{ listen: 8083; server_name: web3.example.com; root: /var/www/nginx/web3; }

示例3

在for循環中再嵌套if判斷,讓生成的配置檔案更加靈活

[root@ansible PlayBook]# cat testfor03.yml # template for 示例--- - hosts: all remote_user: root vars: nginx_vhosts: - web1: listen: 8081 root: "/var/www/nginx/web1" - web2: server_name: "web2.example.com" root: "/var/www/nginx/web2" - web3: listen: 8083 server_name: "web3.example.com" root: "/var/www/nginx/web3" tasks: - name: Templage Nginx Config template: src=nginx.conf.j2 dest=/tmp/nginx_vhost.conf

# 說明:這裡添加了判斷,如果listen沒有定義的話,預設端口使用8888,如果server_name有定義,那麼生成的配置檔案中才有這一項。 [root@ansible PlayBook]# cat templates/nginx.conf.j2 {% for vhost in nginx_vhosts %} server{ {% if vhost.listen is defined %} listen: {{ vhost.listen }}; {% else %} listen: 8888; {% endif %} {% if vhost.server_name is defined %} server_name: {{ vhost.server_name }}; {% endif %} root: {{ vhost.root }}; } {% endfor %}

[root@ansible PlayBook]# ansible-playbook testfor03.yml # 去到一個節點看下生成的結果發現自動生成了三個虛拟主機 [root@linux ~]# cat /tmp/nginx_vhost.conf server{ listen: 8081; root: /var/www/nginx/web1; } server{ listen: 8888; server_name: web2.example.com; root: /var/www/nginx/web2; } server{ listen: 8083; server_name: web3.example.com; root: /var/www/nginx/web3; }