Contents
本記事は Ansible Advent Calendar 2021, Ansible Advent Calendar 2021 – Qiita, vExperts Advent Calendar 2021の15日目の記事になります。
VMware関連のAnsibleネタでまたお前かと思われる方もいるかもしれませんが、しばしお付き合いください。
AnsibleにはPlaybookやRoleをテストするツールがいくつかOSSで提供されています。
その中で molecule
というテストツールはRoleのテストをするツールとして開発・提供されています。
moleucleを使用することで、ざっくりな説明になりますが以下の項目を自動的に実行してくれます。
- テスト環境の構築、テストを実行する前の事前作業
- 構築したテスト環境を使用してRoleのテストを実行
- べき統制のテスト
- Role実行後に想定した状態になっているかどうかの確認
- テスト環境の破棄
moleculeでテスト環境を自動で構築するには、環境を構築するためのドライバが必要です。
ドライバには vagrant
azure
aws
docker
などが準備されています。
もちろん vmware もあります 🙂
詳細は以下で確認してみてください。
そこで、今回はmoleculeとvCenter Simulator(vcsim)を使ってコンテナ環境でVMwareのRoleをテストしてみようと思います。
環境情報
項目 | バージョン | 備考 |
---|---|---|
OS | RHEL 8.4 | |
python | 3.9.6 | |
docker-ce | 20.10.12 | |
ansible-core | 2.12.1 | |
molecule | 3.5.2 | |
community.vmware | 1.17.0 | VMwareコレクション |
community.docker | 2.0.2 | Dockerコレクション |
環境の準備
Dockerのインストール
今回はコンテナエンジンとしてDockerを使用します。
以下の手順でインストールしてください。
dockerのインストール完了後に起動します。
1 2 3 |
[root@molecule ~]# systemctl start docker [root@molecule ~]# systemctl enable docker |
Pythonのインストール
Python 3.9をインストールします。
1 2 |
[root@advent-aap ~]# dnf -y install python39 |
Python 3.9用のSELinuxのパッケージをインストールします。
※標準でインストールされているpython3-libselinuxパッケージはPython 3.6用のものです
1 2 |
[root@advent-aap ~]# pip3 install selinux |
Ansibleのインストール
venvを作成してAnsibleをインストールします。
1 2 3 4 |
[root@molecule ~]# python3 -m venv venv [root@molecule ~]# . venv/bin/activate (venv) [root@molecule ~]# pip install ansible-core |
VMwareコレクションのインストール
VMwareのモジュールを使用するためVMwareコレクションのインストールおよび動作に必要なライブラリをインストールします。
1 2 3 |
(venv) [root@molecule ~]# pip install pyvmomi (venv) [root@molecule ~]# ansible-galaxy collection install community.vmware |
Dockerコレクションのインストール
vcsimコンテナをデプロイするためにDockerコレクションをインストールします。
1 2 |
(venv) [root@molecule ~]# ansible-galaxy collection install community.docker |
moleculeのインストール
moleculeとdockerドライバをインストールします。
1 2 |
(venv) [root@molecule ~]# pip install molecule molecule-docker |
これで準備が整いました 🙂
テスト準備
テスト用Roleの作成
ここではテスト用として example
Roleを作成してみます。
1 2 3 4 |
(venv) [root@molecule ~]# mkdir -p role/example/tasks (venv) [root@molecule ~]# cd role/example/ (venv) [root@molecule example]# vi tasks/main.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
--- - name: test community.vmware.vmware_guest_info: hostname: "{{ vcenter_hostname | default(lookup('env', 'VMWARE_HOST')) }}" username: "{{ vcenter_username | default(lookup('env', 'VMWARE_USER')) }}" password: "{{ vcenter_password | default(lookup('env', 'VMWARE_PASSWORD')) }}" validate_certs: false datacenter: "{{ datacenter }}" name: "{{ vm_name }}" register: vm_info - debug: msg="{{ vm_info }}" |
上記のタスクはVMの情報を取得してdebugで表示するだけの処理を実行する簡単なものになっています。
moleculeのシナリオ作成
moleculeはテストシナリオを作成して、そのシナリオごとに定義されたテスト内容を実行します。
ここでは defualt
のシナリオを作成します。
1 2 |
(venv) [root@molecule example]# molecule init scenario |
シナリオを作成すると以下のファイルが生成されます。
1 2 3 |
(venv) [root@molecule example]# ls molecule/default/ INSTALL.rst converge.yml create.yml destroy.yml molecule.yml verify.yml |
ファイル名 | 説明 |
---|---|
INSTALL.rst | テストシナリオの説明や仕様などを書くrstドキュメント |
molecule.yml | moleculeの設定をするファイル |
create.yml | テストインスタンスを作成するタスクが定義されたファイル |
destroy.yml | テストインスタンスを削除するタスクが定義されたファイル |
converge.yml | 実行するRoleが記述されているファイル |
verify.yml | convergeを実行した後に想定した状態になっているかを確認するタスクが定義されたファイル(今回は使わない) |
作成されるファイルの内容はドライバによって変わりますが、ここでは標準の delegated
ドライバを使用したものを前提に進めます。
delegated
ドライバを使用することでテスト用インスタンスの作成・破棄を自由に定義できます。
例えば、テストで使用したい環境のドライバが存在しない場合でもユーザーがインスタンスを作成・破棄するタスクを書くことで対応することができます。
molecule.ymlの修正
moleculeの設定を以下のようにします。
1 2 |
(venv) [root@molecule example]# vi molecule/default/molecule.yml |
1 2 3 4 5 6 7 8 9 10 11 12 |
--- dependency: name: galaxy driver: name: delegated platforms: - name: vcsim provisioner: name: ansible verifier: name: ansible |
platforms
は作成するインスタンス情報を記述します。
ここでは vcsim
という名前でテスト用インスタンスのホスト名を定義します。
その他の設定の詳細については以下を参照ください。
create.ymlの修正
テスト用インスタンスを作成するタスクを追加します。
1 2 |
(venv) [root@molecule example]# vi molecule/default/create.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
--- - name: Create hosts: localhost gather_facts: false no_log: "{{ molecule_no_log }}" tasks: - name: install dependency role command: "ansible-galaxy install sky_joker.ansible_vmware_govcsim_provisioner -p {{ playbook_dir }}/roles" register: role_installation_result changed_when: role_installation_result.rc != 0 - name: setup vcsim include_role: name: sky_joker.ansible_vmware_govcsim_provisioner - name: populate instance config dict set_fact: instance_conf_dict: instance: "{{ item.name }}" address: "{{ starte_up_govcsim_result.json.host }}" user: "{{ starte_up_govcsim_result.json.username }}" password: "{{ starte_up_govcsim_result.json.password }}" port: "{{ starte_up_govcsim_result.json.port }}" register: instance_config_dict loop: "{{ molecule_yml.platforms }}" - name: convert instance config dict to a list set_fact: instance_conf: "{{ instance_config_dict.results | map(attribute='ansible_facts.instance_conf_dict') | list }}" - name: dump instance config copy: content: | # Molecule managed {{ instance_conf | to_json | from_json | to_yaml }} dest: "{{ molecule_instance_config }}" mode: 0600 |
install dependency roleタスクについて
vcsimをセットアップするためのRoleを作成しましたので、こちらを使うようにRoleをインストールしています。
setup vcsim
上記のRoleを実行しています。
populate instance config dict
こちらには、作成したテスト用インスタンスの情報を記述します。
この情報を基にmoleculeはテストインスタンスへの接続用のinventory情報を生成します。
設定可能なパラメーターに関しては以下を参照ください。
そして convert instance config dict to a list
と dump instance config
タスクを実行してinventoryファイルを生成します。
destroy.ymlの修正
テスト用インスタンスを破棄するタスクを追加します。
1 2 |
(venv) [root@molecule example]# vi molecule/default/destroy.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
--- - name: Destroy hosts: localhost gather_facts: false no_log: "{{ molecule_no_log }}" tasks: - name: remove vcsim community.docker.docker_container: name: vcsim state: absent - name: remove the dependency roles file: path: "{{ playbook_dir }}/roles" state: absent |
vcsimをセットアップするRoleを使うと vcsim
という名前でコンテナが作成されます。
そのため vcsim
が存在している場合はコンテナが削除されます。
また、最後にvcsimセットアップRoleは不要のため削除しています。
converge.ymlの修正
Roleはmoleculeのホストで動作させるため connectoin: local
を追加します。
また、Role内で使うvCenterのホスト名の変数は vcenter_hostname
のため ansible_host(インベントリに記述したホスト名が格納されるマジック変数)
の値をその変数に格納します。
1 2 |
(venv) [root@molecule example]# vi molecule/default/converge.yml |
1 2 3 4 5 6 7 8 9 10 11 12 |
--- - name: Converge hosts: all gather_facts: false connection: local vars: vcenter_hostname: "{{ ansible_host }}" tasks: - name: "Include example" include_role: name: "example" |
テスト用パラメーターの追加
テストで使用する host_vars
group_vars
を追加します。
まずは group_vars
にvcsimの認証情報を記述します。
1 2 3 |
(venv) [root@molecule example]# mkdir molecule/default/group_vars (venv) [root@moleculep example]# vi molecule/default/group_vars/all.yml |
1 2 3 4 |
--- vcenter_username: user vcenter_password: pass |
上記のユーザー名、パスワードがvcsimのデフォルトになります。
次に host_vars
を追加します。
ファイル名は molecule.yml
に記述した platforms
で指定した名前で作ります。
1 2 3 |
(venv) [root@molecule example]# mkdir molecule/default/host_vars (venv) [root@molecule example]# vi molecule/default/host_vars/vcsim.yml |
1 2 3 4 |
--- datacenter: DC0 vm_name: DC0_H0_VM0 |
vcsimのRoleでシミュレーション環境を構築すると標準で以下の構成が作成されます。
一部の見方を書いておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
[ "/", "/F0", "/F0/DC0", <- DC名 "/F0/DC0/vm", <- VMフォルダ階層 "/F0/DC0/vm/F0", "/F0/DC0/vm/F0/DC0_H0_VM0", <- VM名 "/F0/DC0/vm/F0/DC0_H0_VM1", "/F0/DC0/host", <- ESXiフォルダ階層 "/F0/DC0/host/F0", "/F0/DC0/host/F0/DC0_H0", "/F0/DC0/host/F0/DC0_H0/DC0_H0", <- ESXi名 "/F0/DC0/host/F0/DC0_H0/Resources", "/F0/DC0/datastore", "/F0/DC0/datastore/DC0_POD0", "/F0/DC0/datastore/F0", "/F0/DC0/datastore/F0/LocalDS_0", "/F0/DC0/network", "/F0/DC0/network/VM Network", "/F0/DC0/network/F0", "/F0/DC0/network/F0/DVS0", "/F0/DC0/network/F0/DVS0-DVUplinks-15", "/F0/DC0/network/F0/DC0_DVPG0" ] |
テスト実行
moleculeのdefaultシナリオを実行します。
1 2 |
(venv) [root@molecule example]# ANSIBLE_PYTHON_INTERPRETER=`which python` molecule test |
こんな感じでRoleのテストができます 🙂
最後に
vscimを使用する時の注意点ですが、VCSAで出来る操作が全てサポートされているわけではありません。
そのため、vcsimで出来ないテストはVCSAを作って代用するなど代替案を考える必要がありますが、vcsimで出来る範囲であればコンテナ上でサクッとテストができます 🙂
Happy Automation!