Ansible Role 介紹

很多時候其實我們會希望有部分的部署內容是可以被其他不同的 playbook 重新使用,但卻不希望在每一個不同的 playbook 中都要重新定義一次做法,為了解決上述的問題,Ansible 提供了角色 (role) 的概念。可以透過撰寫屬於自己的 role 來讓所有 playbook 重複使用,藉此提升透過 Ansible 自動化的靈活度。

Role 撰寫

由於安裝 cURL 的這個工作很可能會在未來頻繁地被不同的 playbook 重複使用,因此,把安裝 cURL 的方法寫成一個可以重複被利用的 role ,而非 playbook 中的一個 task。在 Ansible 中,所有的 role 都是獨立的,若今天有其中一個服務需要被更新,我們不用遍查所有 playbook 去更新跟該服務有關的片段,我們只需要找到負責部署該服務的 role 並做調整,所有其他呼叫過這個 role 的 playbook 等於都自動同時更新了。在工作資料夾下依照以下結構新增檔案 (新增roles/curl/main.yml):

workspace
├── Vagrantfile
├── inventory
├── playbook.yml
└── roles
    └── curl
        └── tasks
            └── main.yml
  • main.yml
---
  - name: install curl
    yum:
      name: curl
  • 接著修改playbook.yml 增加:
---
- hosts: ironman
  roles:
    - { role: curl, become: yes }
  • 設定Ansible 的配置檔案 – ansible.cfg 來設置 role 路徑 (path)
[all]
roles_path = ./roles

不同作業系統的寫法

workspace
├── Vagrantfile
├── ansible.cfg
├── inventory
├── playbook.yml
└── roles
    ├── curl
    │   └── tasks
    │       └── main.yml
    ├── git
    │   └── tasks
    │       └── main.yml
    └── jenkins
        ├── meta
        │   └── main.yml
        └── tasks
            └── main.yml
  • roles/git/tasks/main.yml
---
  - name: install git
    yum:
      name: git-all
    when: ansible_distribution == 'CentOS'

  - name: install git
    apt:
      name: git
    when: ansible_distribution == 'Ubuntu' or ansible_distribution == 'Debian'

Ansible Role 的依賴關係

現在讓我們重新思考另外一個問題,除了逐一呼叫 role 之外,我們有沒有其他更優雅的方式來定義自動化部署的步驟呢?舉例來說,如果我們希望在每一次安裝 Jenkins 的伺服器上,都同時安裝 cURL 這個工具,有沒有其他更簡單明瞭的方式呢?
答案是有的,在 Ansible 的世界中,我們可以透過定義 role 與 role 之間的依賴關係 (role dependencies) 來提升每一個 role 的可讀性。就以上面的例子而言,我們希望所有部署 Jenkins 的伺服器都預先搭載好 cURL 這個工具,若用 Ansible 的角度思考,這就意味著我們希望 jenkins 這個 role 依賴於 curl 這個 role。我們可以在每一個 role 的資料夾中透過 meta 這個子目錄定義這樣的依賴關係,具體步驟如下:

workspace
├── Vagrantfile
├── ansible.cfg
├── inventory
├── playbook.yml
└── roles
    ├── curl
    │   └── tasks
    │       └── main.yml
    └── jenkins
        ├── meta
        │   └── main.yml
        └── tasks
            └── main.yml
  • roles/jenkins/meta/main.yml 中輸入以下內容:
---
  dependencies:
    - { role: curl, become: yes }

設定好關係之後,就可以回到 playbook.yml 中刪除原本呼叫 curl role 的部分,只留下 jenkins就好,系統就會自動安裝CRUL。開發人員過去往往因為繁瑣的安裝流程難免疏忽其中幾個前置服務安裝,進而導致後面部署流程發生的錯誤,透過這樣的設計流程,將可以徹底被解決。+