はじめに

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 でテストできる状態を保っていきたいですね。

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