【無料ツール】画像をPDFに変換するPhotoPDF Appを公開しました!

【Ansible応用講座 第5回】品質を保証する。MoleculeによるRoleの自動テストとCI連携完全ガイド

「動くかどうかは、運次第」からの脱却。

こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回は、Pythonを使ってAnsibleを拡張するカスタムモジュールの開発を行いました。

さて、あなたが苦労して作り上げた最強のRole。これ、「半年後も確実に動く」と保証できますか?
OSのバージョンが上がったり、依存ライブラリが変わったり、あるいはチームメンバーがうっかり変な修正を加えたり…。
「久しぶりに実行したらエラーで止まって、冷や汗をかいた」という経験は、エンジニアなら誰しもあるはずです。

コウ君

先生、耳が痛いです…。
この前、先輩が作ったRoleを使おうとしたら全然動かなくて。
直そうと思っても、どこを直すと他に影響が出るか分からなくて、結局ゼロから作り直しちゃいました。
プログラムみたいに「テスト」ができればいいんですけど、サーバー構築のテストってどうやるんですか? まさか毎回サーバー立てて壊すんですか?

リナックス先生

その「まさか」を全自動でやるのが、今回のテーマ「Molecule(モレキュール)」よ。
Dockerコンテナを一瞬で立ち上げて、Ansibleを実行して、正しく設定されたかチェックして、最後に破棄する。
これをコマンド一発、あるいはGitにプッシュするたびに自動でやってくれるの。
これができれば、インフラエンジニアとしての信頼度は爆上がりよ!

本記事では、AlmaLinux 9 をベースに、Ansible専用テストフレームワーク Molecule の導入、テストシナリオの作成、そして GitHub Actions と連携したCIパイプラインの構築までを徹底解説します。

🚀 Ansible応用講座(全8回)

現在地:【第5回】品質を保証する。MoleculeによるRoleの自動テストとCI連携


第1章:Molecule(モレキュール)とは何か?

Moleculeは、AnsibleのRole(ロール)を開発・テストするための公式プロジェクトです。
「インフラコードの単体テストツール」とイメージしてください。

Moleculeがやってくれること

molecule test というコマンドを叩くだけで、以下のフローを全自動で行います。

  1. Dependency: 依存するRoleをGalaxyからダウンロード。
  2. Lint: 構文チェック(yaml-lint, ansible-lint)を実行。
  3. Create: テスト用の環境(DockerコンテナやVagrant VMなど)を作成。
  4. Converge: 作成した環境に対してPlaybookを実行。
  5. Idempotence: もう一度Playbookを実行し、変更(Changed)がないか確認(冪等性チェック)。
  6. Verify: サーバーの状態(ポートが開いているか、ファイルがあるか等)を検証。
  7. Destroy: テスト環境を削除。

これを手動でやろうとすると大変ですが、Moleculeなら一瞬です。

なぜDockerを使うのか?

VM(仮想マシン)を立ち上げるのは時間がかかりますが、Dockerコンテナなら数秒で起動します。
Systemdが使えるコンテナイメージを利用することで、本物のサーバーに近い環境で高速にテストを回すことができます。


第2章:テスト環境の構築 (Docker + Molecule)

まずは、コントロールノード(あなたのPCや開発サーバー)に環境を作ります。
ここではPythonとDockerがインストールされている前提で進めます。

1. 必要なパッケージのインストール

Molecule本体と、Dockerを操作するためのドライバをインストールします。

pip install molecule molecule-docker docker ansible-lint
  • molecule: 本体
  • molecule-docker: Dockerドライバ
  • docker: Python用のDocker SDK
  • ansible-lint: 構文チェッカー

2. Dockerの動作確認

Dockerが動いており、sudoなしで実行できることを確認してください。

docker ps
# エラーが出なければOK

第3章:【実践】既存Roleへのテスト追加

