Moleculeを使用して、Redis-Clusterを構築するplaybookのテストを行う
Molecule はAnsible のロールの開発とテストを支援するように設計されているAnsible のテストツールです。
Molecule を使用することで、Docker のコンテナに対してAnsible のロールを実行し、playbook の検証を行うことが可能です。
「なるほど、分からん」という方は、下記をご一読いただければと思います。
今回は以前に作成したplaybook をカスタマイズして、Molecule を使い方を外部記憶として残そうと思います。
前提条件
- Ansible はインストール済みであるとする
- config、inventory の設定は完了済みであるとする
- 鍵生成、鍵交換、疎通確認は完了済みであるとする
- proxy 環境下ではないものとする
- 一つのサーバーにRedis のMaster とSlave を配置する
実行環境
# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
# ansible --version
ansible 2.9.1
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /bin/ansible
python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
構成図のイメージ
構成図は下記のようになります。docker のコンテナはmolecule コマンドで生成します。
Molecule のインストール
下記の手順でMolecule をインストールします。
# yum install -y epel-release
# yum install -y gcc python-pip python-devel openssl-devel libselinux-python
# yum install -y docker ※ 既にdokcer をインストール済みである場合、本手順は飛ばしてください
# pip install -U pip
# pip install -U setuptools
# pip install molecule docker-py pyparsing PyYAML
Molecule のインストールが完了したので、Molecule のバージョンを確認しましょう。
# molecule --version
molecule, version 2.22
個人的にハマったポイント
Molecule を使用する際は、docker か docker-py のどちらかを使用したほうがよいです。両方ともインストールされている場合はいったん、アンインストールしてから、どちらかを再インストールしましょう。今回はdocker-py を使用します。
# pip uninstall docker
# pip uninstall docker-py
# pip install docker-py
今回のテスト対象となるplaybook について
今回テスト対象となるplaybook は、以前作成したRedis-Cluster を構築するplaybook となります。
下記のようなディレクトリ構成を作成し、上記のリンク先のplaybook の内容をロールとして切り出しします。
# tree -r /etc/ansible/roles/
/etc/ansible/roles/
├── redis-cluster
│ ├── start_redis_server
│ │ └── tasks
│ │ └── main.yml
│ ├── setup_redis_conf
│ │ └── tasks
│ │ └── main.yml
│ ├── install_redis
│ │ └── tasks
│ │ └── main.yml
│ ├── create_redis_user
│ │ └── tasks
│ │ └── main.yml
│ ├── create_redis_group
│ │ └── tasks
│ │ └── main.yml
│ ├── create_redis_config_directories
│ │ └── tasks
│ │ └── main.yml
│ └── copy_redis_conf
│ └── tasks
│ └── main.yml
└── common
└── install_list_of_packages
└── tasks
└── main.yml
それに合わせて、下記のようなロールを使用したplaybook を作成します。
- name: deploy Redis-Cluster
hosts: localhost
vars:
ansible_become: yes
install_list_of_packages:
- epel-release
- http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
redis_port_number:
- 7000
- 7001
- 7002
- 7003
- 7004
- 7005
roles:
- install_list_of_packages
- install_redis
- create_redis_group
- create_redis_user
- create_redis_config_directories
- copy_redis_conf
- setup_redis_conf
- start_redis_server
playbook で呼ばれるロールの確認ついでに、ansible-lint を使用して静的解析を行います。
# cd /etc/ansible/playbook
# ansible-lint deploy_redis_cluster.yml -v
Examining deploy_redis_cluster.yml of type playbook
Examining ../roles/common/install_list_of_packages/tasks/main.yml of type tasks
Examining ../roles/redis-cluster/install_redis/tasks/main.yml of type tasks
Examining ../roles/redis-cluster/create_redis_group/tasks/main.yml of type tasks
Examining ../roles/redis-cluster/create_redis_user/tasks/main.yml of type tasks
Examining ../roles/redis-cluster/create_redis_config_directories/tasks/main.yml of type tasks
Examining ../roles/redis-cluster/copy_redis_conf/tasks/main.yml of type tasks
Examining ../roles/redis-cluster/setup_redis_conf/tasks/main.yml of type tasks
Examining ../roles/redis-cluster/start_redis_server/tasks/main.yml of type tasks
[301] Commands should not change things if nothing needs doing
../roles/redis-cluster/start_redis_server/tasks/main.yml:2
Task/Handler: Start Redis-Server
Molecule によるテストの前準備
molecule init の実行
下記のコマンドを実行し、molecule ディレクトリを生成します。
# cd /etc/ansible/roles/redis-cluster
# molecule init scenario -r redis-cluster
--> Initializing new scenario default...
Initialized scenario in /etc/ansible/roles/redis-cluster/molecule/default successfully.
# ll | grep molecule
drwxr-xr-x 3 root root 21 2月 12 22:43 molecule
Molecule のディレクトリ構成の確認
下記のコマンドを実行し、molecule ディレクトリ構成を確認します。
# tree -r molecule/
molecule/
└── default
├── tests
│ ├── test_default.py
│ └── __pycache__
│ └── test_default.cpython-36.pyc
├── playbook.yml
├── molecule.yml
├── INSTALL.rst
└── Dockerfile.j2
各ファイルの設定
Molecule を実行するために、下記3つのファイルを設定します。
molecule/
└── default
├── playbook.yml # 検証するplaybook の内容
├── molecule.yml # molecule を実行する際の設定ファイル
└── Dockerfile.j2 # playbook の検証対象となるコンテナ起動に使用するdocker イメージの設定ファイル
- molecule/default/Dockerfile.j2
# Molecule managed
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
{% if item.env is defined %}
{% for var, value in item.env.items() %}
{% if value %}
ENV {{ var }} {{ value }}
{% endif %}
{% endfor %}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi
CMD ["/sbin/init"]
- molecule/default/molecule.yml
---
dependency:
name: galaxy
driver:
name: docker
lint:
name: yamllint
platforms:
- name: redis-cluster-instance # コンテナの名前
image: centos:7 # 使用するイメージ
pull: False
command: /sbin/init # systemd を必要とする場合に必要なオプション
tmps: # systemd を必要とする場合に必要なオプション
- /run # systemd を必要とする場合に必要なオプション
- /tmp # systemd を必要とする場合に必要なオプション
volumes: # systemd を必要とする場合に必要なオプション
- /sys/fs/cgroup:/sys/fs/cgroup:ro # systemd を必要とする場合に必要なオプション
provisioner:
name: ansible
log: true
config_options:
defaults:
stdout_callback: yaml
bin_ansible_callbacks: true
lint:
name: ansible-lint
verifier:
name: testinfra
lint:
name: flake8
- molecule/default/playbook.yml
---
- name: Converge
hosts: all
vars:
ansible_become: yes
install_list_of_packages:
- epel-release
- http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
redis_port_number:
- 7000
- 7001
- 7002
- 7003
- 7004
- 7005
roles:
- ../roles/common/install_list_of_packages
- ../roles/redis-cluster/install_redis
- ../roles/redis-cluster/create_redis_group
- ../roles/redis-cluster/create_redis_user
- ../roles/redis-cluster/create_redis_config_directories
- ../roles/redis-cluster/copy_redis_conf
- ../roles/redis-cluster/setup_redis_conf
- ../roles/redis-cluster/start_redis_server
Molecule で使用するテスト用の環境を作成
下記のコマンドを実行し、Molecule で使用するテスト用のdocker コンテナを作成します。
# molecule create
--> Validating schema /etc/ansible/roles/redis-cluster/molecule/default/molecule.yml.
Validation completed successfully.
--> Test matrix
└── default
├── dependency
├── create
└── prepare
--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'create'
--> Sanity checks: 'docker'
PLAY [Create] ******************************************************************
TASK [Log into a Docker registry] **********************************************
skipping: [localhost] => (item={'pull': False, 'command': u'/sbin/init', 'name': u'redis-cluster-instance', 'volumes': [u'/sys/fs/cgroup:/sys/fs/cgroup:ro'], 'image': u'centos:7', 'tmps': [u'/run', u'/tmp']})
TASK [Create Dockerfiles from image names] *************************************
changed: [localhost] => (item={'pull': False, 'command': u'/sbin/init', 'name': u'redis-cluster-instance', 'volumes': [u'/sys/fs/cgroup:/sys/fs/cgroup:ro'], 'image': u'centos:7', 'tmps': [u'/run', u'/tmp']})
TASK [Determine which docker image info module to use] *************************
ok: [localhost]
TASK [Discover local Docker images] ********************************************
ok: [localhost] => (item={u'changed': True, u'uid': 0, u'dest': u'/root/.cache/molecule/redis-cluster/default/Dockerfile_centos_7', u'owner': u'root', 'diff': [], u'size': 914, u'src': u'/root/.ansible/tmp/ansible-tmp-1581521805.53-277333827862458/source', 'ansible_loop_var': u'item', u'group': u'root', 'item': {'pull': False, 'command': u'/sbin/init', 'name': u'redis-cluster-instance', 'volumes': [u'/sys/fs/cgroup:/sys/fs/cgroup:ro'], 'image': u'centos:7', 'tmps': [u'/run', u'/tmp']}, u'checksum': u'af0854dd479325baac9797c25a580b67bf4faa0e', u'md5sum': u'89ab4f11c078a9f793fa4f94a495193d', 'failed': False, u'state': u'file', u'gid': 0, u'mode': u'0644', u'invocation': {u'module_args': {u'directory_mode': None, u'force': True, u'remote_src': None, u'dest': u'/root/.cache/molecule/redis-cluster/default/Dockerfile_centos_7', u'selevel': None, u'_original_basename': u'Dockerfile.j2', u'delimiter': None, u'regexp': None, u'owner': None, u'follow': False, u'validate': None, u'local_follow': None, u'src': u'/root/.ansible/tmp/ansible-tmp-1581521805.53-277333827862458/source', u'group': None, u'unsafe_writes': None, u'checksum': u'af0854dd479325baac9797c25a580b67bf4faa0e', u'seuser': None, u'serole': None, u'content': None, u'setype': None, u'mode': None, u'attributes': None, u'backup': False}}})
TASK [Build an Ansible compatible image (new)] *********************************
ok: [localhost] => (item=molecule_local/centos:7)
TASK [Build an Ansible compatible image (old)] *********************************
skipping: [localhost] => (item=molecule_local/centos:7)
TASK [Create docker network(s)] ************************************************
TASK [Determine the CMD directives] ********************************************
ok: [localhost] => (item={'pull': False, 'command': u'/sbin/init', 'name': u'redis-cluster-instance', 'volumes': [u'/sys/fs/cgroup:/sys/fs/cgroup:ro'], 'image': u'centos:7', 'tmps': [u'/run', u'/tmp']})
TASK [Create molecule instance(s)] *********************************************
changed: [localhost] => (item=redis-cluster-instance)
TASK [Wait for instance(s) creation to complete] *******************************
FAILED - RETRYING: Wait for instance(s) creation to complete (300 retries left).
changed: [localhost] => (item={'ansible_loop_var': u'item', u'ansible_job_id': u'429823489509.31439', 'item': {'pull': False, 'command': u'/sbin/init', 'name': u'redis-cluster-instance', 'volumes': [u'/sys/fs/cgroup:/sys/fs/cgroup:ro'], 'image': u'centos:7', 'tmps': [u'/run', u'/tmp']}, u'started': 1, 'changed': True, 'failed': False, u'finished': 0, u'results_file': u'/root/.ansible_async/429823489509.31439'})
PLAY RECAP *********************************************************************
localhost : ok=7 changed=3 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
--> Scenario: 'default'
--> Action: 'prepare'
Skipping, prepare playbook not configured.
docker コンテナが生成されているかを確認します。
# docker ps -a | grep molecule
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76b96d17d540 molecule_local/centos:7 "/sbin/init" About a minute ago Up About a minute moleredis-cluster-instance
Molecule による静的解析
下記のコマンドを実行し、Molecule によるロールの静的解析を行います。
# molecule lint
--> Validating schema /etc/ansible/roles/redis-cluster/molecule/default/molecule.yml.
Validation completed successfully.
--> Test matrix
└── default
└── lint
--> Scenario: 'default'
--> Action: 'lint'
--> Executing Yamllint on files found in /etc/ansible/roles/redis-cluster/...
Lint completed successfully.
--> Executing Flake8 on files found in /etc/ansible/roles/redis-cluster/molecule/default/tests/...
Lint completed successfully.
--> Executing Ansible Lint on /etc/ansible/roles/redis-cluster/molecule/default/playbook.yml...
[301] Commands should not change things if nothing needs doing
start_redis_server/tasks/main.yml:2
Task/Handler: Start Redis-Server
molecule によるテストの実行
下記のコマンドを実行し、docker コンテナに対して、playbook の検証を行います。
# molecule converge
--> Validating schema /etc/ansible/roles/redis-cluster/molecule/default/molecule.yml.
Validation completed successfully.
--> Test matrix
└── default
├── dependency
├── create
├── prepare
└── converge
--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'create'
Skipping, instances already created.
--> Scenario: 'default'
--> Action: 'prepare'
Skipping, prepare playbook not configured.
--> Scenario: 'default'
--> Action: 'converge'
PLAY [Converge] ****************************************************************
TASK [Gathering Facts] *********************************************************
ok: [redis-cluster-instance]
TASK [../roles/common/install_list_of_packages : Install a list of packages] ***
changed: [redis-cluster-instance]
TASK [../roles/redis-cluster/install_redis : Install redis] ********************
changed: [redis-cluster-instance]
TASK [../roles/redis-cluster/create_redis_group : Ensure group "redis" exists] ***
ok: [redis-cluster-instance]
TASK [../roles/redis-cluster/create_redis_user : Create redis user] ************
changed: [redis-cluster-instance]
TASK [../roles/redis-cluster/create_redis_config_directories : mkdir redis config directory] ***
changed: [redis-cluster-instance] => (item=7000)
changed: [redis-cluster-instance] => (item=7001)
changed: [redis-cluster-instance] => (item=7002)
changed: [redis-cluster-instance] => (item=7003)
changed: [redis-cluster-instance] => (item=7004)
changed: [redis-cluster-instance] => (item=7005)
TASK [../roles/redis-cluster/copy_redis_conf : Copy redis.conf] ****************
changed: [redis-cluster-instance] => (item=7000)
changed: [redis-cluster-instance] => (item=7001)
changed: [redis-cluster-instance] => (item=7002)
changed: [redis-cluster-instance] => (item=7003)
changed: [redis-cluster-instance] => (item=7004)
changed: [redis-cluster-instance] => (item=7005)
TASK [../roles/redis-cluster/setup_redis_conf : Setting bind IPv4Address] ******
changed: [redis-cluster-instance] => (item=7000)
changed: [redis-cluster-instance] => (item=7001)
changed: [redis-cluster-instance] => (item=7002)
changed: [redis-cluster-instance] => (item=7003)
changed: [redis-cluster-instance] => (item=7004)
changed: [redis-cluster-instance] => (item=7005)
TASK [../roles/redis-cluster/setup_redis_conf : Setting port number] ***********
changed: [redis-cluster-instance] => (item=7000)
changed: [redis-cluster-instance] => (item=7001)
changed: [redis-cluster-instance] => (item=7002)
changed: [redis-cluster-instance] => (item=7003)
changed: [redis-cluster-instance] => (item=7004)
changed: [redis-cluster-instance] => (item=7005)
TASK [../roles/redis-cluster/setup_redis_conf : Setting cluster-enabled] *******
changed: [redis-cluster-instance] => (item=7000)
changed: [redis-cluster-instance] => (item=7001)
changed: [redis-cluster-instance] => (item=7002)
changed: [redis-cluster-instance] => (item=7003)
changed: [redis-cluster-instance] => (item=7004)
changed: [redis-cluster-instance] => (item=7005)
TASK [../roles/redis-cluster/setup_redis_conf : Setting cluster-config-file] ***
changed: [redis-cluster-instance] => (item=7000)
changed: [redis-cluster-instance] => (item=7001)
changed: [redis-cluster-instance] => (item=7002)
changed: [redis-cluster-instance] => (item=7003)
changed: [redis-cluster-instance] => (item=7004)
changed: [redis-cluster-instance] => (item=7005)
TASK [../roles/redis-cluster/setup_redis_conf : Setting cluster-node-timeout] ***
changed: [redis-cluster-instance] => (item=7000)
changed: [redis-cluster-instance] => (item=7001)
changed: [redis-cluster-instance] => (item=7002)
changed: [redis-cluster-instance] => (item=7003)
changed: [redis-cluster-instance] => (item=7004)
changed: [redis-cluster-instance] => (item=7005)
TASK [../roles/redis-cluster/setup_redis_conf : Setting appendonly] ************
changed: [redis-cluster-instance] => (item=7000)
changed: [redis-cluster-instance] => (item=7001)
changed: [redis-cluster-instance] => (item=7002)
changed: [redis-cluster-instance] => (item=7003)
changed: [redis-cluster-instance] => (item=7004)
changed: [redis-cluster-instance] => (item=7005)
TASK [../roles/redis-cluster/setup_redis_conf : Setting logfile] ***************
changed: [redis-cluster-instance] => (item=7000)
changed: [redis-cluster-instance] => (item=7001)
changed: [redis-cluster-instance] => (item=7002)
changed: [redis-cluster-instance] => (item=7003)
changed: [redis-cluster-instance] => (item=7004)
changed: [redis-cluster-instance] => (item=7005)
TASK [../roles/redis-cluster/start_redis_server : Start Redis-Server] **********
changed: [redis-cluster-instance] => (item=7000)
changed: [redis-cluster-instance] => (item=7001)
changed: [redis-cluster-instance] => (item=7002)
changed: [redis-cluster-instance] => (item=7003)
changed: [redis-cluster-instance] => (item=7004)
changed: [redis-cluster-instance] => (item=7005)
PLAY RECAP *********************************************************************
redis-cluster-instance : ok=15 changed=13 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
無事、playbook が完了いたしました。下記のコマンドを実行して、docker コンテナにログインしましょう。
# molecule login
--> Validating schema /etc/ansible/roles/redis-cluster/molecule/default/molecule.yml.
Validation completed successfully.
Redisのバージョン確認
docker コンテナにインストールされているRedis のバージョンを確認してみましょう。
[root@redis-cluster-instance /]# redis-cli --version
redis-cli 5.0.7
[root@redis-cluster-instance /]# redis-server --version
Redis server v=5.0.7 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=91145edf25c40cd7
Redis-Clusterの構築
それでは、docker コンテナで下記のコマンドを叩いて、Redis-Clusterを構築しましょう。
[root@redis-cluster-instance /]# redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:7004 to 127.0.0.1:7000
Adding replica 127.0.0.1:7005 to 127.0.0.1:7001
Adding replica 127.0.0.1:7003 to 127.0.0.1:7002
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 7bc5f80dd90213eeb3361571ea3dbbb3291e97d8 127.0.0.1:7000
slots:[0-5460] (5461 slots) master
M: d59fe4d92511e504ba5cf7f9001cb8ea7def6b7f 127.0.0.1:7001
slots:[5461-10922] (5462 slots) master
M: d53abfb685e3592a40affcc763a39036f3027103 127.0.0.1:7002
slots:[10923-16383] (5461 slots) master
S: 906638361f1c40cb349d0a4f507cadb497a7d02a 127.0.0.1:7003
replicates d53abfb685e3592a40affcc763a39036f3027103
S: ebb4b50135a4ea7c0ad5061cc169d1a14f760fb1 127.0.0.1:7004
replicates 7bc5f80dd90213eeb3361571ea3dbbb3291e97d8
S: 483c521c5a2b10d23f7335d57d960c274645f2b5 127.0.0.1:7005
replicates d59fe4d92511e504ba5cf7f9001cb8ea7def6b7f
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
..
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: 7bc5f80dd90213eeb3361571ea3dbbb3291e97d8 127.0.0.1:7000
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: d53abfb685e3592a40affcc763a39036f3027103 127.0.0.1:7002
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 483c521c5a2b10d23f7335d57d960c274645f2b5 127.0.0.1:7005
slots: (0 slots) slave
replicates d59fe4d92511e504ba5cf7f9001cb8ea7def6b7f
S: ebb4b50135a4ea7c0ad5061cc169d1a14f760fb1 127.0.0.1:7004
slots: (0 slots) slave
replicates 7bc5f80dd90213eeb3361571ea3dbbb3291e97d8
M: d59fe4d92511e504ba5cf7f9001cb8ea7def6b7f 127.0.0.1:7001
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 906638361f1c40cb349d0a4f507cadb497a7d02a 127.0.0.1:7003
slots: (0 slots) slave
replicates d53abfb685e3592a40affcc763a39036f3027103
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Redis-Clusterの状態確認
docker コンテナ内で構築したRedis-Cluster の状態を確認してみましょう。
[root@redis-cluster-instance /]# redis-cli -p 7000 cluster nodes
d53abfb685e3592a40affcc763a39036f3027103 127.0.0.1:7002@17002 master - 0 1581523028526 3 connected 10923-16383
483c521c5a2b10d23f7335d57d960c274645f2b5 127.0.0.1:7005@17005 slave d59fe4d92511e504ba5cf7f9001cb8ea7def6b7f 0 1581523028316 6 connected
ebb4b50135a4ea7c0ad5061cc169d1a14f760fb1 127.0.0.1:7004@17004 slave 7bc5f80dd90213eeb3361571ea3dbbb3291e97d8 0 1581523028113 5 connected
d59fe4d92511e504ba5cf7f9001cb8ea7def6b7f 127.0.0.1:7001@17001 master - 0 1581523026273 2 connected 5461-10922
906638361f1c40cb349d0a4f507cadb497a7d02a 127.0.0.1:7003@17003 slave d53abfb685e3592a40affcc763a39036f3027103 0 1581523028000 4 connected
7bc5f80dd90213eeb3361571ea3dbbb3291e97d8 127.0.0.1:7000@17000 myself,master - 0 1581523026000 1 connected 0-5460
Molecule で使用したテスト用の環境を削除
下記のコマンドを実行し、Molecule で使用したテスト用のdocker コンテナを削除します。
[root@redis-cluster-instance /]# exit
exit
# molecule destroy
--> Validating schema /etc/ansible/roles/redis-cluster/molecule/default/molecule.yml.
Validation completed successfully.
--> Test matrix
└── default
├── dependency
├── cleanup
└── destroy
--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'cleanup'
Skipping, cleanup playbook not configured.
--> Scenario: 'default'
--> Action: 'destroy'
PLAY [Destroy] *****************************************************************
TASK [Destroy molecule instance(s)] ********************************************
changed: [localhost] => (item=redis-cluster-instance)
TASK [Wait for instance(s) deletion to complete] *******************************
changed: [localhost] => (item={'ansible_loop_var': u'item', u'ansible_job_id': u'412030201772.27418', 'item': {'pull': False, 'command': u'/sbin/init', 'name': u'redis-cluster-instance', 'volumes': [u'/sys/fs/cgroup:/sys/fs/cgroup:ro'], 'image': u'centos:7', 'tmps': [u'/run', u'/tmp']}, u'started': 1, 'changed': True, 'failed': False, u'finished': 0, u'results_file': u'/root/.ansible_async/412030201772.27418'})
TASK [Delete docker network(s)] ************************************************
PLAY RECAP *********************************************************************
localhost : ok=2 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
--> Pruning extra files from scenario ephemeral directory
docker コンテナが削除されているかを確認します。
# docker ps -a | grep molecule
#
まとめ
Molecule を使用して、Redis-Cluster を構築するplaybook の静的解析・ロールのテストを行うことができました。
Molecule を使用して思ったことは、新規に作成したインスタンスやVM を汚さずに、playbook の試行錯誤ができるのが嬉しかったです。失敗したら、コンテナを削除・再作成することで、またまっさらな状態で検証できますからね。次は、GitLab Runner とMolecule を組み合わせて、playbook のCI/CD によるテストの自動化を行いたいですね。スケジュール設定をしておけば、毎日夜中にテストできますし、いつテストしたっけ?ってなることがなくなりますし。下記のURLのような状態に持っていけるのがより良いかなと思います。