はじめに
<バージョン>
ansible: 2.9.17
molecule: 3.3.0
[Ansible] molecule でネットワーク機器の設定後のテストを自動化する(いまいち編)の記事
(以後、参考記事)にあるように、moleculeでネットワーク機器用roleのテストが自動化
できそうなので色々調べてみました。
今回はvMXに対してshowコマンドの結果を取得するroleをmoleculeで動作確認します。
1. roleの構成
参考記事の構成をもとにroleを作成しました。roleのディレクトリを
molecule init role <ロール名(今回はrole_test)>
で作成し、不要なファイルは削除しました。
違いとしては、インベントリがhost.ymlとして別途分けています。
role_test
│
├── molecule
│ └── default
│ ├── inventory
│ │ └── hosts.yml ☆ココが違う
│ ├── INSTALL.rst
│ ├── converge.yml
│ ├── molecule.yml
│ └── verify.yml
└── tasks
└── main.yml
2. 関連ファイル(molecule.yml)
今回の記事で一番重要な部分なので単独で章を作ります。案外、参考資料が少なくて調べるのに苦労しました。
ポイントは以下にまとめます。詳細な設定は、Molecule 3.2.5.dev6 documentationに載っています。
driver
接続対象のホストがすでに存在する場合はname: delegated
と書けばよいです。
moleculeは実行時にdockerでインスタンスを構築して動作確認ということも可能なようです。
Developing and Testing Ansible Roles with Molecule and Podman - Part 1
provisioner
ansibleでいう、ansible.cfgやインベントリの設定が行える部分です。インベントリは、
hosts.ymlを参照するようにして、config_options
でgather_facts: false
にする設定を入れました。
※インベントリの内容は次の章で説明します。
platforms
provisionerのインベントリにあるホストの中から、実際どのホストに接続するかを選択します。
verifier
role実行後の確認方法を記載します。今回はplaybook実行後に、別途playbook(verify.yml)
を実行するので、name: ansible
とします。
lint
playbook実行前にlintを実行したい場合は書いておきましょう。
yamllint
とansible-lint
は別途インストールが必要です。
---
dependency: # 依存関係のあるファイル
name: galaxy
enabled: false # Ansible Galaxyは使わないのでfalseにしておく
driver: # 対象機器を用意する方法
name: delegated # 接続対象が既に存在する場合、delegatedでよい
provisioner: # 環境設定
name: ansible
inventory:
links:
hosts: ./inventory/hosts.yml # インベントリのパスを指定(基準はrole名/molecule/default)
config_options:
defaults: # ansible.cfgの内容を記載可能
gathering: explicit # gather_facts: false をデフォルトにする
platforms: # 確認対象
- name: host_01 # 対象host
verifier: # 事後確認方法
name: ansible # 確認内容はverify.ymlに記載
lint: |
set -e
yamllint .
ansible-lint
3. その他関連ファイル
以下ファイルについては、moleculeを使うにあたっての工夫は特にありません。
(1)hosts.yml(インベントリ)
---
all:
children:
test_nw:
hosts:
host_01:
ansible_host: <対象機器のIPアドレス>
vars:
ansible_port: 22
ansible_connection: network_cli
ansible_network_os: junos
ansible_user: username
ansible_ssh_pass: password
ansible_host_key_checking: false
(2)main.yml
roleで実際に実行されるplaybookです。
---
- name: get show
junos_command:
commands: show interfaces fxp0 terse
register: int_results
- name: get result
copy:
content: "{{ int_results.stdout[0] }}"
dest: "./{{ inventory_hostname }}_result.log"
mode: "644"
(3)verify.yml
roleの後に実行されるplaybookです。今回は適当なassertを入れておきます。
role内で定義した変数は、このplaybookに引き継がれないので注意が必要です。
---
- name: Verify
hosts: all
tasks:
- name: Example assertion
assert:
that:
- ansible_host is defined
4. molecule実行
今回は主に以下の流れでmoleculeを動作させます。
(1)lint実行
(2)role実行(main.yml)
(3)冪等性確認で、再度role実行(main.yml)
(4)事後確認(verify.yml)
roleが入っているディレクトリに移動して、molecule test
コマンドで
動作確認を実施しましょう。
cd /home/centos/roles/role_test
molecule test
以下が実行ログです。ログの重要な部分に☆マークを付けておきました。
プロセスに必要なファイルが存在しない場合は、WARNING Skipping, <メッセージ>
が表示されて、手順がskipされます。
ポイントとしては、冪等性確認で、再度role実行をした際に結果がchangedになってしまうとエラーになります。
(venv) [centos@ip-<ip addr> role_test]$ molecule test
INFO default scenario test matrix: dependency, lint, cleanup, destroy, syntax, create, prepare, converge, idempotence, side_effect, verify, cleanup, destroy
INFO Performing prerun...
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > dependency
WARNING Skipping, dependency is disabled.
WARNING Skipping, dependency is disabled.
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
☆lint実行
INFO Running default > lint
COMMAND: set -e
yamllint .
ansible-lint
Loading custom .yamllint config file, this extends our internal yamllint config.
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > cleanup
WARNING Skipping, cleanup playbook not configured.
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > destroy
WARNING Skipping, destroy action has no playbook.
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > syntax
playbook: /home/centos/roles/role_test/molecule/default/converge.yml
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > create
WARNING Skipping, create action has no playbook.
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > prepare
WARNING Skipping, prepare playbook not configured.
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > converge
☆role実行(1回目)
PLAY [Converge] ***************************************************************************************************************************************************
TASK [Include role_test] ******************************************************************************************************************************************
TASK [role_test : get show] ***************************************************************************************************************************************
[WARNING]: arguments wait_for, match, rpcs are not supported when using transport=cli
ok: [host_01]
TASK [role_test : get result] *************************************************************************************************************************************
changed: [host_01] ☆ここではchanged
PLAY RECAP ********************************************************************************************************************************************************
host_01 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > idempotence
☆role実行(2回目)
PLAY [Converge] ***************************************************************************************************************************************************
TASK [Include role_test] ******************************************************************************************************************************************
TASK [role_test : get show] ***************************************************************************************************************************************
[WARNING]: arguments wait_for, match, rpcs are not supported when using transport=cli
ok: [host_01]
TASK [role_test : get result] *************************************************************************************************************************************
ok: [host_01] ☆ここがOKなので冪等性が確認された
PLAY RECAP ********************************************************************************************************************************************************
host_01 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
INFO Idempotence completed successfully.
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > side_effect
WARNING Skipping, side effect playbook not configured.
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > verify
INFO Running Ansible Verifier
☆事後確認
PLAY [Verify] *****************************************************************************************************************************************************
TASK [Example assertion] ******************************************************************************************************************************************
ok: [host_01] => {
"changed": false,
"msg": "All assertions passed"
}
PLAY RECAP ********************************************************************************************************************************************************
host_01 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
INFO Verifier completed successfully.
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > cleanup
WARNING Skipping, cleanup playbook not configured.
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > destroy
WARNING Skipping, destroy action has no playbook.
INFO Pruning extra files from scenario ephemeral directory
5. エラーパターン
5-1. lintでエラーになった場合
一度moleculeを実行するとroleのディレクトリに.yamllint
が作成されるので、
yamllintのカスタマイズが可能です。今回は、以下の設定を入れます。これを入れると、
yamlの1行目に"---"が無い場合はエラーになります。詳細は、yamllint documentationをご参照ください。
動作確認のために、hosts.ymlの1行目の"---"を削除します。
<修正前>
document-start: disable
<修正後>
document-start:
present: true
以下が実行ログです。想定通りyamllintによってエラーが起こりました。
INFO Running default > lint
COMMAND: set -e
yamllint .
ansible-lint
./molecule/default/inventory/hosts.yml
1:1 warning missing document start "---" (document-start) ☆ エラーが発生
Loading custom .yamllint config file, this extends our internal yamllint config.
WARNING Listing 1 violation(s) that are fatal
yaml: missing document start "---" (document-start)
molecule/default/inventory/hosts.yml:1
You can skip specific rules or tags by adding them to your configuration file:
# .ansible-lint
warn_list: # or 'skip_list' to silence them completely
- yaml # Violations reported by yamllint
Finished with 1 failure(s), 0 warning(s) on 6 files.
CRITICAL Lint failed with error code 2
5-2. 冪等性でエラーになった場合
あえて冪等性でエラーにするためにmain.ymlでrandom fileterを使い、0~100の間
でランダムな値を発生させます。
---
- name: random number
copy:
content: "{{ 100 | random }}"
dest: "./{{ inventory_hostname }}_result.log"
mode: "644"
以下が実行ログです。ログの重要な部分に☆マークを付けておきました。
ログのように2回目のrole実行でchangedになった部分があるので、
冪等性(英語でidempotence)でエラーになりました
☆role実行(1回目)
PLAY [Converge] ***************************************************************************************************************************************************
TASK [Include role_test] ******************************************************************************************************************************************
TASK [role_test : random number] **********************************************************************************************************************************
changed: [host_01] ☆1回目はchanged
PLAY RECAP ********************************************************************************************************************************************************
host_01 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
INFO Inventory /home/centos/roles/role_test/molecule/default/./inventory/hosts.yml linked to /home/centos/.cache/molecule/role_test/default/inventory/hosts
INFO Running default > idempotence
☆role実行(2回目)
PLAY [Converge] ***************************************************************************************************************************************************
TASK [Include role_test] ******************************************************************************************************************************************
TASK [role_test : random number] **********************************************************************************************************************************
changed: [host_01] ☆2回目もchanged
PLAY RECAP ********************************************************************************************************************************************************
host_01 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
CRITICAL Idempotence test failed because of the following tasks:
* => role_test : random number ☆エラーになったtaskの名前
WARNING An error occurred during the test sequence action: 'idempotence'. Cleaning up. ☆冪等性でエラーになる
まとめ
moleculeのいいところ
- 既存のroleの構成のままでroleの動作確認機能が追加できる
-
molecule test
コマンド一つで、roleの動作確認・冪等性・lintの確認が行える
少し気になるところ
- roleごとにmolecule.ymlを書く必要がある
- verify.ymlにassertを書くくらいなら、role内のtaskに書いた方がよい気がする
参考資料
[Ansible] molecule でネットワーク機器の設定後のテストを自動化する(いまいち編)
Moleculeに入門してみたよ
Molecule 3.2.5.dev6 documentation
Molecule で ansible の config を設定する
[Ansible] デフォルトを gather_facts: false 扱いにする
yamllint documentation