相信有那麼一天,我們將可以像畢凱艦長一樣用嘴巴叫所有主機做事!


Cheng Wei Chen



Ansible 小技巧,利用 Variables 快速切換 playbook 套用之主機

Ansible 的 playbook 只需要 hoststasks 這兩個最基本的參數即可運作。一個最基本的 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 嗎?

這裡提供兩個理由給大家參考:

  1. hosts 使用 Variables 可以強迫你仔細思考要執行的主機

    hosts 被換成 Variables 之後,如果你沒有輸入 Variables,那麼 playbook 將無法順利執行,它會出現 ERROR! 'myVM' is undefined 的錯誤訊息。

    這意味著你一定要輸入 -e 把 Variables 填入,這逼著你一定要思考過到底目標主機是那一台,強迫你在下指令前要思考清楚。

  2. Variables 還可以做出更複雜的組合

    Ansible 的 hosts 原本就已支援進階的用法。
    例如:
    web*
    web:db
    web:&db
    web:!db

    若再配上 Variables 就能再組合出更複雜的用法。
    web:!{{ myVM }}

以上兩個理由提供給大家參考,如果有更好的意見,也歡迎提供給我參考與學習,畢竟每個人的用法不同,教學相長,彼此學習嘍。

Ansible 官網文件:

沒有留言:

張貼留言

不歡迎留言打廣告,所以有進行留言管理,敬請見諒。