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 官網文件: