【Ansible】Moleculeを利用してローカルマシン上でRole Testしてみた!

どもども、生後1ヶ月の息子に振り回される新米パパです。


皆様、Ansibleは利用しておりますでしょうか。リモートホストの設定をコード管理し柔軟に適用することができる大変優れたツールです。


ただしこのAnsible、個人的にどうしても気になってしまう点がありました。それは"設定適用は一方的であり元に戻すことはできない"という点と"Checkオプションは存在するが実際に適用してみると思わぬエラーが発生しやすい"という点です。


これらの問題を解決するには"実際に設定を適用できるテスト用環境を用意する"必要がありますが、わざわざAnsibleの適用テストのためにホストを一台準備するのはコストも手間もかかりすぎます。


もちろん本番環境適用までにステージング環境などで一度試行し大きな事故が起こらないようにしている場合も多いでしょうが、それにしたって一々コードレビューを通さないといけません。これで実際に適用して問題が発生したら、また修正してレビュー出して…めんどくさい!


なんとかローカルマシンでいい感じにテストできないものかね!と思ってた矢先、とても良さそうなものを見つけ、実際に使用してみましたので紹介したいと思います。その名も"Molecule"!

Moleculeの概要

MoleculeはAnsible Roleのテストツールです。


Moleculeを利用することでテスト環境の作成からRole単位のtaskテスト、冪等性チェックまで行ってくれる大変優れたツールです。今回は私のローカルマシン(MacOS Catalina 10.15.7)で実行してみたいと思います。


テスト環境はdockerやVagrantなどを利用して構築されます。今回はdockerを利用したテストを行います。


それでは実際にMoleculeを利用してみましょう。

Molecule をインストールする

まずはMoleculeとテスト環境へ接続する処理を行うドライバーをインストールします。


今回はpipを利用してインストールしましょう。

$ pip3 install (--user) molecule
$ pip3 install (--user) molecule-docker

Moleculeのバージョンとドライバー一覧を確認し、インストールが無事完了していることを確認します。

$ molecule --version
$ molecule drivers

それでは次にテストまでの下準備をしましょう。

テスト準備

まずはMoleculeを利用してroleディレクトリ内に今回使用するディレクトリを作成します。taskディレクトリやhandlers
、metaディレクトリなどroleを定める上で必要なディレクトリ テンプレートを作成することができます。


今回はAmazon Linux2インスタンスにJava17をインストールするロールを作成するという前提のもと、下記コマンドでディレクトリ を作成します。

$ molecule init role test.java --driver-name docker

すると下記のような構成のディレクトリが構築されるかと思います。

.
├── README.md
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── molecule
│   └── default
│       ├── converge.yml
│       ├── molecule.yml
│       └── verify.yml
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

ansible-galaxy initでも同じようにテンプレートディレクトリを作成することができますが、今回の場合はMoleculeの利用に必要なmoleculeディレクトリとtestsディレクトリも追加されていることが確認できます。


今回は手っ取り早くテストだけ行いたいので必要な部分のみ設定します。


まずは普段と同様に"tasks/main.yml"に今回の設定内容を記載します。先ほどにも述べた通り今回はAmazon Linux2インスタンスにJava17をインストールするため

---
# tasks file for java
# Install and Set up JAVA

- name: Install corret headless
  yum:
    name: java-17-amazon-corretto-headless
    state: present
- name: Install corret
  yum:
    name: java-17-amazon-corretto
    state: present
- name: Install corret devel
  yum:
    name: java-17-amazon-corretto-devel
    state: present
- name: Install corret jmods
  yum:
    name: java-17-amazon-corretto-jmods
    state: present
- name: Alternatives.
  alternatives:
    name: '{{ item }}'
    link: "/usr/bin/{{ item }}"
    path: "/usr/lib/jvm/java-17-amazon-corretto.x86_64/bin/{{ item }}"
  with_items:
    - java
    - javac

- name: Get JAVA version
  command: java -version
  tags:
  - molecule-idempotence-notest

このように記載します。注目して欲しいのは下記の部分です。

- name: Get JAVA version
  command: java -version
  tags:
  - molecule-idempotence-notest

見慣れないタグが付いているかと思います。これはMoleculeの冪等性もチェックに配慮するため追加します。

commandモジュールなど何度も実行されてしまうものについてはその都度changedの判定となり冪等性チェックに失敗するため対象から除外するようタグをつけておきます。


次にmoleculeディレクトリ内の"molecule.yml"を修正します。

---
dependency:
  name: galaxy
driver:
  name: docker
platforms:
  - name: instance
    image: amazonlinux:2
    pre_build_image: true
provisioner:
  name: ansible
verifier:
  name: ansible

moleculeの基本設定ファイルです。platformsのimageをAmazon Linux2に変更しておきます。


これで準備完了です!実際にテストしてみましょう。

ROleテスト

それではテストコマンドを実行してきます。まずはroles/javaディレクトリに移動しておきましょう。

下記コマンドを実行してテストを開始します。今回はroleの指定はしません。

$ molecule test --all

するとテスト環境構築が始まり、role内に設定されたtaskが実行され始めたことがわかります。


普段通りの設定適用に加え、冪等性のチェックも行われています。下記のようなERRORが表示されている場合は前述のとおり冪等性エラーが発生しているのでタグをつけるなど対応する必要があります。

CRITICAL Idempotence test failed because of the following tasks:

冪等性チェックが全てGreenであれば無事テストが通ったということになります!

まとめ

お疲れ様でした!MoleculeによるAnsibleのRoleテストでした。


今回はローカルマシン上で実行しましたが、CIに組み込むなど使い方は様々で非常に便利かと思います。


「ansibleチェックオプションは通ったけどなんか緊張するな」という感覚を少しでも減らすことができれば幸いです。


ここまで読んでいただきありがとうございました!

ansible

Posted by CY