ゼロからRoleを作る場合は molecule init role my_role を使いますが、今回は「すでにあるRole」にテスト環境を追加する手順を紹介します。
実務ではこちらの方が圧倒的に多いはずです。

1. シナリオの初期化

テストしたいRoleのディレクトリ(例: roles/apache)に移動し、以下のコマンドを実行します。

cd roles/apache
molecule init scenario --driver-name docker

すると、Roleの中に molecule/default/ というディレクトリが生成されます。
これがテストの設定ファイル群です。

roles/apache/
├── molecule/
│   └── default/
│       ├── molecule.yml    # 全体の設定
│       ├── converge.yml    # テスト実行用Playbook
│       └── verify.yml      # 検証コード
├── tasks/
│   └── main.yml
...

2. molecule.yml の設定(コンテナ定義)

どのようなコンテナを立ち上げるかを定義します。
今回はSystemdが使える AlmaLinux 9 のイメージを指定します。

molecule/default/molecule.yml を編集します。

---
dependency:
  name: galaxy
driver:
  name: docker
platforms:
  - name: instance
    image: geerlingguy/docker-almalinux9-ansible
    # Systemdを動かすための特権設定
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:rw
    cgroupns_mode: host
    privileged: true
    pre_build_image: true
provisioner:
  name: ansible
verifier:
  name: ansible

ポイント: Jeff Geerling氏(Ansible界の有名人)が公開している geerlingguy/docker-almalinux9-ansible イメージを使うと、コンテナ内でSystemdが使えるため、service モジュールのテストが容易になります。

3. converge.yml の確認

これは「テスト時に実行されるPlaybook」です。
デフォルトでは「対象のRoleをインクルードする」だけになっています。通常はそのままでOKです。

---
- name: Converge
  hosts: all
  tasks:
    - name: "Include apache"
      include_role:
        name: "apache"

第4章:テストの実行と検証コードの記述

準備ができたら、一度動かしてみましょう。

1. コンテナ作成とPlaybook実行 (converge)

いきなり test コマンドを叩くと、成功時にコンテナが消えてしまいデバッグできません。
まずは converge で「作成〜実行」までを行います。

molecule converge

Dockerイメージのプル、コンテナ起動、そしてRoleの実行が行われます。
エラーが出なければ、コンテナ内でApacheのインストール等が完了しているはずです。

2. コンテナへのログイン

起動中のテスト用コンテナに入って中身を確認できます。

molecule login

シェルに入ったら、systemctl status httpdcurl localhost などで動作確認ができます。
確認したら exit で抜けます。

3. 検証コードの記述 (verify.yml)

手動確認でOKなら、その確認作業を自動化しましょう。
以前は Testinfra というPythonライブラリを使うのが主流でしたが、現在はAnsible自体で検証を行う Ansible Verifier が推奨されています。
学習コストが低く、Ansibleのモジュール知識がそのまま使えるのがメリットです。

molecule/default/verify.yml を編集します。

---
- name: Verify
  hosts: all
  gather_facts: false
  tasks:
    - name: Check if httpd is running
      ansible.builtin.service_facts:

    - name: Assert httpd state
      ansible.builtin.assert:
        that:
          - ansible_facts.services['httpd.service'].state == 'running'
          - ansible_facts.services['httpd.service'].status == 'enabled'

    - name: Check HTTP response
      ansible.builtin.uri:
        url: http://localhost
        return_content: yes
      register: webpage

    - name: Assert content
      ansible.builtin.assert:
        that:
          - "'Hello Ansible' in webpage.content"

ここでは service_facts モジュールでサービスの状態を取得し、assert モジュールで期待値と比較しています。
また、uri モジュールで実際にアクセスしてコンテンツをチェックしています。

4. 検証の実行 (verify)

検証コードだけを実行します。

molecule verify

すべて緑色(OK)になれば、テスト合格です!

5. フルテスト (test)

最後に、破棄から再構築、冪等性チェックまで含めたフルコースを実行します。

molecule test

これが通れば、あなたのRoleは「品質保証済み」です。

