GitLab CIとMoleculeでRoleテスト自動化

はじめに

AnsibleにはRoleのテストを支援してくれる「Molecule」というツールがあります。今回は MoleculeGitLab CI を用いてRoleのテスト自動化ができるように環境を整えていきます。

Moleculeの詳細については、ひよこ大佐本こと「Ansible構築・運用ガイドブック」や「ソフトウェアデザイン 2020年6月号」に載っています。(Molecule実践ガイドまだ?)

主に備忘録のため参照される場合は適宜読み替えてください。

作業内容

今回は「自宅ラボ」と称している仮想化基盤(ESXi)上の「作業用マシン(CentOS 7)」で

  • moleculeコマンドの実行
  • GitLab Runnerコンテナの起動
  • GitLab CIでmolecule testの自動化

をできるようにします。なお前提として、作業用マシンにはdockerインストール済みで、GitLabは仮想化基盤上の別サーバに導入済みです。

環境構築

Moleculeインストール

作業用マシンでMoleculeのコマンドを実行できるようにします。Molecule 公式サイトに複数のインストール方法が載っていますが、今回はvirtualenv内にmoleculeコマンドをインストールします。

$ sudo python3 -m pip install virtualenv
$ virtualenv molecule
$ source molecule/bin/activate
(molecule) $ python -m pip install "molecule[lint]" "docker"
(molecule) $ molecule --version
molecule 3.0.4
ansible==2.9.9 python==3.6

公式サイトではインストール時に--userオプションを付いていたのですが、自分の環境ではエラーが出てしまったので外しています(TODO: エラー原因調査)。また、pipでmoleculeをインストールするとansibleもついてきます。pipでansibleをインストールする場合はmoleculeに置き換えてもいいかもしれませんね。

Ansible Role作成

さきほどインストールしたmoleculeコマンドを使ってAnsibleのRoleを作成します。ansible-galaxyコマンドと同様に、Roleに必要なディレクトリのテンプレートを作成することができ、Moleculeで使用する molecule ディレクトリも作成されます。今回は「test-role」という名前のRoleにしています。

(molecule) $ molecule init role test-role
--> Initializing new role test-role...
Initialized role in /home/nnstt1/test-role successfully.

(molecule) $ ls -l ./test-role/
total 4
drwxrwxr-x 2 nnstt1 nnstt1   22 May 31 20:58 defaults
drwxrwxr-x 2 nnstt1 nnstt1    6 May 31 20:58 files
drwxrwxr-x 2 nnstt1 nnstt1   22 May 31 20:58 handlers
drwxrwxr-x 2 nnstt1 nnstt1   22 May 31 20:58 meta
drwxrwxr-x 3 nnstt1 nnstt1   21 May 31 20:58 molecule
-rw-rw-r-- 1 nnstt1 nnstt1 1328 May 31 20:58 README.md
drwxrwxr-x 2 nnstt1 nnstt1   22 May 31 20:58 tasks
drwxrwxr-x 2 nnstt1 nnstt1    6 May 31 20:58 templates
drwxrwxr-x 2 nnstt1 nnstt1   39 May 31 20:58 tests
drwxrwxr-x 2 nnstt1 nnstt1   22 May 31 20:58 vars

この状態でmolecule testコマンドを実行すると、テスト実行環境のコンテナが作成されてテストできるようになっていると思います。また、./test-roleディレクトリをGitLabで管理するリポジトリとして扱います。(git init等は省略)

GitLab Runner 登録

GitLab CI用に作業マシン上のGitLab Runnerを登録します。今回gitlab/gitlab-runnerコンテナイメージを使用します。

# コンテナ起動
$ docker run -d --name gitlab-runner --restart always \
  -v /srv/gitlab-runner/config:/etc/gitlab-runner  \
  -v /var/run/docker.sock:/var/run/docker.sock \
  gitlab/gitlab-runner:latest

# GitLab-Runner登録
$ docker exec -it gitlab-runner gitlab-runner register -n \
  --url https://gitlab.nnstt1.work/ \
  --registration-token [TOKEN] \
  --executor docker \
  --description "My Docker Runner" \
  --docker-image "docker:19.03.8" \
  --docker-privileged \
  --docker-volumes "/certs/client"

今回のつまずきとして、GitLab-Runnerを登録する際にdocker-privilegedをFalseの状態で登録していたため、.gitlab-ci.ymlに書いたdindコンテナが起動せずに、GitLab CIで実行されたコンテナ内でdockerコマンドが使用できない旨のエラーが発生しました。

.gitlab-ci.yml

リポジオリ直下に .gitlab-ci.yml を作成してGitLab Runnerで動かすコンテナと実行スクリプトを定義します。Molecule 公式サイトに各種CIツールでのテスト自動化方法が記載されており、今回はそちらの.gitlab-ci.ymlを使っています。

一部追記しており、環境変数DOCKER_TLS_CERTDIR/certs を設定しています。(参考: Building Docker images with GitLab CI/CD

---
image: docker:latest

variables:
  DOCKER_TLS_CERTDIR: "/certs"

services:
  - docker:dind

before_script:
  - apk update && apk add --no-cache
    python3-dev py3-pip gcc git curl build-base
    autoconf automake py3-cryptography linux-headers
    musl-dev libffi-dev openssl-dev openssh
  - docker info
  - python3 --version
  - python3 -m pip install ansible molecule[docker]
  - ansible --version
  - molecule --version

molecule:
  stage: test
  script:
    - molecule test

テスト自動化の確認

以上で環境は整いました。あとはGitLab上のリポジトリを更新すれば自動的にmolecule testが実行されてRoleのテストが行われます。

まとめ

GitLab CIとMoleculeを使ってRoleのテスト自動化ができるようになりました。既に作っているRoleにテストを追加していくのは大変ですが、少なくとも新規Roleについては継続的にMoleculeでテストできる状態を保っていきたいですね。

職場のプロキシ環境下で同じようなことが簡単にできるかな…。