ansible筆記(10):初識ansible playbook

ansible筆記(10):初識ansible playbook

假設,咱們想要在test70主機上安裝nginx並啓動,咱們能夠在ansible主機中執行以下3條命令


ansible test70 -m yum_repository -a 'name=aliEpel description="alibaba EPEL" baseurl=http://mirrors.aliyun.com/epel/7/$basearch'
ansible test70 -m yum -a 'name=nginx disable_gpg_check=yes enablerepo=aliEpel'
ansible test70 -m service -a "name=nginx state=started"


咱們經過上述3條命令,先肯定配置了對應的yum源,而後使用yum模塊安裝了nginx,最後使用service模塊啓動了nginx,最終達到了咱們的目的。

可是在實際的工做環境中,咱們可能須要常常在新主機上安裝nginx,難道每次有新的服務器加入工做環境,咱們都要修改上述3條命令中的主機名而且從新將每一條命令執行一遍嗎?這樣彷佛有些麻煩,確定有更好的辦法,沒錯,咱們能夠將上述命令寫成腳本,每次修改一些變量,而後執行腳本就好了,這樣彷佛方便了很多,而ansible天生就提供了這種相似"腳本"的功能,在ansible中,相似"腳本"的文件被稱做"劇本"'劇本'的英文名稱爲'playbook',咱們只須要將要作的事情編寫成playbook,把不一樣的模塊按照順序編排在劇本中,ansible就會按照劇本一步一步的執行,最終達到咱們的目的,雖然playbook的功能與腳本相似,可是劇本並非簡單的將ad-hoc命令按照順序堆砌在一個可執行文件中,編寫劇本須要遵循YAML語法,若是你沒有接觸過YAML語法,不用懼怕,堅持看完後面的示例,熟悉一些固定套路之後,你也能夠本身編寫playbook。


那麼怎樣編寫playbook呢?咱們先從一個簡單的示例開始

首先,咱們須要建立一個YAML格式的playbook文件。

playbook文件以".yaml"或者".yml"做爲文件名後綴,此處咱們建立一個名爲"test.yml"的劇本文件。

在編寫劇本以前,咱們先來回顧兩個簡單的ad-hoc命令,好比以下兩條命令:

[root@node1 data]# ansible test211 -m ping
[root@node1 data]# ansible test211 -m file -a "path=/data/test211 state=directory"

上述命令表示使用ping模塊去ping主機test70,而後再用file模塊在test70主機上建立目錄,那麼,若是把上述命令轉換成playbook的表現形式,該如何書寫呢?示例以下

(此處先進行示例,後文會說明怎樣執行playbook)

---
- hosts: test211
  remote_user: root
  tasks:
  - name: ping the host
    ping:
  - name: make directory test
    file:
      path: /data/testfile
      state: directory

如上所示,第一行使用三個橫槓做爲開始,在YAML語法中,"---"表示文檔開始。

第二行使用"- "做爲開頭(注意:橫槓後面有空格),若是你瞭解過YAML語法,那麼你必定知道YAML使用"- "表示一個塊序列的節點,若是你不瞭解YAML語法,不用在此處糾結,先這麼寫,寫的多了,天然會理解,從上例能夠看出,"- "後面使用hosts關鍵字指定了要操做的主機,hosts關鍵字對應的值爲test70,表示咱們要在test70主機上進行操做,"hosts: test70"是一個鍵值對,注意,在YAML語法中使用冒號映射鍵值對時,'冒號'後面必須有'空格',這也是語法,沒有爲何,記住就好,若是你想要一次性在多臺主機上進行操做,能夠同時寫多個主機,每臺主機使用逗號隔開,好比'hosts: test70,test61',若是你在清單中對主機進行了分組,也可使用組名。

第三行,使用remote_user關鍵字能夠指定在進行遠程操做時使用哪一個用戶進行操做,'remote_user: root'表示test70的root用戶進行操做,上圖中,remote_user關鍵字與hosts關鍵字對齊,表示它們是平級的,以前的文章中提到過,在YAML語法中進行縮進時,不能使用tab鍵進行縮進,必須使用空格,因此,爲了兼容使用tab鍵進行縮進的使用習慣,能夠將vim編輯器設置爲自動將tab轉成空格。

第四行,使用tasks關鍵字指明要進行操做的任務列表,以後的行都屬於tasks鍵值對中的值。

以後的行都屬於tasks任務列表中的任務,能夠看出,整個任務列表一共有兩個任務組成,每一個任務都以"- "開頭,每一個任務都有本身的名字,任務名使用name關鍵字進行指定,第一個任務使用ping模塊,使用ping模塊時沒有指定任何參數。第二個任務使用file模塊,使用file模塊時,指定了path參數與state參數的值。

好了,test.yml已經編寫完成了,可是,咱們尚未運行這個劇本,運行劇本須要使用'ansible-playbook'命令,示例以下

[root@node1 data]# ansible-playbook test.yml 

PLAY [test211] **********************************************************************************************************************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [test211]

TASK [ping the host] ****************************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [test211]

TASK [make directory test] **********************************************************************************************************************************************************************************************************************************************************************************************************************************************
changed: [test211]

PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
test211                    : ok=3    changed=1    unreachable=0    failed=0


如上圖所示,playbook執行後返回了一些信息,這些信息是此次劇本運行的概況。

