Chengwei Chen
May 28, 2018 · 9 min read

延續上一篇文章,針對公開放上 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:
.... 中略 ....

接著就是重點,要在 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 的測試有任何更好的做法,還請務必與我分享交流一下,謝謝大家。


Laravel 道場

Laravel 道場致力於提供最好的 PHP/Laravel 教育訓練及顧問服務。從 2013 年起就經營開發社群、舉辦讀書會、教學工作坊,希望透過活動交流與互動,能增加開發者的本職學能及產能。聯絡信箱:hi@laravel-dojo.com

Chengwei Chen

Written by

表面上是只會釋放閃光文的愛妻家,私底下其實是默默關注新知的技術愛好者。平時熱衷研究維運及自動化相關技術,目標是未來可以像畢凱艦長一樣用嘴巴叫所有主機做事! 目前為 DevOps Taiwan 社群志工以及 DevOpsDays Taipei 其中一位 Organizer。https://chengweichen.com

Laravel 道場

Laravel 道場致力於提供最好的 PHP/Laravel 教育訓練及顧問服務。從 2013 年起就經營開發社群、舉辦讀書會、教學工作坊,希望透過活動交流與互動,能增加開發者的本職學能及產能。聯絡信箱:hi@laravel-dojo.com