見出し画像

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の開発支援とテストを自動化するツールで、テストの部分に注目すると、以下のテストが行えるとされています。

・Lintチェック
・Docker内でのPlaybook実行
・冪等性チェック
・テストコードの実行

どうやら、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以下がインストールされている場合は、一度アンインストールしたほうがよいようです。

画像1

また、今回は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

これで、下のようなフォルダとファイルが生成されました。

画像2

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が実行されました。

画像3

確認のため、"docker ps"を実行してみると、下のようにコンテナが動いていることが確認できました。

画像4

ターゲットの準備ができたので、次にRoleを実行してみましょう。

Roleを実行するにはMoleculeを"converge"オプションで実行します。これにより、自動生成されたconverge.ymlというPlaybook(作成したRoleを実行するだけの簡単なもの)が実行されます。

画像5

結果はこのようにFailが出て失敗してしまいました。

表示されているメッセージを見ると、aptでインストールしようとした"apache2"パッケージがないとのこと。

実際に"molecule login"でコンテナ内に入って"apt list"をしてみると、apache2がありませんでしたので、"apt update"を実行してみました。

画像6

そして、再度"molecule converge"を実行してみると、下のように無事ApacheがインストールされPlaybookが最後まで実行できました。

画像7

どうやら、ターゲットのコンテナを作るときに、"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のようです。

画像8

これでターゲットのコンテナが削除され、また次回はクリーンな状態でテストができることになりました。

今回はMoleculeのインストールとRoleの作成、基本的な実行のところまで書きましたが、次回はLintの実行と、Roleのテストを行うタスクを追加してRoleの本格的なテストを行ってみたいと思います。
――――――――――――――――――――――――――――――――――

執筆者プロフィール:水谷 裕一
大手外資系IT企業で15年間テストエンジニアとして、多数のプロジェクトでテストの自動化作業を経験。その後画像処理系ベンチャーを経てSHIFTに入社。
SHIFTでは、テストの自動化案件を2件こなした後、株式会社リアルグローブ・オートメーティッド(RGA)にPMとして出向中。RGAでは主にAnsibleに関する案件をプレーイングマネジャーとして担当している。

お問合せはお気軽に
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/