Tags
https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html
http://www.zsythink.net/archives/2641
tags用於讓用戶選擇運行playbook中的部分代碼。ansible具有冪等性,因此會自動跳過沒有變化的部分,即便如此,有些代碼為測試其確實沒有發生變化的時間依然會非常地長。此時,如果確信其沒有變化,就可以通過tags跳過此些代碼片斷。
tags:在playbook中可以為某個或這些任務定義一個"標簽",在執行此playbook時,通過ansible-playbook命令使用--tags選項能實現僅運行指定的tasks而非所有的。
# vim apache.yml //在配置文件修改以后,沒有必要把整個playbook定義的tasks都運行一遍。運行playbooks時只需指定說明需要運行的task。
1 - hosts: websrvs //如何只運行所需要運行的task?可以給每個task都給一個單獨的標簽或者只給需要鄖運行的task一個單獨的標簽,在運行ansible-playbook明確指明標簽對應的task就可以了。 2 remote_user: root 3 vars: 4 - package: httpd 5 - service: httpd 6 tasks: //第一次運行的時候,tasks全部運行一邊,再次運行時可以只運行一分部內容 7 - name: install httpd package //比如第一個tasks在第一次運行后,如果配置文件發生改變,那么再次執行tasks時,沒有必要把此tasks再執行一遍,因為即使執行了也沒有發生任何改變。 8 yum: name={{ package }} state=latest 9 - name: install configuration file for httpd //文件修改后,可以之運行這個任務,其他的任務可以不運行 10 template: src=/root/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf 11 tags: //此處定義標簽 12 - conf //標簽對應的task名字 13 notify: 14 - restart httpd 15 - name: start httpd service 16 service: name={{ service }} enabled=true state=started 17 handlers: 18 - name: restart httpd 19 service: name=httpd state=restarted
# vim /etc/ansible/hosts //對websrvs進行修改,表示playbook中定義的配置文件有修改
[websrvs]
192.168.184.142 http_port=8080
192.168.184.143 http_port=80
# ansible-playbook apache.yml --tags="conf"
1 PLAY [websrvs] *********************************************************************************************************************** 2 3 TASK [Gathering Facts] *************************************************************************************************************** 4 ok: [192.168.184.143] 5 ok: [192.168.184.142] 6 //安裝程序包的task和啟動服務的task都沒有執行,而是直接復制配置文件到被管控主機。 7 TASK [install configuration file for httpd] ****************************************************************************************** 8 changed: [192.168.184.143] //這里只運行了標簽tags為conf的task 9 changed: [192.168.184.142] 10 11 RUNNING HANDLER [restart httpd] ****************************************************************************************************** 12 changed: [192.168.184.142] //由於存在notify機制,所以在配置文件修改后會重啟服務 13 changed: [192.168.184.143] 14 15 PLAY RECAP *************************************************************************************************************************** 16 192.168.184.142 : ok=3 changed=2 unreachable=0 failed=0 17 192.168.184.143 : ok=3 changed=2 unreachable=0 failed=0
Roles詳解
ansilbe自1.2版本引入的新特性,用於層次性、結構化地組織playbook。roles能夠根據層次型結構自動裝載變量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。簡單來講,roles就是通過分別將變量、文件、任務、模板及處理器放置於單獨的目錄中,並可以便捷地include它們的一種機制。角色一般用於基於主機構建服務的場景中,但也可以是用於構建守護進程等場景中。
一個roles的案例如下所示:
site.yml //整個yml文件的主調接口
webservers.yml //兩個子yml文件
dbservers.yml
roles/ //roles里面定義了多個role
common/ //第一個是通行角色,無論是通行角色還是服務器角色下都有子目錄
files/ //文件:源文件和目標文件
templates/ //模板
tasks/ //所有的task
handlers/ //處理器
vars/ //變量
meta/ //元數據
webservers/ //服務器角色
files/
templates/
tasks/
handlers/
vars/
meta/
而在playbook中,可以這樣使用roles:
---
- hosts: webservers
roles: //定義roles為common和webservers,直接調用roles里面的內容
- common
- webservers
也可以向roles傳遞參數,例如:
---
- hosts: webservers
roles: //調用roles時
- common
- { role: foo_app_instance, dir: '/opt/a', port: 5000 } //foo_app_instance是角色,傳遞某個參數dir: '/opt/a', port: 5000
- { role: foo_app_instance, dir: '/opt/b', port: 5001 }
甚至也可以條件式地使用roles,例如:
---
- hosts: webservers
roles:
- { role: some_role, when: "ansible_os_family == 'RedHat'" }
創建role的步驟
(1) 創建以roles命名的目錄;
(2) 在roles目錄中分別創建以各角色名稱命名的目錄,如webservers等;
(3) 在每個角色命名的目錄中分別創建files、handlers、meta、tasks、templates和vars目錄;用不到的目錄可以創建為空目錄,也可以不創建;
(4) 在playbook文件中,調用各角色;
role內各目錄中可用的文件
tasks目錄:至少應該包含一個名為main.yml的文件,其定義了此角色的任務列表;此文件可以使用include包含其它的位於此目錄中的task文件;
files目錄:存放由copy或script等模塊調用的文件;
templates目錄:template模塊會自動在此目錄中尋找Jinja2模板文件;
handlers目錄:此目錄中應當包含一個main.yml文件,用於定義此角色用到的各handler;在handler中使用include包含的其它的handler文件也應該位於此目錄中;
vars目錄:應當包含一個main.yml文件,用於定義此角色用到的變量;
meta目錄:應當包含一個main.yml文件,用於定義此角色的特殊設定及其依賴關系;ansible 1.3及其以后的版本才支持;
default目錄:為當前角色設定默認變量時使用此目錄;應當包含一個main.yml文件;
什么場景下可以用到role?
有三台主機,A配置成httpd服務器,B配置為php服務器,C配置成MySQL server。這三台服務都要配置上ntp服務,方便同步時間,這里使用crontab命令來執行。
如何定義playbook?第一個play應用於A即web server上,第二個play應用於B即php server,第三個play應用於C即mysql server,但是這樣操作不利於模塊化和重復調用。假如隨后又加進一個主機D,既要配置成web server又要配置成php server,那么可能就要寫第四個play應用於D主機了。
為了避免代碼重復,roles定義的功用可以實現代碼被多次調用。比如定義三個角色分別是:websrvs、phpsrvs和dbsrvs,那么下面調用角色就如下所示:
hosts: A //當定義主機A時,使用websrvs角色
role:
- websrvs
hosts: B //當定義主機B時,使用phpsrvs角色
role:
- phpsrvs //當定義主機C時,使用dbsrvs角色
hosts: C
role:
- dbsrvs //當定義主機D時,使用websrvs角色和phpsrvs角色
hosts: D
role:
- websrvs
- phpsrvs
實驗示例
# mkdir -pv ansible_playbooks/roles/{websrvs,dbsrvs}/{tasks,files,templates,meta,handlers,vars} //按照規定創建目錄
# tree ansible_playbooks/ //查看此目錄的樹形結構
ansible_playbooks/
└── roles
├── dbsrvs
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
└── websrvs
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars
# cd ansible_playbooks/roles/websrvs/ //要注意目錄的改變
# cp /etc/httpd/conf/httpd.conf files/ //這里假設每一個服務的配置文都是相同的,當作靜態文件使用
# vim tasks/main.yml //定義所有的任務
- name: install httpd package yum: name=httpd - name: install configuration file copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf //注意:src使用的相對路徑,即相對於ansible_playbooks/roles/websrvs/files,files下的文件都可以使用相對路徑,直接調用 tags: - conf notify: - restart httpd //注意這里需要用到觸發器handlers,需要另外定義 - name: start httpd service: name=httpd state=started
# vim handlers/main.yml //此前把handlers和任務都是定義在一個文件中,現在需要分別定義,每一個內容都放在以它的標簽命名的目錄下面
//注意路徑:ansible_playbooks/roles/websrvs
- name: restart httpd
service: name=httpd state=restarted
# vim vars/main.yml //如果還要定義變量,就需要在ansible_playbooks/roles/websrvs/vars目錄下定義變量,這里可以暫時先刪除
- http_port: 80 //這里只是作為示例
以上就定義了websrvs這個角色,如果想調用這個角色,需要在roles的目錄之外創建一個固定格式為site.yml的文件。
# vim site.yml //定義playbook,只需在這個文件中定義調用那個角色就可以了
- hosts: websrvs //定義playbook所應用的主機
remote_user: root
role: //定義上面所指定主機的應用角色
- websrvs //角色名字,這個角色里面所有tasks、handlers、vars都可以在這里調用
# ansible-playbook site.yml //由於被管控主機之前已經安裝了httpd程序,所以這里只是修改了配置文件
PLAY [websrvs] *********************************************************************************************************************** TASK [Gathering Facts] *************************************************************************************************************** ok: [192.168.184.143] ok: [192.168.184.142] TASK [websrvs : install httpd package] *********************************************************************************************** ok: [192.168.184.142] ok: [192.168.184.143] TASK [websrvs : install configuration file] ****************************************************************************************** changed: [192.168.184.143] changed: [192.168.184.142] TASK [websrvs : start httpd] ********************************************************************************************************* ok: [192.168.184.142] ok: [192.168.184.143] RUNNING HANDLER [websrvs : restart httpd] ******************************************************************************************** changed: [192.168.184.143] changed: [192.168.184.142] PLAY RECAP *************************************************************************************************************************** 192.168.184.142 : ok=5 changed=2 unreachable=0 failed=0 192.168.184.143 : ok=5 changed=2 unreachable=0 failed=0
下面定義dbsrvs角色
# yum install mariadb-server //首先先在管控主機上安裝mysql,因為要用到配置文件my.cnf
# cd ansible_playbooks/roles/dbsrvs/ //看清楚路徑,這里編輯是dbsrvs角色
# cp /etc/my.cnf files/ //放在files目錄下,使用相對路徑直接調用就可以了
# vim tasks/main.yml //定義dbsrvs角色的任務
- name: install mariadb-server package yum: name=mariadb-server state=latest - name: install configuration file copy: src=my.cnf dest=/etc/my.cnf //src直接引用dbsrvs/files目錄下的文件 tags: - myconf notify: - restart mariadb - name: start mariadb service service: name=mariadb enabled=true state=started
# vim handlers/main.yml //定義處理器
- name: restart mariadb
service: name=mariadb state=restarted
# vim site.yml //分開指明角色
- hosts: 192.168.184.142 remote_user: root roles: - websrvs - hosts: 192.168.184.143 remote_user: root roles: - dbsrvs - hosts: 192.168.184.145 remote_user: root roles: - websrvs - dbsrvs
roles注意事項:
1、目錄名同角色名
2、目錄結構有固定格式;
files:靜態文件
templates:Jinjia2模板文件
tasks:至少有一個main.yml文件,定義各handlers
vars:至少有一個main.yml文件,定義變量
meta:定義依賴關系等信息
3、site.yml中定義playbook,額外也可以有其他的yml文件;