👋
ansible + moleculeの環境構築
目的
ansible + moleculeが動くまでの最低限の環境を作成する手順を記載する
2025/08時点で検索で出てくるのは古い記事ばかりで手間取ったり、最小の構成でやりたかったので記事にした
最終目標としては、ansible + molecule + dockerで複数のUbuntuでテストをできるのを最終目的とするが、今回の記事は環境構築と最小限の動作確認まで
ansibleのインストール
参考文献:
pythonのバージョンの確認
python3 -m pip -V
pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)
なかったら、pythonをインストール
ansibleのインストール
python3 -m pip install --user ansible
ansibleのバージョンの確認
ansible --version
mozyanari@mozyanari-desktop:~$ ansible --version
ansible [core 2.17.13]
config file = None
configured module search path = ['/home/mozyanari/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/mozyanari/.local/lib/python3.10/site-packages/ansible
ansible collection location = /home/mozyanari/.ansible/collections:/usr/share/ansible/collections
executable location = /home/mozyanari/.local/bin/ansible
python version = 3.10.12 (main, May 27 2025, 17:12:29) [GCC 11.4.0] (/usr/bin/python3)
jinja version = 3.1.6
libyaml = True
ansible collection locationについて
moleculeでansible collection locationはmoleculeでroleを探すときのパスになっているので、実はここの下にroleを作るのが一番簡単だが、「.ansible」の下にgit cloneするのはあまりないので、自分でroleを認識するパスは指定する
moleculeのインストール
参考文献
$ python3 -m pip install --user molecule
mozyanari@mozyanari-desktop:~$ molecule --version
molecule 25.7.0 using python 3.10
ansible:2.17.13
default:25.7.0 from molecule
Dockerのインストール
参考文献
mozyanari@mozyanari-desktop:~$ docker -v
Docker version 27.4.1, build b9d17ea
Dockerでpythonで使うためのライブラリ
pip install --user docker
moleculeのプラグインをインストール
pip install molecule-plugins
ansible + moleculeのフレームワークでテストが動くかをチェック
taskの雛形を作成
mkdir molecule-test
ansible-galaxy init test_role
testsフォルダがありますがmoleculeのフレームワークを使いたいので、このtestsフォルダは使いません
検索したときに出てきたがエラーが出たコマンド
mozyanari@mozyanari-desktop:~/molecule-test/test_role$ ansible-galaxy init role apt_install --driver-name docker
usage: ansible-galaxy [-h] [--version] [-v] TYPE ...
ansible-galaxy: error: argument TYPE: invalid choice: 'init' (choose from 'collection', 'role')
...
mozyanari@mozyanari-desktop:~/molecule-test/test_role$ molecule init role a
Usage: molecule init [OPTIONS] COMMAND [ARGS]...
Try 'molecule init -h' for help.
Error: No such command 'role'.
moleculeのテストの雛形を作成
cd test_role
molecule init scenario --driver-name docker
meta/main.ymlを修正
galaxy_info:
author: your name
description: your role description
company: your company (optional)
role_name: test_role ←追加
namespace: localhost ←追加
role_nameは作成したroleの名前(今回はtest_role)
namespaceはlocalhostに仮に設定した
これって自動で追加出来ないのか?
テストを動くか試す
cd ~/molecule-test/test_role
molecule test
下記の実行結果のようにデフォルで入っているテストを実行出来た
実行結果
mozyanari@mozyanari-desktop:~/molecule-test/test_role$ molecule test
WARNING Driver docker does not provide a schema.
WARNING Driver docker does not provide a schema.
INFO default ➜ discovery: scenario test matrix: dependency, cleanup, destroy, syntax, create, prepare, converge, idempotence, side_effect, verify, cleanup, destroy
INFO default ➜ prerun: Performing prerun with role_name_check=0...
INFO default ➜ dependency: Starting
WARNING default ➜ dependency: Skipping, missing the requirements file.
WARNING default ➜ dependency: Skipping, missing the requirements file.
INFO default ➜ dependency: Completed
INFO default ➜ cleanup: Starting
WARNING default ➜ cleanup: Skipping, cleanup playbook not configured.
INFO default ➜ cleanup: Completed
INFO default ➜ destroy: Starting
INFO default ➜ destroy: ansible-playbook version: ansible-playbook
config file = None
configured module search path = ['/home/mozyanari/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/mozyanari/.local/lib/python3.10/site-packages/ansible
ansible collection location = /home/mozyanari/.ansible/collections:/usr/share/ansible/collections
executable location = /home/mozyanari/.local/bin/ansible-playbook
python version = 3.10.12 (main, May 27 2025, 17:12:29) (/usr/bin/python3)
jinja version = 3.1.6
libyaml = True
INFO Sanity checks: 'docker'
PLAY [Destroy] *****************************************************************
TASK [Set async_dir for HOME env] **********************************************
ok: [localhost]
TASK [Destroy molecule instance(s)] ********************************************
changed: [localhost] => (item=instance)
TASK [Wait for instance(s) deletion to complete] *******************************
FAILED - RETRYING: [localhost]: Wait for instance(s) deletion to complete (300 retries left).
ok: [localhost] => (item=instance)
TASK [Delete docker networks(s)] ***********************************************
skipping: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
INFO default ➜ destroy: Completed
INFO default ➜ syntax: Starting
INFO default ➜ syntax: ansible-playbook version: ansible-playbook
config file = None
configured module search path = ['/home/mozyanari/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/mozyanari/.local/lib/python3.10/site-packages/ansible
ansible collection location = /home/mozyanari/.ansible/collections:/usr/share/ansible/collections
executable location = /home/mozyanari/.local/bin/ansible-playbook
python version = 3.10.12 (main, May 27 2025, 17:12:29) (/usr/bin/python3)
jinja version = 3.1.6
libyaml = True
playbook: /home/mozyanari/molecule-test/test_role/molecule/default/converge.yml
INFO default ➜ syntax: Completed
INFO default ➜ create: Starting
INFO default ➜ create: ansible-playbook version: ansible-playbook
config file = None# 環境
Ubuntu
configured module search path = ['/home/mozyanari/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/mozyanari/.local/lib/python3.10/site-packages/ansible
ansible collection location = /home/mozyanari/.ansible/collections:/usr/share/ansible/collections
executable location = /home/mozyanari/.local/bin/ansible-playbook
python version = 3.10.12 (main, May 27 2025, 17:12:29) (/usr/bin/python3)
jinja version = 3.1.6
libyaml = True
PLAY [Create] ******************************************************************
TASK [Set async_dir for HOME env] **********************************************
ok: [localhost]
TASK [Log into a Docker registry] **********************************************
skipping: [localhost] => (item=None)
skipping: [localhost]
TASK [Check presence of custom Dockerfiles] ************************************
ok: [localhost] => (item=instance)
TASK [Create Dockerfiles from image names] *************************************
skipping: [localhost] => (item=instance)
skipping: [localhost]
TASK [Synchronization the context] *********************************************
skipping: [localhost] => (item=instance)
skipping: [localhost]
TASK [Discover local Docker images] ********************************************
ok: [localhost] => (item=unix://var/run/docker.sock)
TASK [Create docker network(s)] ************************************************
skipping: [localhost]
TASK [Build an Ansible compatible image (new)] *********************************
skipping: [localhost] => (item=molecule_local/quay.io/centos/centos:stream8)
skipping: [localhost]
TASK [Determine the CMD directives] ********************************************
ok: [localhost] => (item=instance)
TASK [Create molecule ins簡単な構成管理のコードを作成tance(s)] *********************************************
changed: [localhost] => (item=instance)
TASK [Wait for instance(s) creation to complete] *******************************
FAILED - RETRYING: [localhost]: Wait for instance(s) creation to complete (300 retries left).
FAILED - RETRYING: [localhost]: Wait for instance(s) creation to complete (299 retries left).
FAILED - RETRYING: [localhost]: Wait for instance(s) creation to complete (298 retries left).
changed: [localhost] => (item=instance)
PLAY RECAP *********************************************************************
localhost : ok=6 changed=2 unreachable=0 failed=0 skipped=5 rescued=0 ignored=0
INFO default ➜ create: Completed
INFO default ➜ prepare: Starting
WARNING default ➜ prepare: Skipping, prepare playbook not configured.
INFO default ➜ prepare: Completed
INFO default ➜ converge: Starting
INFO default ➜ converge: ansible-playbook version: ansible-playbook
config file = None
configured module search path = ['/home/mozyanari/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/mozyanari/.local/lib/python3.10/site-packages/ansible
ansible collection location = /home/mozyanari/.ansible/collections:/usr/share/ansible/collections
executable location = /home/mozyanari/.local/bin/ansible-playbook
python version = 3.10.12 (main, May 27 2025, 17:12:29) (/usr/bin/python3)
jinja version = 3.1.6
libyaml = True
PLAY [Converge] ****************************************************************
TASK [Replace this task with one that validates your content] ******************
ok: [instance] => {
"msg": "This is the effective test"
}
PLAY RECAP *********************************************************************
instance : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
INFO default ➜ converge: Completed
INFO default ➜ idempotence: Starting
INFO default ➜ idempotence: ansible-playbook version: ansible-playbook
config file = None
configured module search path = ['/home/mozyanari/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/mozyanari/.local/lib/python3.10/site-packages/ansible
ansible collection location = /home/mozyanari/.ansible/collections:/usr/share/ansible/collections
executable location = /home/mozyanari/.local/bin/ansible-playbook
python version = 3.10.12 (main, May 27 2025, 17:12:29) (/usr/bin/python3)
jinja version = 3.1.6
libyaml = True
PLAY [Converge] ****************************************************************
TASK [Replace this task with one that validates your content] ******************
ok: [instance] => {
"msg": "This is the effective test"
}
PLAY RECAP *********************************************************************
instance : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
INFO default ➜ idempotence: Idempotence completed successfully.
INFO default ➜ idempotence: Completed
INFO default ➜ side_effect: Starting
WARNING default ➜ sideeffect: Skipping, side effect playbook not configured.
INFO default ➜ side_effect: Completed
INFO default ➜ verify: Starting
INFO default ➜ verify: Running Ansible Verifier
WARNING default ➜ verify: Skipping, verify playbook not configured.
INFO default ➜ verify: Verifier completed successfully.
INFO default ➜ verify: Completed
INFO default ➜ cleanup: Starting
WARNING default ➜ cleanup: Skipping, cleanup playbook not configured.
INFO default ➜ cleanup: Completed
INFO default ➜ destroy: Starting
INFO default ➜ destroy: ansible-playbook version: ansible-playbook
config file = None
configured module search path = ['/home/mozyanari/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/mozyanari/.local/lib/python3.10/site-packages/ansible
ansible collection location = /home/mozyanari/.ansible/collections:/usr/share/ansible/collections
executable location = /home/mozyanari/.local/bin/ansible-playbook
python version = 3.10.12 (main, May 27 2025, 17:12:29) (/usr/bin/python3)
jinja version = 3.1.6
libyaml = True
PLAY [Destroy] *****************************************************************
TASK [Set async_dir for HOME env] **********************************************
ok: [localhost]
TASK [Destroy molecule instance(s)] ********************************************
changed: [localhost] => (item=instance)
TASK [Wait for instance(s) deletion to complete] *******************************
FAILED - RETRYING: [localhost]: Wait for instance(s) deletion to complete (300 retries left).
changed: [localhost] => (item=instance)
TASK [Delete docker networks(s)] ***********************************************
skipping: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
INFO default ➜ destroy: Completed
INFO default ➜ scenario: Pruning extra files from scenario ephemeral directory
まとめ
今回の手順でmoleculeが最低限動くことが確認出来た
フォルダ構成は下記のようになった
mozyanari@mozyanari-desktop:~/molecule-test$ tree -L 4
.
└── test_role
├── README.md
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── molecule
│ └── default
│ ├── converge.yml
│ ├── molecule.yml
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
Discussion