CLOVER🍀

That was when it all began.

Moleculeで使うインスタンスを、Vagrantで管理する

これは、なにをしたくて書いたもの?

MoleculeでAnsibleのRoleをテストする時のDriverとして、Dockerではなく仮想マシン…というかVagrantが使えそうだったので
1度試してみることにしました。

まあ、いろいろありそうなのですが…。

Molecule Vagrant Driver

ドキュメントを見ると、以下のようにVagrant用のDriverが存在することが確認できます。

Configuration / Vagrant

すぐ近くにいろいろ注意書きがあります。

This driver is alpha quality software. Do not perform any additonal tasks inside the create playbook. Molecule does not know about the Vagrant instances’ configuration until the converge playbook is executed.

α品質だよとか、改善が必要な箇所があるとか書いてあるのですが…。

他にも書いておくことがあるのですが、それは最後にします。

まずは、動かしてみましょう。

環境

今回の環境は、こちらです。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:    18.04
Codename:   bionic


$ vagrant version
Installed Version: 2.2.6
Latest Version: 2.2.6


$ vagrant plugin list
vagrant-libvirt (0.0.45, global)


$ python3 -V
Python 3.6.9

Ubuntu Linux 18.04 LTSで、Vagrantは2.2.6、VagrantのProviderにはlibvirtを使います。

Molecure、Vagrant Driverのインストール

では、Moleculeと、Vagrant用のDriverをインストールします。

$ pip3 install molecule
$ pip3 install molecule[vagrant]

バージョンは、こちらです。

$ pip3 freeze | grep -E 'ansible|molecule|vagrant'
ansible==2.9.3
ansible-lint==4.2.0
molecule==2.22
python-vagrant==0.5.15

RoleとMolecule関連ファイルの作成、動作確認まで

「molecule init role」で、Roleを作成しましょう。お題としては、Apacheをインストールしてsystemdを使って起動するRoleとします。

$ molecule init role -r apache --driver-name vagrant

この時に、「--driver-name」で「vagrant」を指定します。

作成されたRoleのディレクトリ内に移動します。

$ cd apache

作成されたファイルを見てみましょう。

$ find -type f
./handlers/main.yml
./README.md
./vars/main.yml
./meta/main.yml
./defaults/main.yml
./tasks/main.yml
./molecule/default/prepare.yml
./molecule/default/playbook.yml
./molecule/default/tests/__pycache__/test_default.cpython-36.pyc
./molecule/default/tests/test_default.py
./molecule/default/molecule.yml
./molecule/default/INSTALL.rst
./.yamllint

Docker Driverの時と、ちょっと構成が違います。

Ansible Roleを開発、テストするためのMoleculeを試す - CLOVER🍀

「prepare.yml」というファイルがあるので、中身を見てみます。
molecule/default/prepare.yml

---
- name: Prepare
  hosts: all
  gather_facts: false
  tasks:
    - name: Install python for Ansible
      raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
      become: true
      changed_when: false

Pythonをインストールするようですね。

「molecule.yml」を見ると、Driverの指定がVagrantになっています。
molecule/default/molecule.yml

---
dependency:
  name: galaxy
driver:
  name: vagrant
  provider:
    name: virtualbox
lint:
  name: yamllint
platforms:
  - name: instance
    box: ubuntu/xenial64
provisioner:
  name: ansible
  lint:
    name: ansible-lint
verifier:
  name: testinfra
  lint:
    name: flake8

Playbookは、ふつうです。
molecule/default/playbook.yml

---
- name: Converge
  hosts: all
  roles:
    - role: apache

ここからは、今回やりたいことに合わせてファイルを修正していきます。

「molecule.yml」では、まずVagrantのProviderをlibvirtにします。

driver:
  name: vagrant
  provider:
    name: libvirt

VagrantのBoxは、「generic/ubuntu1804」とします。

platforms:
  - name: instance
    box: generic/ubuntu1804

この状態で、「molecule create」。

$ molecule create

インスタンスを見てみます。

