Ansible 的 playbook 只需要 hosts 與 tasks 這兩個最基本的參數即可運作。一個最基本的 playbook 的結構會長成下面的模樣。
---
- hosts: myVM
tasks:
- apt: name=curl state=latest update_cache=yes
tasks 設定了這個 playbook 要執行的動作,上面的範例很簡單,它只有一個動作就是透過 apt-get 安裝 curl。
而 hosts 則會與 Inventory file 搭配,Ansible 在執行 playbook 時,會從 Inventory file 中找到吻合 “myVM” 的主機,對它執行 tasks 中的動作。
一般來說當主機越來越多時,就必須用到一些進階 Inventory file 技巧來達到複雜的彈性運用,像是下面的舉例:
設定多個不同的 Inventory file 在執行 playbook 時,直接指定不同的 Inventory file。 例如:公司的主機群放在 Inventory file A,私人的主機群放在 Inventory file B。
設定多個不同的 Groups 在一個 Inventory file 之內,利用 Groups 區分主機群。
下面的範例中 vm1、vm2 即是屬於 centos 這個 Group,同理 vm3、vm4 即是屬於 ubuntu 這個 Group。在執行 playbook 時,可以在
hosts中指定不同 Groups。
[centos]
vm1
vm2
[ubuntu]
vm3
vm4
透過 Groups of Groups 達到更複雜的組合 將多個 Group 再組合成另一個 Groups of Groups。
下面的範例中,只要在執行 playbook 時,
hosts指定 ubuntu1404,即可在 vm1 ~ vm4 每一台都運行,因為 web 與 db 這兩個 Group 都屬於 ubuntu 這個 Groups of Groups。
[ubuntu1404:children]
web
db
[web]
vm1
vm2
[db]
vm3
vm4
我目前除了利用上述的方法之外,個人偏好另一個小技巧,就是將 playbook 的 hosts 設為 Variables,方便我能快速切換 playbook 套用之主機。
我們直接延續上面的 Groups of Groups 當作 Inventory file 的範例,我的 playbook 則修改如下:
---
- hosts: "{{ myVM }}"
tasks:
- apt: name=curl state=latest update_cache=yes
於是當我執行 playbook 時,我可以透過 -e 改變 myVM 的值,以此來彈性的決定本次要套用的 hosts 爲何。
例如:
ansible-playbook playbook.yml -e myVM=ubuntu1404
如此所有主機都會被套用 playbook。
ansible-playbook playbook.yml -e myVM=web
如此只有 web 這個 Group 會被套用 playbook。
ansible-playbook playbook.yml -e myVM=vm4
如此只有 vm4 這台主機會被套用 playbook。
當然這個小技巧實用度也有限,因為這意味者你必須很熟悉你所管理的 Inventory file 之結構與內容,在你的主機數量不算太多的前提下,這技巧應該能提升一點使用 playbook 的彈性。
2016.02.26 更新:
前面介紹了在 playbook 中用 Variables 快速切換主機的小技巧,但其實這件事情你也可以透過 --limit 即可做出一樣的結果。
例如:
ansible-playbook playbook.yml --limit web
如此只有 web 這個 Group 會被套用 playbook。
那麼還有必要在 hosts 中使用 Variables 嗎?
這裡提供兩個理由給大家參考:
hosts使用 Variables 可以強迫你仔細思考要執行的主機
當 hosts 被換成 Variables 之後,如果你沒有輸入 Variables,那麼 playbook 將無法順利執行,它會出現 ERROR! 'myVM' is undefined 的錯誤訊息。
這意味著你一定要輸入 -e 把 Variables 填入,這逼著你一定要思考過到底目標主機是那一台,強迫你在下指令前要思考清楚。
- Variables 還可以做出更複雜的組合
Ansible 的 hosts 原本就已支援進階的用法。
例如:
web*
web:db
web:&db
web:!db
若再配上 Variables 就能再組合出更複雜的用法。 web:!{{ myVM }}
以上兩個理由提供給大家參考,如果有更好的意見,也歡迎提供給我參考與學習,畢竟每個人的用法不同,教學相長,彼此學習嘍。
Ansible 官網文件:
