TestinfraとAnsibleを組み合わせて使う
インフラテストツールのTestinfraをAnsibleと組み合わせて使用すると色々と捗るよという投稿です。
Testinfraについては以前ブログを書いているので見ていただければと。
Inventoryの共有
TestinfraはAnsibleのInventoryの情報を参照することができます。
そのためAnsibleで管理している情報をそのままテストへ活用できます。
https://testinfra.readthedocs.io/en/latest/backends.html#ansible
$ py.test --hosts='ansible://all' # tests all inventory hosts $ py.test --hosts='ansible://host1,ansible://host2' $ py.test --hosts='ansible://web*' $ py.test --force-ansible --hosts='ansible://all' $ py.test --hosts='ansible://host?force_ansible=True'
Inventoryファイルをansible.cfg等で設定せずにオプションで指定する場合には--ansible-inventory=ANSIBLE_INVENTORY
で指定できます。
Ansibleのmoduleの実行
Testinfraのテストの中でAnsibleのmoduleを実行することができます。
https://testinfra.readthedocs.io/en/latest/modules.html#ansible
[koh@kohs-MBP] ~/vag_test % ipython Python 3.7.3 (default, May 1 2019, 16:07:48) Type 'copyright', 'credits' or 'license' for more information IPython 7.5.0 -- An enhanced Interactive Python. Type '?' for help. In [1]: import testinfra In [2]: host = testinfra.get_host("ansible://Vag1") In [3]: host.ansible("command", "echo foo", check=False) Out[3]: {'ansible_facts': {'discovered_interpreter_python': '/usr/bin/python'}, 'changed': True, 'cmd': ['echo', 'foo'], 'delta': '0:00:00.004734', 'end': '2019-10-05 15:07:42.251008', 'rc': 0, 'start': '2019-10-05 15:07:42.246274', 'stderr': '', 'stderr_lines': [], 'stdout': 'foo', 'stdout_lines': ['foo']} In [4]:
こちらはcommandモジュールを実行してみた例です。
実行した結果としてchangedやrc, stdout等Ansibleで実行したときと同様のデータが帰ってきます。
setupモジュールを使用するテストとしては下記のようなイメージでしょうか。
[koh@kohs-MBP] ~/vag_test % cat test_ansible.py def test_dns(host): nameservers = host.ansible("setup")["ansible_facts"]["ansible_dns"]["nameservers"] assert '10.1.1.1' in nameservers [koh@kohs-MBP] ~/vag_test % [koh@kohs-MBP] ~/vag_test % py.test -v test_ansible.py --hosts='ansible://Vag1' ======================================== test session starts ======================================== platform darwin -- Python 3.7.3, pytest-4.4.1, py-1.8.0, pluggy-0.9.0 -- /Users/koh/.pyenv/versions/3.7.3/bin/python3.7 cachedir: .pytest_cache rootdir: /Users/koh/vag_test, inifile: pytest.ini plugins: xonsh-0.8.12, testinfra-3.0.5 collected 1 item test_ansible.py::test_dns[ansible://Vag1] FAILED [100%] ============================================= FAILURES ============================================== _____________________________________ test_dns[ansible://Vag1] ______________________________________ host = <testinfra.host.Host object at 0x10e9be748> def test_dns(host): nameservers = host.ansible("setup")["ansible_facts"]["ansible_dns"]["nameservers"] > assert '10.1.1.1' in nameservers E AssertionError: assert '10.1.1.1' in ['10.0.2.3'] test_ansible.py:3: AssertionError ===================================== 1 failed in 2.17 seconds ====================================== zsh: exit 1 py.test -v test_ansible.py --hosts='ansible://Vag1' [koh@kohs-MBP] ~/vag_test %
setupの結果からnameserverの情報を取得しテストすることができました。
Variableの共有
Ansible側で定義されているVariableを参照できます。
参照できる変数はhost_varsとgroup_varsで定義されているものとinventory_hostname等の一部の変数です。
Playbook内でinclude_vars等で定義しているものは参照できないのでご注意ください。
[koh@kohs-MBP] ~/vag_test % ipython Python 3.7.3 (default, May 1 2019, 16:07:48) Type 'copyright', 'credits' or 'license' for more information IPython 7.5.0 -- An enhanced Interactive Python. Type '?' for help. In [1]: import testinfra In [2]: host = testinfra.get_host("ansible://Vag1") In [3]: host.ansible.get_variables() Out[3]: {'aaa': 'bbb', 'foo': 'bar', 'hoge': 'fuga', 'inventory_hostname': 'Vag1', 'group_names': ['Vag'], 'groups': {'Vag': ['Vag1', 'Vag2', 'Vag3'], 'all': ['Vag1', 'Vag2', 'Vag3']}} In [4]:
まとめ
現在MoleculeでもTestinfraがデフォルトのテストツールとして採用されているように、かなりAnsibleとの相性がいいと感じました。
Testinfraは他にもDockerやKubenatesとも組み合わせることができるので色々と試していきたいです。