如何Ansible編寫一個Playbook

  • 2019 年 11 月 12 日
  • 筆記

1、playbooks介紹

playbooks是 一個不同於使用Ansible命令行執行方式的模式,其功能更強大靈活。簡單來說,playbook是一個非常簡單的配置管理和多主機部署系統,不同於任何已經存在的模式,可作為一個適合部署複雜應用程序的基礎。Playbook可以定製配置,可以按照指定的操作步驟有序執行,支持同步和異步方式。值得注意的是playbook是通過YAML格式來進行描述定義的。

2、playbook基礎組件

1.Hosts:運行執行任務(task)的目標主機

2.remote_user:在遠程主機上執行任務的用戶

3.tasks:任務列表

4.handlers:任務,與tasks不同的是只有在接受到通知時才會被觸發

5.templates:使用模板語言的文本文件

6.variables:變量,變量替換

3、playbook和臨時命令的比較

1.臨時命令不適合複雜配置管理或編配場景。

2.臨時命令一次只能調用一個模塊或一組參數。當需要多個操作時,必須使用多個臨時命令來執行。

3.playbook是描述要在受管理主機上實施的必要配置或程序性步驟的文件。playbook為配置管理和部署提供了強大而靈活的解決方案。playbook可以將冗長而複雜的管理任務變為可輕鬆重複的歷程,並且預測成果。

4、命令到playbook的演化

為了便於理解playbook,我們使用user模塊在指定節點docker-03上創建一個用戶名為newbie,uid為4000的用戶。

 [root@docker-01 ~]# ansible -m user -a "name=newbie uid=4000 state=present" docker-03   docker-03 | CHANGED => {      "ansible_facts": {          "discovered_interpreter_python": "/usr/bin/python"     },      "changed": true,      "comment": "",      "create_home": true,      "group": 4000,      "home": "/home/newbie",      "name": "newbie",      "shell": "/bin/bash",      "state": "present",      "system": false,      "uid": 4000   }

如果寫成playbook

 [root@docker-01 ~]# cat user.yml   ---   -name: Configure important user consistently   hosts: docker-03   tasks:      -name: newbie exists with UID 4000       user:         name: newbie         uid: 4000         state: present     [root@docker-01 ~]# ansible-playbook user.yml     PLAY [Configure important user consistently] ***********************************     TASK [Gathering Facts] *********************************************************   ok: [docker-03]     TASK [newbie exists with UID 4000] *********************************************   changed: [docker-03]     PLAY RECAP *********************************************************************   docker-03                 : ok=2   changed=1   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0 

paly的第一行以破折號和空格(指示play是列表的第一項)開始,然後是第一個key:name

name key描述paly的目的。name key是可選的,但推薦使用。

 -name: Configure important user consistently

play中的第二個key是hosts屬性,指定運行play任務的主機。

 hosts: docker-03

play中最後一個key是tasks屬性,為這個play運行的任務列表。

 tasks:      -name: newbie exists with UID 4000       user:         name: newbie         uid: 4000         state: present

playbook是YAML格式的文本文件,擴展名通常為yml。

playbook使用帶空格字符的縮進來表示數據結構。YAML對縮進使用了多少空格沒有嚴格的要求,但是有兩個基本規則:

1、層次機構中相同級別的數據元素(例如相同列表中的項)必須具有相同的縮進。

2、子項必須比其父項縮進的更多。

可以添加空行增加可讀性。

5、Tab鍵的使用

yml文件只能使用空格縮進,不能使用Tab,如果vim編輯器,可以通過編輯$HOME/.vimrc將Tab轉化為2個空格。文件如果不存在,則自己創建。

 [root@docker-03 ~]# vim ~/.vimrc   autocmd FileType yaml setlocal ai ts=2sw=2et

6、playbook的格式

playbook以三個破折號(—)作為文檔開始標記。以三個點(…)作為文檔結尾標記,儘管在實踐中經常被省略。

在這些標記之間,playbook由一組paly構成。YAML列表中的item以一個破折號開始,後跟空格。例如:

 -name: Configure important user consistently   -apple: This is an apple   -orange: This is an orange

paly本身是key-value對的集合。同一個paly中keys應該有相同的縮進。下面的示例顯示了一個帶有三個keys的YAML代碼片段。前兩個keys的值很簡單。第三個key的列表中有三個items作為值。

 name: Configure important user consistently   hosts: docker-03   tasks:      -first      -second      -third

tasks屬性列出要在主機上運行的任務,列表中的每個任務本身都是鍵值對的集合。

