Ansible之Playbook
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.36 192.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
條件測試:如果需要根據變量、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
1)編寫playbook
[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
1)編寫playbook
[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
2)模板文件編寫
[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 %}
3)執行playbook
並查看生成結果
[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判斷,讓生成的配置文件更加靈活
1)編寫playbook
[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
2)模板文件編寫
# 說明:這里添加了判斷,如果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 %}
3)執行playbook
並查看生成結果
[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; }
上面三個示例的圖片展示效果
例一
例二
例三