'PLAY [test211]'表示此次運行的playbook中有一個'play'是針對test211這臺主機運行的,一個'playbook'是由一個或多個'play'組成的,這樣說可能不太容易理解,那麼咱們打個比方,一個'劇本'是由一個或多個'橋段'組成的,每一個橋段都有不一樣的場景、人物、故事,全部的橋段組合在一塊兒,組成一個完整的劇本,劇本就是playbook,橋段就是play,而上例中,整個劇本中只有一個橋段,也就是說,上例的playbook中,咱們只寫了一個play,在下文中咱們會舉例說明怎樣書寫多個play,到時候你會更加明白到底什麼是所謂的'play',固然,'橋段'只是我本身爲了方便理解給'play'起的中文名,官方名稱只叫"play"。

從上述信息能夠看出,僅有的這個play是針對test211運行的,這個play一共包含三個任務,第一個任務的名字叫作'Gathering Facts',第二個任務的名字叫作'Ping the host',第三個任務的名字叫作'make directory test',看到此處你會發現,咱們在playbook中明明只寫了兩個任務,爲何最後執行時卻有三個任務呢?這是由於,每一個play在執行時,都會先執行一個默認任務,這個默認任務就是'Gathering Facts''Gathering Facts'任務會收集當前play對應的目標主機的相關信息,收集完這些基礎信息後,纔會執行咱們指定的任務,因爲上例中,hosts的值只有test211一個主機,因此這個play只針對test211運行,因此'Gathering Facts'這個任務只收集了test211的相關信息,執行完默認任務後,開始執行'Ping the host'任務和'make directory test'任務,因爲在執行playbook以前,/testdir/test目錄已經存在於test211主機中,因此'make directory test'任務返回的信息是綠色的,若是對應的目錄並不存在,'make directory test'任務返回的信息應該是黃色的,這是由於冪等性的緣故,前文已經解釋過,此處再也不贅述。

當playbook中的全部play執行完畢後,在返回信息的'PLAY RECAP'中能夠對全部目標主機的執行狀況進行'回顧',因爲咱們的目標主機只有test211一臺,因此只看到了test211的執行歸納信息。


咱們已經執行了一個playbook,這個playbook中只有一個play,咱們也能夠在這個playbook中多寫幾個play,示例以下:

---
- hosts: test211
  remote_user: root
  tasks:
  - name: pint the host
    ping:
  - name: make directory test211
    file:
      path: /data/test211
      state: directory

- hosts: test212,test215
  remote_user: root
  tasks:
    - name: touch file
      file:
        path: /touchfile
        state: touch

- hosts:
    test212
    test215
  remote_user: root
  tasks:
    - name: create user jack
      user: 
        name: jack

如上所示,上例中有多個play,第一個play針對test211執行,這個play會執行兩個任務。

第二個play針對test212和test215執行,第二個play只包含一個任務,即在對應的目標主機上建立/touchfile文件

第三個play針對test212和test215執行,細心如你必定發現了,當你須要在play中指定多個主機時,有兩種語法可使用,第二個play和第三個play中的語法均可以指定多個主機,第三個play也只包含一個任務,即在test212和test215主機上建立jack用戶。


多個play寫完之後,咱們來運行一下劇本試試

以下所示,每一個play執行時都會顯示當前play對應的目標主機,而且每一個play執行時都會先執行默認的facts任務,收集對應目標主機的信息,當全部play都執行完畢後,會出現'PLAY RECP',至關於一個小的報告信息,看到這裏,你應該已經理解了到底什麼是所謂的'play'了吧。


[root@node1 data]# ansible-playbook test2.yml 

PLAY [test211] ****************************************************************

TASK [Gathering Facts] ********************************************************
ok: [test211]

TASK [pint the host] **********************************************************
ok: [test211]

TASK [make directory test211] *************************************************
ok: [test211]

PLAY [test212,test215] ********************************************************

TASK [Gathering Facts] ********************************************************
ok: [test215]
ok: [test212]

TASK [touch file] *************************************************************
changed: [test212]
changed: [test215]

PLAY [test212 test215] ********************************************************

TASK [Gathering Facts] ********************************************************
ok: [test215]
ok: [test212]

TASK [create user jack] *******************************************************
changed: [test215]
changed: [test212]

PLAY RECAP ********************************************************************
test211                    : ok=3    changed=0    unreachable=0    failed=0   
test212                    : ok=4    changed=2    unreachable=0    failed=0   
test215                    : ok=4    changed=2    unreachable=0    failed=0   

若是你並非很熟悉YAML語法,你能夠不用過於深究YAML語法,只須要死記硬背,記住某些"固定套路"便可編寫playbook,寫的多了,天然會對這些語法有所理解

若是你的playbook寫完了,可是你不能肯定playbook文件中是否存在語法錯誤,那麼你可使用以下命令對playbook進行語法檢查

[root@node1 data]# ansible-playbook --syntax-check /data/test2.yml

執行上述命令後,若是隻返回了playbook的名稱,就表示沒有語法錯誤。

除了對playbook進行語法測試,咱們還可以'模擬執行'playbook,'模擬執行'並非真正的執行,只是'僞裝'執行一下,playbook中的任務並不會真正在目標主機中運行,因此你能夠放心大膽的進行模擬,使用以下命令便可模擬運行playbook,模擬運行功能能夠幫助咱們'預估'playbook是否可以正常執行。

[root@node1 data]# ansible-playbook --check test2.yml 

注意:使用上述命令進行'模擬'時,一些任務可能會報錯,這多是由於報錯的任務在執行時須要依賴以前的其餘任務的完成結果,可是由於是'模擬'執行,因此以前的任務並不會真正的執行,既然以前的任務沒有真正的執行,天然不會產生對應的結果,因此後面的任務就報錯了,也就是說,咱們並不能徹底以'模擬'的反饋結果做爲playbook是否可以正常運行的判斷依據,只能經過'模擬'大概的'預估'一下而已。
相關文章
相關標籤/搜索