以下是另一個多tasks的演示

 tasks:      -name: web server is enabled        service:         name: httpd         enabled: true        -name: NTP server is enabled        service:         name: chronyd         enabled: true        -name: Postfix is enabled        service:         name: postfix         enables: true

7、執行一個簡單的playbook

 [root@docker-02 ~]# cat webserver.yml   ---   -name: play to setup web server   hosts: docker-03   tasks:    -name: latest httpd version installed     yum:       name: httpd       state: latest     [root@docker-02 ~]# ansible-playbook webserver.yml     PLAY [play to setup web server] ************************************************     TASK [Gathering Facts] *********************************************************   ok: [docker-03]     TASK [latest httpd version installed] ******************************************   changed: [docker-03]     PLAY RECAP *********************************************************************   docker-03                 : ok=2   changed=1   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0  

上面的輸出說明了為何有必要在playbook中將name屬性用於play和任務,即便此屬性是可選的。playbook執行時顯示name屬性的值。對於具有多個play和tasks的palybook,使用name屬性會給監控playbook的執行提供非常大的幫助。

一般來說,Ansible playbook中的任務是冪等(idempotent)的,可以安全的多次執行playbook。如果目標託管機已經處於正確的狀態,則不應進行任何修改。例如,假設前一個例子的劇本再次執行。

 [root@docker-02 ~]# ansible-playbook webserver.yml     PLAY [play to setup web server] ************************************************     TASK [Gathering Facts] *********************************************************   ok: [docker-03]     TASK [latest httpd version installed] ******************************************   ok: [docker-03]     PLAY RECAP *********************************************************************   docker-03                 : ok=2   changed=0   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0 

所有任務狀態ok,且沒有發生任何change

8、語法驗證

在執行playbook前,最好進行驗證,確保其內容的語法正確無誤。ansible-playbook命令提供–syntax-check選項,可用於驗證playbook文件的語法。下例演示了一個playbook成功通過語法驗證。

 [root@docker-02 ~]# ansible-playbook --syntax-check webserver.yml   playbook: webserver.yml

語言驗證失敗時,將報語法錯誤。輸出中包含語法問題在playbook中的大致位置。下例演示了一個playbook語法驗證失敗,其中play的name屬性後缺少了空格分隔符。

 [root@docker-02 ~]# ansible-playbook --syntax-check webserver.yml   ERROR! Syntax Error whileloading YAML.   mapping values are not allowed inthis context     The error appears to be in'/root/webserver.yml': line 3, column 8, but may   be elsewhere inthe file depending on the exact syntax problem.     The offending line appears to be:     -name: play to setup web server   hosts: docker-03         ^ here

9、執行空運算

另一個有用的選項-C選項。這會使Ansible報告在執行該playbook時將會發生什麼更改,但不會對受管主機進行任何實際的更改。

下面演示了一個playbook的空運行,它在受管主機上安裝了最新版本的httpd軟件包。

 [root@docker-02 ~]# ansible-playbook -C webserver.yml     PLAY [play to setup web server] ************************************************     TASK [Gathering Facts] *********************************************************   ok: [docker-03]     TASK [latest httpd version installed] ******************************************   changed: [docker-03]     PLAY RECAP *********************************************************************   docker-03                 : ok=2   changed=1   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0  

10、實戰2個plays,針對兩台主機分別操作

 [root@docker-03 ~]# vim /etc/ansible/hosts   [test1]   172.17.120.50   [test2]   172.17.120.51     [root@docker-03 ~]# vim test.yml   ---   #This is a simple playbook with two plays   -name: first play   hosts: 172.17.120.50   tasks:      -name: first task     yum:       name: httpd       state: present      -name: second task      service:       name: httpd       enabled: true     -name: second play   hosts: 172.17.120.51   tasks:      -name: first task      service:       name: mariadb       enabled: true     [root@docker-03 ~]# ansible-playbook test.yml   PLAY [first play] ******************************************************************************************************************************************************************************************     TASK [Gathering Facts] *************************************************************************************************************************************************************************************   ok: [172.17.120.50]     TASK [first task] ******************************************************************************************************************************************************************************************   ok: [172.17.120.50]     TASK [second task] *****************************************************************************************************************************************************************************************   changed: [172.17.120.50]     PLAY [second play] *****************************************************************************************************************************************************************************************     TASK [Gathering Facts] *************************************************************************************************************************************************************************************   ok: [172.17.120.51]     TASK [first task] ******************************************************************************************************************************************************************************************   changed: [172.17.120.51]     PLAY RECAP *************************************************************************************************************************************************************************************************   172.17.120.50             : ok=3   changed=1   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0   172.17.120.51             : ok=2   changed=1   unreachable=0   failed=0   skipped=0   rescued=0   ignored=0