延續上一篇文章,針對公開放上 Ansible Galaxy 的 Roles,我們能夠完全比照 geerlingguy 大神的測試方式,直接使用 Travis Ci。但如果是一些不打算公開的 Roles,那就只好使用自己的 CI Server 來測試,在這篇文章中就讓我們用 GitLab CI 來進行測試。


在文章開始之前要先打預防針,其實轉換並不難,特別是如果你早已看懂 geerlingguy 的測試方法,那還請忽略本文,因為對於高手而言這篇文章很可能只是在說廢話啦 XD。

GitLab CI 的詳細使用方式就不多說了,請參閱官方文件。GitLab 依然有提供免費註冊,並且也有提供有限免費的 CI Runner 可以使用,因此想要試用又不想自行架設者,可以先註冊免費帳號來試用。

使用 GitLab CI 的方式與 Travis CI 類似,同樣都是在專案內新增一個 yaml 檔案,並在其中定義 CI Pipeline 與 CI Job,而 GitLab CI 預設使用的檔名為 .gitlab-ci.yml。因此其實我們只要仿造在前一篇文章中說明過的 geerlingguy 大神之測試方法,在 .gitlab-ci.yml 中,將其轉換成 GitLab CI 可以接受的方式即可。

預備多種測試環境

與 Travis CI 相同,GitLab CI 也支援使用 docker 來建立不同的測試環境,因此在 .gitlab-ci.yml 中,需要特別註明要使用支援 Docker 的 Runner,並且替每個 CI Job 指定所使用的 Docker Image。

當然我們要使用的是 geerlingguy 所製作的那些 Docker Images,並且根據我們想要測試的 os distribution 新增數個 CI Job。

ubuntu1404:
stage: testing
tags:
- "docker"
image: geerlingguy/docker-ubuntu1404-ansible
script:
.... 中略 ....

ubuntu1604:
stage: testing
tags:
- "docker"
image: geerlingguy/docker-ubuntu1604-ansible
script:
.... 中略 ....

仿造 geerlingguy 大神的測試方法

接著就是重點,要在 script 中仿造 geerlingguy 的測試方法。

首先我們要將撰寫好的 Role 移至指定的路徑之下。

script:
- cp -R /builds/your_group_or_namespace/your_project_name /etc/ansible/roles/role_under_test/

這裡要稍微解釋一下,GitLab CI 的 Runner 預設會自動將 Project clone 至 /builds/your_group_or_namespace/your_project_name 這個路徑,因此上面的範例請根據你實際使用 GitLab 所建立的 Group 或 Namespace,以及 Project 名稱而修改。類似下面的範例:

script:
- cp -R /builds/chengwei/ansible-role-myrole /etc/ansible/roles/role_under_test/

接著就簡單了,首先先跑一次 --syntax-check

- ansible-playbook /etc/ansible/roles/role_under_test/tests/test.yml --syntax-check

接著跑兩次 Playbook。

- ansible-playbook /etc/ansible/roles/role_under_test/tests/test.yml
- ansible-playbook /etc/ansible/roles/role_under_test/tests/test.yml

不過與 Travis CI 不太一樣的地方是,如果你想在再補一個自己的驗證方法,來驗證 Role 真的有確實執行成果,要記得目前執行的環境仍在相同的 docker container 內,因此指令要改成 local 執行才行。例如我要檢查是否真的有安裝 nginx。

- ls /usr/sbin/nginx | grep "/usr/sbin/nginx"'

最後,提供一個完整的 .gitlab-ci.yml 範例。

---
## reference: https://github.com/geerlingguy/ansible-role-apache/blob/master/.travis.yml

stages:
- testing

ubuntu1404:
stage: testing
tags:
- "docker"
image: geerlingguy/docker-ubuntu1404-ansible
script:
- cp -R /builds/chengwei/ansible-role-myrole /etc/ansible/roles/role_under_test/
- export playbook=${playbook:-"test.yml"}
- export ANSIBLE_FORCE_COLOR=1
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook --syntax-check
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook

ubuntu1604:
stage: testing
tags:
- "docker"
image: geerlingguy/docker-ubuntu1604-ansible
script:
- cp -R /builds/chengwei/ansible-role-myrole /etc/ansible/roles/role_under_test/
- export playbook=${playbook:-"test.yml"}
- export ANSIBLE_FORCE_COLOR=1
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook --syntax-check
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook

centos6:
stage: testing
tags:
- "theqwan-docker"
image: geerlingguy/docker-centos6-ansible
script:
- cp -R /builds/chengwei/ansible-role-myrole /etc/ansible/roles/role_under_test/
- export playbook=${playbook:-"test-centos.yml"}
- export ANSIBLE_FORCE_COLOR=1
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook --syntax-check
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook

centos7:
stage: testing
tags:
- "docker"
image: geerlingguy/docker-centos7-ansible
script:
- cp -R /builds/chengwei/ansible-role-myrole /etc/ansible/roles/role_under_test/
- export playbook=${playbook:-"test-centos.yml"}
- export ANSIBLE_FORCE_COLOR=1
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook --syntax-check
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook --tags=centos7
- ansible-playbook /etc/ansible/roles/role_under_test/tests/$playbook --tags=centos7

測試的結果在 GitLab CI 的 Pipeline 介面應該看起來會類似下圖,成功或失敗一樣是一目了然。

補充:如果你的 Runner 是自己架設的,也許你也可以考慮用 docker in docker 的方式來改寫這個 Roles 測試方式。

小結

相信大家早已讀懂 geerlingguy 大神是如何測試 Ansible Roles 的,同理相信本文對各位高手來說應該確實是一篇廢文 XD,正所謂教學相長,如果各位高手針對 Ansible Roles 的測試有任何更好的做法,還請務必與我分享交流一下,謝謝大家。