💡 プロの視点:冪等性テストの重要性
Moleculeはデフォルトで Idempotence check を行います。
「2回実行して Changed が出たらテスト失敗」と判定されます。
これにより、「設定変更していないのに毎回再起動してしまう」といった品質の低いRoleを排除できます。
このチェックを通すことは、実務において非常に重要です。


第5章:CI/CDパイプラインへの統合 (GitHub Actions)

手元のPCでテストが通っても、チームメンバーがテストを実行するとは限りません。
コードをGitHubにプッシュしたら、クラウド上で勝手にテストが走るようにしましょう。

ワークフローファイルの作成

リポジトリの .github/workflows/molecule.yml を作成します。

name: Molecule Test

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.9", "3.10"]

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install dependencies
        run: |
          pip install molecule molecule-docker docker ansible-lint

      - name: Run Molecule tests
        run: molecule test
        env:
          ANSIBLE_FORCE_COLOR: '1'  # ログに色をつける

これだけで世界が変わる

このファイルをコミットしてプッシュすると、GitHubの「Actions」タブでテストが走り出します。
これ以降、誰かがバグを含んだコードをPR(プルリクエスト)しようとしても、テストが失敗して「×」が付くため、マージを阻止できます。

これが「品質をシステムで担保する」ということです。


第6章:トラブルシューティングとTips

Molecule導入時によくある悩みと解決策です。

Q1. Systemdが動かない (Failed to get D-Bus connection)

原因: Dockerコンテナは通常Systemdを持っていません。
対策: molecule.ymlprivileged: true にし、/sys/fs/cgroup をマウントする必要があります(第3章の設定を参照)。また、イメージもSystemd対応のもの(geerlingguy製など)を使うのが近道です。

Q2. テストが遅い

原因: 毎回Dockerイメージをプルしていたり、依存パッケージのインストールに時間がかかっています。
対策:
1. GitHub Actionsのキャッシュを使って、pipのインストール時間を短縮する。
2. 必要なツールをあらかじめ入れたカスタムDockerイメージを作成し、それを使ってテストする。

Q3. 特定のタスクだけ冪等性チェックで失敗する

原因: command モジュールなどで、常にChangedになってしまうタスクがある。
対策: changed_when を適切に設定するか、テスト時だけスキップするタグ(molecule-notestなど)を付けて回避します。


まとめ:自信を持ってデプロイするために

お疲れ様でした!
これで、あなたのAnsibleコードは「いつ誰が実行しても動くことが保証された」堅牢な資産となりました。

今回の重要ポイント:

  • Moleculeを使えば、コンテナを使ってRoleの単体テストができる。
  • verify.yml でインフラの状態をアサーション(検証)する。
  • GitHub Actionsと連携して、プルリクエストのたびにテストを回す。
  • 冪等性テスト(Idempotence)は品質保証の要。

「テストコードを書く時間がない」と言う人がいますが、手動で何度も確認したり、障害対応に追われたりする時間に比べれば、テストを書く時間は微々たるものです。
自動テストは、未来のあなたとチームを守る最強の盾になります。

さて、ここまではLinuxサーバーの話が中心でしたが、企業のインフラには「Windowsサーバー」も存在します。
「AnsibleってLinux専用でしょ?」と思っていませんか? 実はWindowsもバリバリ管理できるんです。

次回、応用講座 第6回は「Windowsも支配する。WinRM接続とPowerShell操作の完全ガイド」です。
SSHではなく WinRM を使った接続方法、Windows特有のモジュール、そしてPowerShellスクリプトとの連携など、Windows管理者のためのAnsible術を伝授します。
Active Directory環境の自動化などに興味がある方は必見です。お楽しみに!

▼ テスト駆動開発(TDD)を始める ▼

Docker環境で実験
「VPS」で自分専用環境

おすすめVPSを見る

品質保証のプロへ
「ITエンジニア転職」

転職エージェントを見る

コメント