Molecule は、 Ansible 向けのテストフレームワークです。 role 単体のテストしか試していませんが、複数の role を跨いだテストもできるかもしれません。
1. Molecule
Ansible を書いていると冪等性を保つために register
や when
を使うわけですが、コード量が増えてくると意図した通りに動作しているのか不安になってきます。
Molecule を使うと仮想環境の準備から Ansible の実行、環境の破棄までを行ってくれます。
- YAML ファイルの静的解析 ( YAML lint / Ansible lint )
- 指定した仮想環境への Ansible playbook 流し込み
- Testinfra による構築環境の状態テスト
- Ansible playbook (role's task) の冪等性検証
Molecule では、 Ansible を流し込む仮想環境を Driver と呼んでおり、いくつか用意されています。デフォルトの Driver は、 Docker です。 ( 私が試したのも Docker です )
- Azure
- Delegated
- Docker (Default)
- EC2
- GCE
- LXC
- LXD
- Openstack
- Vagrant
- Molecule Vagrant Module
2. 使い方
以下、テストの実行環境は Ubuntu 16.04 です。
2.1. Python の環境
何はともあれ、 Python の環境を整えます。以下、 pyenv と pyenv-virtualenv を使う場合の手順です。
$ pyenv install 3.6.5
$ pyenv virtualenv 3.6.5 molecule-py3
$ pyenv shell molecule-py3
必要な Python パッケージをインストールします。この記事を書いた時点でのインストールパッケージのバージョンです。
package | version |
---|---|
ansible | 2.5.2 |
molecule | 2.13.1 |
docker-py | 1.10.6 |
$ pip install ansible molecule docker-py
$ pip list --format=columns
pip list --format=columns
Package Version
---------------- ---------
ansible 2.5.2
ansible-lint 3.4.21
anyconfig 0.9.4
arrow 0.12.1
asn1crypto 0.24.0
attrs 18.1.0
bcrypt 3.1.4
binaryornot 0.4.4
Cerberus 1.1
certifi 2018.4.16
cffi 1.11.5
chardet 3.0.4
click 6.7
click-completion 0.3.1
colorama 0.3.9
cookiecutter 1.6.0
cryptography 2.2.2
docker-py 1.10.6
docker-pycreds 0.2.3
fasteners 0.14.1
flake8 3.5.0
future 0.16.0
git-url-parse 1.1.0
idna 2.6
Jinja2 2.10
jinja2-time 0.2.0
MarkupSafe 1.0
mccabe 0.6.1
molecule 2.13.1
monotonic 1.5
more-itertools 4.1.0
paramiko 2.4.1
pathspec 0.5.6
pbr 3.0.1
pexpect 4.2.1
pip 10.0.1
pluggy 0.6.0
poyo 0.4.1
psutil 5.2.2
ptyprocess 0.5.2
py 1.5.3
pyasn1 0.4.2
pycodestyle 2.3.1
pycparser 2.18
pyflakes 1.6.0
PyNaCl 1.2.1
pytest 3.5.1
python-dateutil 2.7.2
python-gilt 1.2.1
PyYAML 3.12
requests 2.18.4
setuptools 39.0.1
sh 1.12.14
six 1.11.0
tabulate 0.8.2
testinfra 1.12.0
tree-format 0.1.2
urllib3 1.22
websocket-client 0.47.0
whichcraft 0.4.1
yamllint 1.11.1
2.2. テストの追加
既存の Ansible Role にテストを追加する場合、 Role が配置されているディレクトリまで移動します。 Ansible の Best Practices に従っている場合、 tasks
や files
ディレクトリが存在する場所です。
$ cd /path/to/<role_name>
molecule init scenario
で既存の Role に Molecule のテストを追加します。
$ molecule init scenario -r <role_name>
以下のファイルが生成されます。
$ tree molecule
molecule/
└── default
├── create.yml
├── destroy.yml
├── Dockerfile.j2
├── INSTALL.rst
├── molecule.yml
├── playbook.yml
├── prepare.yml
└── tests
├── __pycache__
│ └── test_default.cpython-36.pyc
└── test_default.py
3 directories, 9 files
テストを走らせる前に molecule.yml
と test_default.py
を編集します。
molecule.yml
に Driver と Ansible を流し込むイメージを指定します。 Driver が docker
で、イメージが Ubuntu 16.04
の場合、以下のように指定します。他の設定は 公式ドキュメント を参照してください。 サンプルコード も 一応 用意されています。
...
driver:
name: docker
platform:
- name: instance
image: ubuntu:16.04
...
test_default.py
にテストを記述します。テストには testinfra が使われています。 Python 版の Serverspec 的な位置づけですかね。
2.3. テストの実行
この時点で一応 molecule test
を実行できます。
$ sudo -E molecule test
molecule test
はすべてのテストを実行するので、場合によっては非効率になります。例えば、 molecule test
には環境の破棄まで含まれているので、エラーが発生したときに調査できなくなってしまいます。
Molecule には、 test
以外にもいくつかのコマンドが用意されていますので、使い分けると効率的にテストができます。
check Use the provisioner to perform a Dry-Run...
converge Use the provisioner to configure instances...
create Use the provisioner to start the instances.
dependency Manage the role's dependencies.
destroy Use the provisioner to destroy the instances.
idempotence Use the provisioner to configure the...
init Initialize a new role or scenario.
lint Lint the role.
list Lists status of instances.
login Log in to one instance.
prepare Use the provisioner to prepare the instances...
side-effect Use the provisioner to perform side-effects...
syntax Use the provisioner to syntax check the role.
test Test (lint, destroy, dependency, syntax,...
verify Run automated tests against instances.
よく使うのは converge
と destroy
ですかね。
converge
は次のテストが含まれていて、環境の準備と Ansible の流し込みが行われます。
└── default
├── dependency
├── create
├── prepare
└── converge
環境は破棄されていないので、普通に docker
のコマンドでコンテナの中に入れます。
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
c12b3f5ab75f molecule_local/ubuntu:16.04 "bash -c 'while true…" 22 minutes ago Up 22 minutes instance
$ sudo docker exec -it c1 bash
root@instance:/#
destroy
は、文字通り環境の破棄です。
3. 使ってみて
Ansible を含めて Molecule は、 Python で書かれているので環境の準備が簡単です。テストで面倒な環境の生成と破棄を行ってくれるのは非常に便利です ( Docker なので起動と終了も早い ) 。
ただ 1 点、日本語のドキュメントが少なくて困るので、備忘録として残しておきます。