moleculeとは
- Ansibleのテスト環境の準備からテスト環境へのPlaybook実行、testinfraやinspec、Ansibleでのテスト実行、テスト環境の破棄を全てやってくれるテストフレームワーク。詳細は公式サイトにくわしい。
- 2020/2/21時点の最新はv3.1、サポートするAnsibleのバージョンは最新の2メジャーバージョン。(v2.9が最新の場合はv2.8まで)
前提条件
- docker daemonが起動している。
-
molecule
はバージョン3.0.1
を使用。 -
Ansible
はバージョン2.9.5
を使用。
インストール
pipでインストールする。
$ pip install 'molecule[docker]'
既存ロールにテストシナリオを追加
ロールのディレクトリに移動して実行すること
$ cd roles/nginx
$ moleculer init scenario
-
molecule
ディレクトリが作成される。 - デフォルトのオプションは以下
- シナリオ名: default
- driver: docker
- provisioner: Ansible
- Verifier: Ansible
roles/nginx/molecule
└── default
├── converge.yml
├── INSTALL.rst
├── molecule.yml
└── verify.yml
テスト実行
-
molecule test
を実行するだけ。デフォルトではシナリオ名default
が実行される。個別にシナリオ指定することも可能。
$ molecule test
-
test
では以下全ての工程が実行される。
❯ molecule test --help
Usage: molecule test [OPTIONS]
Test (lint, cleanup, destroy, dependency, syntax, create, prepare,
converge, idempotence, side_effect, verify, cleanup, destroy).
-
今回作成したシナリオでは以下。
- dockerイメージ取得
- dockerコンテナ作成、起動
- ansible-lintでPlaybookのチェック
- playbook実行
- ansibleでテスト実行
- dockerコンテナ破棄
-
これらの工程を個別に指定して実行することも可能。
converge
ではコンテナ作成、Playbook実行、テスト実行、コンテナ破棄までやってくれる。
$ molecule converge
ローカルでテストするだけなら以上で完了。
小ネタ
依存関係のあるロールの実行
ロールに依存関係がある場合、たとえばnginxロールでyum install
しているが、その前にcommonロールでyumのconfig設定している場合はnginxロールだけ実行してもエラーになる。
依存関係にある処理はprepare.yml
に書いておくことで事前に実行することができる。
- name: prepare.yml
hosts: all
tasks:
- name: "execute common role"
include_role:
name: "common"
lintのスキップ
molecule.ymlでオプションをつける
lint: |
yamllint .
ansible-lint -x 701,703
flake8
環境変数を使用
bashと同じ要領で使える。${var:-hoge}
とか${var%/}
とか(名前わからない)も使用可能。
platforms:
- name: instance
image: ${DOCKER_IMAGE:-registry.example.com:5000/centos:7}
コンテナ内でsystemd起動させたい
platforms:
# ~snip~
volumes:
- /var/run/docker.sock:/var/run/docker.sock:rw
- /sys/fs/cgroup:/sys/fs/cgroup:ro
command: /sbin/init
capabilities:
- SYS_ADMIN
Ansibleのhost_vars
,group_vars
を使用
provisioner:
# ~snip~
inventory:
links:
#hosts: ../../../inventory/hosts
group_vars: ../../../..//group_vars/
host_vars: ../../../../host_vars/
testフラグを立てる
provisioner:
name: ansible
ansible_args:
- "-e molecule_test=true"
さらにplaybookの中でwhen: not molecule_test
をつければテストでスキップできる。
verifierをtestinfraに変更する
個人的にはAnsibleでプロビジョニングしたサーバをAsibleでテストすることに疑問を感じる。開発者の間でもかなり議論があった様子。
https://github.com/ansible-community/molecule/issues/2013
testinfraやInspecの学習コストが苦にならないならテストツールは分けるべきというのが個人的な意見なので変更する。
verifier:
name: testinfra
molecule.ymlカスタマイズ例
---
dependency:
name: galaxy
driver:
name: docker
lint: |
yamllint .
ansible-lint -x 701,703
flake8
platforms:
- name: instance
image: ${DOCKER_IMAGE:-registry.example.com:5000/centos:7}
pull: true
pre_build_image: true
privileged: true
volumes:
- /var/run/docker.sock:/var/run/docker.sock:rw
- /sys/fs/cgroup:/sys/fs/cgroup:ro
command: /sbin/init
capabilities:
- SYS_ADMIN
provisioner:
name: ansible
ansible_args:
- "-e molecule_test=true"
inventory:
links:
#hosts: ../../../inventory/hosts
group_vars: ../../../..//group_vars/
host_vars: ../../../../host_vars/
verifier:
name: ansible