MoleculeでAnsibleのRoleをテストする - その1
こんにちは。株式会社SHIFT、自動化エンジニアの水谷です。最近はAnsibleに関する記事ばかり書いていますが、今回もAnsibleに関する記事です(汗
Ansibleにおける自動テスト
アプリ開発などと同様に、AnsibleでPlaybookを作成して何かを自動化する際にも、テストは重要な工程の1つとなります。
Playbookのテストとしては、ansible-playbookコマンドの--syntax-checkオプションでシンタックスチェックを行うことや、Ansible LintやYAML Lintで書式ミスをチェックするのもその1つになります。これら2つのテストは、簡単に自動実行できるので、Gitなどにコミットする際に、(CIとして)自動実行することは簡単にできるでしょう。
では、文法や記述ミスではなくPlaybookの動作内容を自動テストしたい場合はどうすればよいでしょうか? 実際にコマンドラインからPlaybookを実行してみて、ターゲットマシンに接続して、期待通りの状態になっているか確認するしかないのでしょうか? これでは、変数をいろいろ変えて、リグレッションを起こしていないか、など細かい点まで毎回確認するのは手間がかかりますし、漏れもでてしまうことでしょう。
そこで、Playbook用のテストフレームワークが欲しいところですが、探してみると、いくつかありました。その中でもMoleculeが機能的にも充実していますので、今回と次回の2回に分けてMoleculeについて書いてみたいと思います。
1回目の今回は、Moleculeの導入からDockerコンテナ内でRoleを実行するところまでになります。
Moleculeとは
Moleculeは、正確にはPlaybookではなく、Roleの開発支援とテストを自動化するツールで、テストの部分に注目すると、以下のテストが行えるとされています。
どうやら、Dockerでターゲット環境(Playbookで操作される側)を構築し、Playbookを実行した後にテストを行い、終了後はテスト環境を自動的に削除してくる感じに見えます。これは便利そうですね。
Moleculeのインストール
さて、まずはMoleculeのインストール方法から見ていきましょう。MoleculeはPythonで作られているので、pip(pip3)でインストールできます。なお、今回もWindows 10上のWSL2にインストールしたUbuntu 18.08で作業を行っていきます。
$ pip3 install molecule[docker,lint]
最後の[docker,lint]の部分は、Playbookの実行にDockerを使い、Lintの実行を行うことを意味しています。もしLintのみを行いたい場合は[lint]とし、逆にLintは不応でDocker上での実行テストのみを行いたい場合は[docker]と指定すれば良いようです。
なお、最新版のMoleculeは、Ansible 2.10以上に対応しているようなので、2.9以下がインストールされている場合は、一度アンインストールしたほうがよいようです。
また、今回はDockerを使ってRoleの実行をしたいので、Dockerのインストールを行いました。試してみたい方はDocker-CEをインストールしておいてください。
Moleculeを使ったRoleの作成
以前Ansible Galaxyを使ってRoleのフォルダ構成を作成する方法について書いたことがありましたが、MoleculeにもRoleのフォルダやファイルを作成する機能があります。Moleculeを使ってRoleのテストをするのに必要な各種ファイルも作ってくれますので、必ずRoleのテストを行いたい場合はMoleculeを使ってRoleを作成するようにしましょう。
さて、そのRoleの雛形を作るには以下のようにinitオプションを使用してmoleculeコマンドを実行します。
$ molecule init role <role名>
今回は例としてApacheをインストールするRoleを作ってみましょう。
$ molecule init role apache
これで、下のようなフォルダとファイルが生成されました。
molecule.ymlの中身
このフォルダ構成を、Ansible Galaxyで作ったRoleとを比べると、moleculeで作ったRoleには"molecule"ディレクトリと"tests"ディレクトリが存在することに気づきます。
"tests"の下にはテスト用Playbookと、テスト用インベントリファイルがあり、実行したいテストをここに記述することになります。一方の"molecule"ディレクトリには、どのようなテストをどんな環境で実行するか、などの指定するためのファイルが作られています。
その中のmolecule/default/molecule.ymlを見てみましょう。
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: instance
image: docker.io/pycontribs/centos:8
pre_build_image: true
provisioner:
name: ansible
verifier:
name: ansible
これを見ると、なんとなくDockerで、centos 8のイメージを使ったターゲット環境を用意して、そこに対してPlaybookを実行してくれるであろうことがわかりますね。
今回はUbuntuをターゲットとしたRoleをテストしたいので、imageの行を下のように変更し、pre-build_imageの行はfalseにしました(これにより、素のUbuntuからターゲット環境を作ってくれるようです)。
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: instance
image: ubuntu:18.04
pre_build_image: false
provisioner:
name: ansible
verifier:
name: ansible
Apacheインストールタスクの作成
今回は、UbuntuにApacheをインストールして、サービスを開始するだけの簡単なRoleとしますので、tasks/main.ymlは下のようなものになります。
---
- name: install apache2
apt:
name: apache2
state: present
- name: start apache2
service:
name: httpd
state: started
enabled: true
サンプルRoleに対する実行結果
さて、最低限の準備が整ったので、MoleculeからこのRoleを実行してみたいと思います。
Moleculeは、"test"オプションを指定して実行すれば、指定したテストを順に実行してくれるようですが、まずはDockerでターゲットが作られ、これに対してPlaybookが実行されるところまでのステップを1つずつ実行して見ていきたいと思います。
まず、コンテナの作成ですが、これは対象のRole内に移動して、"molecule create"で行います。
$ cd apache
$ molecule create
結果は以下のように、ターゲットコンテナ作成のPlaybookが実行されました。
確認のため、"docker ps"を実行してみると、下のようにコンテナが動いていることが確認できました。
ターゲットの準備ができたので、次にRoleを実行してみましょう。
Roleを実行するにはMoleculeを"converge"オプションで実行します。これにより、自動生成されたconverge.ymlというPlaybook(作成したRoleを実行するだけの簡単なもの)が実行されます。
結果はこのようにFailが出て失敗してしまいました。
表示されているメッセージを見ると、aptでインストールしようとした"apache2"パッケージがないとのこと。
実際に"molecule login"でコンテナ内に入って"apt list"をしてみると、apache2がありませんでしたので、"apt update"を実行してみました。
そして、再度"molecule converge"を実行してみると、下のように無事ApacheがインストールされPlaybookが最後まで実行できました。
どうやら、ターゲットのコンテナを作るときに、"apt update"を実行するようにしておかないといけないようですね。
【補足】後からわかったのですが、コマンドの追加は"platforms:"のところで下のように"command:"の行を追加することで、できました。
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: instance
image: ubuntu:18.04
pre_build_image: false
command: "apt update"
provisioner:
name: ansible
verifier:
name: ansible
何はともあれ、これでWSL2上のUbuntuの中にDockerでUbuntuを動かし、それをターゲットとしてPlaybookの実行ができたことになります!
それにしても、Windows 10の中でUbuntuが動いて、さらにその中でUbuntuが動いているという状況を見て、なんだかとんでもない世界にいるな、とか思ってしまうのは自分だけでしょうか……。
さて、後処理についても確認しておくと、コンテナを終了させるには、"destroy"オプションでMoleculeを実行すればOKのようです。
これでターゲットのコンテナが削除され、また次回はクリーンな状態でテストができることになりました。
今回はMoleculeのインストールとRoleの作成、基本的な実行のところまで書きましたが、次回はLintの実行と、Roleのテストを行うタスクを追加してRoleの本格的なテストを行ってみたいと思います。
――――――――――――――――――――――――――――――――――
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/