實驗平臺:centos/redhat平臺。node
ansbile-playbook是一系統ansible命令的集合,其利用yaml 語言編寫,運行過程,ansbile-playbook命令根據自上而下的順序依次執行。同時,playbook開創了不少特性,它能夠容許你傳輸某個命令的狀態到後面的指令,如你能夠從一臺機器的文件中抓取內容並附爲變量,而後在另外一臺機器中使用,這使得你能夠實現一些複雜的部署機制,這是ansible命令沒法實現的。linux
playbook經過ansible-playbook命令使用,它的參數和ansible命令相似,如參數-k(–ask-pass) 和 -K (–ask-sudo) 來詢問ssh密碼和sudo密碼,-u指定用戶,這些指令也能夠經過規定的單元寫在playbook 。ansible-playbook的簡單使用方法: ansible-playbook example-play.yml 。web
下面給出一個簡單的ansible-playbook示例,瞭解下其構成。shell
# cat user.yml - name: create user hosts: all user: root gather_facts: false vars: - user: "test" tasks: - name: create user user: name="{{ user }}"
上面的playbook 實現的功能是新增一個用戶:apache
name參數對該playbook實現的功能作一個概述,後面執行過程當中,會打印 name變量的值 ;ubuntu
hosts參數指定了對哪些主機進行參做;centos
user參數指定了使用什麼用戶登陸遠程主機操做;安全
gather_facts參數指定了在如下任務部分執行前,是否先執行setup模塊獲取主機相關信息,這在後面的task會使用到setup獲取的信息時用到;bash
vars參數,指定了變量,這裏指字一個user變量,其值爲test ,須要注意的是,變量值必定要用引號引住;併發
task指定了一個任務,其下面的name參數一樣是對任務的描述,在執行過程當中會打印出來。user提定了調用user模塊,name是user模塊裏的一個參數,而增長的用戶名字調用了上面user變量的值。具體執行結果以下:
[root@361way playbooks]# ansible-playbook user.yml PLAY [create user] ************************************************************ TASK: [create user ] ********************************************** changed: [10.212.52.252] changed: [10.212.52.14] changed: [10.212.52.16] PLAY RECAP ******************************************************************** 10.212.52.14 : ok=1 changed=1 unreachable=0 failed=0 10.212.52.16 : ok=1 changed=1 unreachable=0 failed=0 10.212.52.252 : ok=1 changed=1 unreachable=0 failed=0
一樣,若是想實現把這個新增的用戶刪除,只需將該playbook文件的最後一行替換爲以下行再執行相應的playbook便可:
user: name="{{ user }}" state=absent remove=yes
再給出一個稍微複雜的示例,經過ansible-playbook實現對N臺主機同時修補bash shellcode 漏洞。須要注意的是,可能現網主機分佈着不一樣的系統版本。這裏假設現網同時存在centos5和6版本,具體playbook內容以下:
# cat update_bash.yml - hosts: all remote_user: root gather_facts: True tasks: - name: update bash in redhat 6 version yum: name=http://mirrors.aliyun.com/centos/6.6/os/x86_64/Packages/bash-4.1.2-29.el6.x86_64.rpm.rpm state=present when: ansible_os_family == "RedHat" and ansible_distribution_version|int >=6 - name: update bash in redhat 5 version yum: name=http://mirrors.hustunique.com/centos/5/updates/x86_64/RPMS/bash-3.2-33.el5.1.x86_64.rpm state=present when: ansible_os_family == "RedHat" and ansible_distribution_version|int <=5
上面使用了when語句,同時也開啓了gather_facts setup模塊,這裏的ansible_os_family變量和ansible_distribution_version變量就是直接使用的setup模塊獲取的信息。
若是有大量主機,就在運行的時候加上-f而後選擇一個合適的併發主機數量便可,我這裏使用了這個,很快的就升級完成bash了。
playbook是由一個或多個「play」組成的列表。play的主要功能在於將事先歸併爲一組的主機裝扮成事先經過ansible中的task定義好的角色。從根本上來說所謂task無非是調用ansible的一個module。將多個play組織在一個playbook中便可以讓它們聯同起來按事先編排的機制同唱一臺大戲。其主要有如下四部分構成
playbooks組成:
Target section: 定義將要執行 playbook 的遠程主機組
Variable section: 定義 playbook 運行時須要使用的變量
Task section: 定義將要在遠程主機上執行的任務列表
Handler section: 定義 task 執行完成之後須要調用的任務
而其對應的目錄層爲五個,以下:
通常所需的目錄層有:(視狀況可變化)
vars 變量層
tasks 任務層
handlers 觸發條件
files 文件
template 模板
下面介紹下構成playbook 的四層結構。
一、Hosts和Users
playbook中的每個play的目的都是爲了讓某個或某些主機以某個指定的用戶身份執行任務。
hosts 用於指定要執行指定任務的主機其能夠是一個或多個由冒號分隔主機組。
remote_user 則用於指定遠程主機上的執行任務的用戶。
不過remote_user也可用於各task中。也能夠經過指定其經過sudo的方式在遠程主機上執行任務其可用於play全局或某任務。
此外甚至能夠在sudo時使用sudo_user指定sudo時切換的用戶。
示例:
- hosts: webnodes tasks: - name: test ping connection: remote_user: test sudo: yes
二、任務列表和action
play的主體部分是task list。
task list中的各任務按次序逐個在hosts中指定的全部主機上執行即在全部主機上完成第一個任務後再開始第二個。在運行自下而下某playbook時若是中途發生錯誤全部已執行任務都將回滾所以在更正playbook後從新執行一次便可。
task的目的是使用指定的參數執行模塊而在模塊參數中可使用變量。模塊執行是冪等的這意味着屢次執行是安全的由於其結果均一致。每一個task都應該有其name用於playbook的執行結果輸出建議其內容儘量清晰地描述任務執行步驟。若是未提供name則action的結果將用於輸出。
定義task的可使用「action: module options」或「module: options」的格式推薦使用後者以實現向後兼容。若是action一行的內容過多也中使用在行首使用幾個空白字符進行換行。
tasks: - name: make sure apache is running service: name=httpd state=running 在衆多模塊中只有command和shell模塊僅須要給定一個列表而無需使用「key=value」格式例如 tasks: - name: disable selinux command: /sbin/setenforce 0 若是命令或腳本的退出碼不爲零可使用以下方式替代 tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand || /bin/true 或者使用ignore_errors來忽略錯誤信息 tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand ignore_errors: True
三、handlers
用於當關注的資源發生變化時採起必定的操做。
「notify」這個action可用於在每一個play的最後被觸發這樣能夠避免屢次有改變發生時每次都執行指定的操做取而代之僅在全部的變化發生完成後一次性地執行指定操做。
在notify中列出的操做稱爲handler也即notify中調用 handler中定義的操做。
注意:在 notify 中定義內容必定要和tasks中定義的 - name 內容同樣,這樣才能達到觸發的效果,不然會不生效。
- name: template configuration file template: src=template.j2 dest=/etc/foo.conf notify: - restart memcached - restart apache handler是task列表這些task與前述的task並無本質上的不一樣。 handlers: - name: restart memcached service: name=memcached state=restarted - name: restart apache service: name=apache state=restarted
四、tags
tags用於讓用戶選擇運行或略過playbook中的部分代碼。ansible具備冪等性所以會自動跳過沒有變化的部分即使如此有些代碼爲測試其確實沒有發生變化的時間依然會很是地長。
此時若是確信其沒有變化就能夠經過tags跳過此些代碼片段。
五、示例
下面再給出一個安裝httpd web服務的示例:
# cat /etc/ansible/playbook/install_web.yml - hosts: webservers remote_user: root gather_fasks: False vars: packages: httpd tasks: - name: Install httpd yum: name={{ packages }} state=present - name: Cofiguration httpd copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf tags: httpd_conf notify: - restart httpd - name: Start httpd service: name=httpd state=started enabled=no tags: start - name:Add centos user user: name={{ item }} state=absent tags: adduser with_items: - centos - admin handlers: - name: restart httpd service: name=httpd state=restart
注:上面的代碼沒有考慮ubuntu平臺,僅僅考慮centos/redhat平臺。