Ansible Molecule と Docker を使った Ansible ロールの自動テスト

目的と検索意図(主な狙いと類似クエリ)
この記事の主な狙いは、Ansible ロールを自動でテストするための Molecule と Docker の導入手順とベストプラクティスを、初心者から中級者向けに分かりやすくまとめることです。関連する検索クエリ例:
- Ansible Molecule テスト
- Molecule Docker 使い方
- testinfra Ansible テスト
- Ansible ロール 自動化 テスト
- Molecule CI パイプライン
はじめに(概要)
Ansible Molecule は、ロールやプレイブックの検証を自動化して再現可能にするためのテストフレームワークです。Molecule 自体はドライバー(Docker、Podman、Vagrant、クラウド等)を使って一時的なテストインスタンスを作成し、Ansible の実行→検証→破棄をワンストップで行います。検証には pytest ベースの testinfra などを使います。
重要: 本手順は手元の開発環境でのローカルテスト向けです。本番環境適用前は常に別のステップで検証してください。
前提条件
- Linux システム(この記事は Ubuntu 22.04 を想定、ホスト名例: ansible-test)
- sudo 権限を持つ非 root ユーザー(例: alice)
- Ansible と基本的な概念(ロール、タスク、変数)への理解
- ネットワーク経由で Docker イメージをダウンロードできること
推奨環境とバージョン(事実に依らない数値は記載していません)
- OS: Ubuntu 22.04 を推奨
- Python 3(システムまたは仮想環境上)
- Docker CE(OCI 準拠のコンテナランタイム)
- Molecule と molecule-plugins[docker]
- pytest-testinfra(testinfra)
Important: テストに使うベースイメージには Python が入っている必要があります(Molecule が Ansible を実行するため)。
画像(図や操作画面)
セクション 1: 依存パッケージのインストール
まずパッケージインデックスを更新します。
sudo apt update
次に Python3、pip、仮想環境ツール、Ansible と必要なツールをインストールします。
sudo apt install python3 python3-pip python3-venv ansible ca-certificates curl gnupg lsb-release
プロンプトで y を入力して続行します。
Docker CE は公式リポジトリからインストールするのを推奨します。まずキーリングディレクトリを作り、GPG キーをダウンロードします。
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
リポジトリを追加します。
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
インデックスを更新して Docker をインストールします。
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
現在のユーザーを docker グループに追加し、非 root でコンテナを実行できるようにします。
sudo usermod -aG docker $USER
新しいグループ情報を反映するために一度ログアウト/ログインするか、シェルを再起動します。動作確認として hello-world イメージを実行します。
docker run hello-world
これで依存関係の準備は完了しました。次に仮想環境上に Molecule をインストールします。
セクション 2: Molecule のインストール
作業用の Python 仮想環境を作成し、アクティブ化します。
python3 -m venv ansible-venv
source ansible-venv/bin/activate
仮想環境に移動して Molecule と Docker ドライバーをインストールします。
cd ansible-venv/
pip3 install wheel molecule 'molecule-plugins[docker]'
注記: CI 環境では仮想環境を作らずにコンテナ内で Molecule を実行するケースも一般的です。
セクション 3: Molecule でロール雛形を作成
LEMP(Linux, Nginx, MariaDB, PHP-FPM)を例にロールを作成します。molecule init role コマンドで雛形を生成します。
molecule init role test.lemp --driver-name docker
上のコマンドで現在の作業ディレクトリに lemp フォルダが生成されます。
cd lemp
tasks/main.yml を編集してパッケージとサービスのタスクを定義します。
nano tasks/main.yml
ファイル内容例:
---
- name: "Installing LEMP Stack"
apt:
name: "{{ pkg_list }}"
state: present
- name: "Ensure LEMP Services is running"
service:
name: "{{ item }}"
state: started
enabled: true
with_items: "{{ svc_list }}"
保存して終了します。
vars/main.yml にパッケージとサービス名の変数を追加します。
nano vars/main.yml
ファイル内容例:
---
pkg_list:
- nginx
- mariadb-server
- php-fpm
- php-cli
svc_list:
- nginx
- mariadb
- php8.1-fpm
セクション 4: テスト用インスタンスの設定
Molecule のデフォルト設定ファイルを編集してテストに使うプラットフォーム(イメージ)を指定します。例として mipguerrero26/ubuntu-python3 イメージを利用します。
まずローカルで対象イメージを一度 pull して動作確認します。
docker pull mipguerrero26/ubuntu-python3
docker images
必要であれば一時コンテナで Python バージョンや OS 情報を確認します。
docker run -it mipguerrero26/ubuntu-python3 /bin/bash
python3 --version
cat /etc/lsb-release
exit
molecule/default/molecule.yml を編集して platforms セクションにイメージ名と privileged 設定を入れます。
nano molecule/default/molecule.yml
編集例:
platforms:
- name: instance-ubuntu22.04
image: mipguerrero26/ubuntu-python3
privileged: true
保存してエディタを閉じます。
インスタンスの一覧を確認します。
molecule list
セクション 5: Converge でロールを適用する
実際に Molecule がコンテナを作成してロールを適用するには以下を実行します。
molecule converge
処理の流れ: Molecule が Docker で一時インスタンスを立ち上げ → Ansible ロールを適用 → 必要なら手動でコンテナに入って確認できます。
Molecule がコンテナを作成している様子:
Ansible ロールが適用される様子:
適用後、docker ps で対象コンテナを確認し、exec で入ってサービスの状態をチェックします。
docker ps
docker exec -it instance-ubuntu22.04 /bin/bash
ss -tulpn
ss -pl | grep php
最後にテストが終わったら環境を破棄します。
molecule destroy
コンテナがないことを確認します。
docker ps
docker ps -a
セクション 6: testinfra を使った検証スクリプトの作成
testinfra は pytest ベースのライブラリで、ターゲットホストの状態(パッケージ、サービス、ファイル等)を検証できます。まずインストールします。
pip3 install pytest-testinfra
テストディレクトリとテストファイルを作成します。
mkdir -p molecule/default/tests/
nano molecule/default/tests/test_default.py
test_default.py の例:
import os
import pytest
import testinfra.utils.ansible_runner
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
@pytest.mark.parametrize('pkg', [
'nginx',
'mariadb-server',
'php-fpm'
])
def test_pkg(host, pkg):
package = host.package(pkg)
assert package.is_installed
@pytest.mark.parametrize('svc', [
'nginx',
'mariadb',
'php8.1-fpm'
])
def test_svc(host, svc):
service = host.service(svc)
assert service.is_running
assert service.is_enabled
保存して終了します。
molecule/default/molecule.yml の verifier セクションを testinfra と tests ディレクトリを指すように変更します。
nano molecule/default/molecule.yml
編集例:
verifier:
name: testinfra
directory: tests
保存してファイルを閉じます。
そしてフルテストを実行します(create → converge → verify → destroy の一連の流れ)。
molecule test
実行中は既存インスタンスの破棄や新規作成が行われます。
テスト実行後の出力例: collected X items - X passed といった成功報告が表示されます。
セクション 7: 開発フローと推奨ワークフロー
ローカルでの推奨開発フロー(反復):
- molecule init でロール雛形を生成
- tasks/vars を編集してロールを実装
- molecule converge で手動確認
- molecule verify を実行して自動検証
- 問題がなければコミット→CI で molecule test を実行
コマンドまとめ:
molecule converge
molecule verify
molecule destroy
molecule test
molecule --help
トラブルシューティングとよくある問題
- Docker イメージに Python がない: Molecule は Ansible を実行するために Python を必要とします。ベースイメージに Python があるか事前に確認してください。
- 権限エラー: docker グループへユーザーが追加されているか、現在のシェルへ反映されているか確認します(ログアウト/ログイン)。
- ネットワーク経由でのイメージ取得失敗: プロキシやファイアウォール設定を確認。
- サービス名の不一致: ディストリビューションやパッケージ名によってサービス名が異なる場合があります(例: php8.1-fpm 等)。
Notes: testinfra の API を使えばファイルの内容やパーミッション、ソケットの存在なども柔軟に検証できます。
追加価値: 運用向けチェックリストとプレイブック
以下は現場で使えるチェックリストと簡易 SOP(手順書)です。CI パイプラインやデベロッパーのローカル開発、運用担当者別に整理しています。
Role 開発者向けチェックリスト
- molecule init を実行して雛形を生成した
- tasks と vars を最小変更で動かすことを確認した
- molecule converge で手動確認を行った
- testinfra による自動テストを作成した
- molecule test をローカルで成功させた
CI エンジニア向けチェックリスト
- CI イメージに Docker (あるいは Docker-in-Docker を)用意した
- 仮想環境のセットアップ(Python 仮想環境 / pip キャッシュ)を組み込んだ
- molecule test をパイプライン内で自動実行している
- テスト失敗時にアーティファクト(ログ/インベントリ)を保存している
運用担当者向けチェックリスト
- 使用するベースイメージの OS とパッケージポリシーを把握している
- テストで利用するポートやボリュームの競合を回避している
- 破棄処理(molecule destroy)が確実に行われることを確認している
テストケースと受入基準(例)
- テストケース 1: パッケージのインストール
- 期待値: nginx, mariadb-server, php-fpm がインストールされている
- テストケース 2: サービスの稼働
- 期待値: nginx と mariadb と php-fpm が起動中かつ自動起動設定されている
- テストケース 3: ポート確認
- 期待値: nginx が 80 ポートで LISTEN している
- 受入基準: 全ての testinfra テストが成功し、molecule test がエラー無しで終了すること
代替アプローチと相互比較
- Podman ドライバー: rootless コンテナ運用やセキュリティポリシーが厳しい環境では Podman を検討する。Podman は Docker 互換だが、一部のネットワーク機能やボリュームの挙動が異なる。
- Vagrant + VirtualBox: 仮想マシンベースでより実機に近い検証をしたい場合は Vagrant ドライバーが有効。ただし VM 起動はコンテナより遅い。
- クラウドプロバイダー: AWS/Azure/GCP を使うと本番に近い環境でのテストが可能だが、コストと破棄漏れのリスクに注意する。
選択のヒューリスティック: 速さと反復開発重視なら Docker、再現性と本番互換を重視するなら VM/クラウドを選択。
失敗例といつこの方法が向かないか
- ベースイメージ側の init や systemd に依存するロールは、軽量なコンテナでの検証が困難な場合があります。systemd が必要なサービスは VM ベースのテストが必要になることがあります。
- ハードウェア依存(特定の NIC, GPU)や特定のカーネルモジュールに依存するテストはコンテナ検証では不十分です。
インシデント対応(簡易ランブック)
- テスト失敗を検知したらログとインベントリを収集する。
- molecule –debug を再実行して詳細ログを取得
- ローカルで再現可能か確認する。
- molecule converge をローカルで実行し、失敗箇所を特定
- 失敗がロールの変更によるものか外部依存かを切り分ける。
- 必要なら rool をロールバックし、影響範囲を洗い出す。
- CI での再発防止: テストを追加して回帰を防ぐ
互換性メモと移行のコツ
- Ansible バージョンによってモジュールの動作やパラメータが変わることがあるため、Molecule のテストで使用する Ansible バージョンを固定することを推奨します。
- OS 切替時はパッケージ名やサービス名の差分に注意してください(例: Debian 系と RHEL 系でパッケージ名が異なる)。
1行用語集
- Molecule: Ansible ロールのテストを自動化するフレームワーク
- testinfra: pytest ベースのインフラ検証ライブラリ
- Converge: ロールをターゲットに適用して望ましい状態にする操作
セキュリティ・プライバシーメモ
- テストで使用するイメージやアーティファクトに機密情報(パスワード、証明書)を含めないこと。CI のシークレット管理は適切なシークレットストアを利用する。
SNS 用プレビュー候補
OG タイトル候補: Ansible Molecule と Docker でロールを自動テスト OG 説明候補: Molecule と Docker、testinfra を使って Ansible ロールをローカルで自動検証する手順と運用チェックリストを解説。
まとめ
- Molecule は Ansible ロールをローカルや CI 上で自動テストするための強力なツールです。
- Docker ドライバーは高速で反復テストに向いていますが、必要に応じて Podman、Vagrant、クラウドを選択してください。
- testinfra を活用してパッケージ・サービス・ソケットなどを自動検証することで品質を向上できます。
重要: テストは本番環境の安全性を保証するものではありません。ロールの本番投入前に別途ステージング環境での検証を必ず行ってください。
さらに学ぶための公式ドキュメント: Ansible Molecule の公式ドキュメントを参照してください。