$ molecule list
--> Validating schema /path/to/apache/molecule/default/molecule.yml.
Validation completed successfully.
Instance Name    Driver Name    Provisioner Name    Scenario Name    Created    Converged
---------------  -------------  ------------------  ---------------  ---------  -----------
instance         vagrant        ansible             default          true       false

もちろん、「molecule login」で起動したインスタンスにログインすることができます。

$ molecule login
--> Validating schema /path/to/apache/molecule/default/molecule.yml.
Validation completed successfully.
Warning: Permanently added '192.168.121.7' (ECDSA) to the list of known hosts.
Last login: Mon Jan 20 14:48:59 2020 from 192.168.121.1

確認できたら、1度、インスタンスから出ます。

次に、Roleを作成しましょう。せっかく仮想マシンを使うので、aptでApacheをインストールするだけでなく、systemctlを使って
Apacheを起動させます。 tasks/main.yml

---
- name: install apache2
  become: yes
  apt:
    name: apache2
    state: present
- name: start apache2
  become: yes
  systemd:
    state: started
    name: apache2

「molecule converge」を実行。

$ molecule converge

完了後、インスタンスにログインすると、Apacheが動作していることが確認できます。

$ molecule login


$ curl -I localhost
HTTP/1.1 200 OK
Date: Mon, 20 Jan 2020 14:54:08 GMT
Server: Apache/2.4.29 (Ubuntu)
Last-Modified: Mon, 20 Jan 2020 14:53:18 GMT
ETag: "2aa6-59c9373ab6eac"
Accept-Ranges: bytes
Content-Length: 10918
Vary: Accept-Encoding
Content-Type: text/html

テストもしてみましょう。
molecule/default/tests/test_default.py

import os

import testinfra.utils.ansible_runner

testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
    os.environ['MOLECULE_INVENTORY_FILE']
).get_hosts('all')


def test_apache_is_installed(host):
    apache2 = host.package('apache2')
    assert apache2.is_installed


def test_apache_is_running_and_enabled(host):
    apache2 = host.service('apache2')
    assert apache2.is_running
    assert apache2.is_enabled

Apacheがインストールされていることと、サービスが実行・有効化されていることを確認します。

「molecule verify」でテスト実行。

$ molecule verify
--> Scenario: 'default'
--> Action: 'verify'
--> Executing Testinfra tests found in /path/to/apache/molecule/default/tests/...
    ============================= test session starts ==============================
    platform linux -- Python 3.6.9, pytest-5.3.3, py-1.8.1, pluggy-0.13.1
    rootdir: /path/to/apache/molecule/default
    plugins: testinfra-3.4.0
collected 2 items                                                              
    
    tests/test_default.py ..                                                 [100%]
    
    ============================== 2 passed in 5.92s ===============================

OKです。

インスタンスを破棄。

$ molecule destroy

最後に、ここまでまとめて「molecule test」で確認します。自動生成された状態の「meta/main.yml」は、LintでNGになるので修正
しておいてください。

$ molecule test

インスタンスの作成からPlaybookの実行、インスタンスの破棄までが確認できます。

Vagrant Driverはなくなる?

Vagrant Driver、それからドキュメントに記載のある、Molecule Vagrant Moduleあたりが気になっていろいろ見ていると、こんな
情報を見つけました。

plugins: externalize vagrant driver · Issue #2315 · ansible/molecule · GitHub

Removed migration and vagrant driver by ssbarnea · Pull Request #2414 · ansible/molecule · GitHub

vagrant rpms are not published in a repository · Issue #11070 · hashicorp/vagrant · GitHub

どうやら、Vagrant DriverはMoleculeからいなくなりそうですね。yum/dnfリポジトリがないから、メンテナンスが大変だということ
みたいです。

リポジトリのIssueを見ても、メンテナンスしてくれる人を探している感じです。

GitHub - ansible-community/molecule-vagrant: Molecule Vagrant Driver

looking for maintainers · Issue #2 · ansible-community/molecule-vagrant · GitHub

ローカルで、コンテナではなく仮想マシンを使いたい場合はどうするんでしょうね?libvirtになるのでしょうか?

GitHub - ansible-community/molecule-libvirt: Molecule LibVirt Provider

とりあえず、直近は(なくなる想定であっても)Vagrantかなぁと思います。