前回作ったロールはロール名に"-"が入っていて、これはどうも良くないらしいので名前を直した。
さて、前回はテスト用のタスクだったけど、今度はホントにgroupを作ってみよう。
実際にテストとして走らせるplaybookは、molecule/default/converge.ymlとなる。
--- - name: Converge hosts: all tasks: - name: "Include usergroup" include_role: name: "usergroup" vars_from: "test"
ここでテスト用の変数ファイルを読み込む様に指定する。
テスト用変数ファイル(vars/test.yml)はこんな感じ。
--- usergroups: - { name: "hoge", gid: 7777 } - { name: "fuga", gid: 8888 }
タスクを書いてみる。tasks/main.ymlはこんな感じ。
--- - name: Make groups group: name: "{{ item.name }}" gid: "{{ item.gid }}" loop: "{{ usergroups }}"
実行してみる。
> molecule converge INFO default scenario test matrix: dependency, create, prepare, converge INFO Running default > dependency WARNING Skipping, missing the requirements file. WARNING Skipping, missing the requirements file. INFO Running default > create INFO Sanity checks: 'docker' PLAY [Create] ****************************************************************** TASK [Log into a Docker registry] ********************************************** skipping: [localhost] => (item={'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}) TASK [Check presence of custom Dockerfiles] ************************************ ok: [localhost] => (item={'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}) TASK [Create Dockerfiles from image names] ************************************* skipping: [localhost] => (item={'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}) TASK [Discover local Docker images] ******************************************** ok: [localhost] => (item={'changed': False, 'skipped': True, 'skip_reason': 'Conditional result was False', 'item': {'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}, 'ansible_loop_var': 'item', 'i': 0, 'ansible_index_var': 'i'}) TASK [Build an Ansible compatible image (new)] ********************************* skipping: [localhost] => (item=molecule_local/docker.io/pycontribs/centos:8) TASK [Create docker network(s)] ************************************************ TASK [Determine the CMD directives] ******************************************** ok: [localhost] => (item={'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}) TASK [Create molecule instance(s)] ********************************************* changed: [localhost] => (item=inst) TASK [Wait for instance(s) creation to complete] ******************************* FAILED - RETRYING: Wait for instance(s) creation to complete (300 retries left). changed: [localhost] => (item={'started': 1, 'finished': 0, 'ansible_job_id': '506425403898.18190', 'results_file': '/Users/tambara/.ansible_async/506425403898.18190', 'changed': True, 'failed': False, 'item': {'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}, 'ansible_loop_var': 'item'}) PLAY RECAP ********************************************************************* localhost : ok=5 changed=2 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0 INFO Running default > prepare WARNING Skipping, prepare playbook not configured. INFO Running default > converge PLAY [Converge] **************************************************************** TASK [Gathering Facts] ********************************************************* ok: [inst] TASK [Include usergroup] ******************************************************* TASK [usergroup : Make groups] ************************************************* changed: [inst] => (item={'name': 'hoge', 'gid': 7777}) changed: [inst] => (item={'name': 'fuga', 'gid': 8888}) PLAY RECAP ********************************************************************* inst : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
確認する
> molecule login INFO Running default > login [root@inst /]# cat /etc/group root:x:0: bin:x:1: daemon:x:2: sys:x:3: adm:x:4: tty:x:5: disk:x:6: (中略) dbus:x:81: input:x:999: kvm:x:36: render:x:998: systemd-journal:x:190: systemd-coredump:x:997: systemd-resolve:x:193: ssh_keys:x:996: hoge:x:7777: fuga:x:8888:
これに対するassertを書く。molecure/default/verify.ymlをこう書き換える。
--- # This is an example playbook to execute Ansible tests. - name: Verify hosts: all gather_facts: false tasks: - shell: grep hoge /etc/group |grep -q 7777 register: hoge - shell: grep fuga /etc/group |grep -q 8888 register: fuga - name: Example assertion assert: that: - hoge.rc == 0 - fuga.rc == 0
こんなんでいいのかな?
実行してみる。
> molecule verify INFO default scenario test matrix: verify INFO Running default > verify INFO Running Ansible Verifier INFO Sanity checks: 'docker' PLAY [Verify] ****************************************************************** TASK [shell] ******************************************************************* changed: [inst] TASK [shell] ******************************************************************* changed: [inst] TASK [Example assertion] ******************************************************* ok: [inst] => { "changed": false, "msg": "All assertions passed" } PLAY RECAP ********************************************************************* inst : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 INFO Verifier completed successfully.
わかりにくい・・・。
試しに、grep hoge...の行の最後の7777を8888に変えてみる。
実行するとテストがfailになる。
> molecule verify INFO default scenario test matrix: verify INFO Running default > verify INFO Running Ansible Verifier INFO Sanity checks: 'docker' PLAY [Verify] ****************************************************************** TASK [shell] ******************************************************************* fatal: [inst]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": "grep hoge /etc/group |grep -q 8888", "delta": "0:00:00.003928", "end": "2021-03-07 09:08:57.065460", "msg": "non-zero return code", "rc": 1, "start": "2021-03-07 09:08:57.061532", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} PLAY RECAP ********************************************************************* inst : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 CRITICAL Ansible return code was 2, command was: ansible-playbook --inventory /Users/tambara/.cache/molecule/usergroup/default/inventory --skip-tags molecule-notest,notest /Users/tambara/study/ansible_study/roles/usergroup/molecule/default/verify.yml
assertに入る前にエラーになってる。
ignore_errors: true
してみる。
--- - name: Verify hosts: all gather_facts: false ignore_errors: true tasks: - shell: grep hoge /etc/group |grep -q 8888 register: hoge - shell: grep fuga /etc/group |grep -q 8888 register: fuga - name: Example assertion assert: that: - hoge.rc == 0 - fuga.rc == 0
実行してみる。
> molecule verify INFO default scenario test matrix: verify INFO Running default > verify INFO Running Ansible Verifier INFO Sanity checks: 'docker' PLAY [Verify] ****************************************************************** TASK [shell] ******************************************************************* fatal: [inst]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": "grep hoge /etc/group |grep -q 8888", "delta": "0:00:00.005223", "end": "2021-03-07 09:21:12.978052", "msg": "non-zero return code", "rc": 1, "start": "2021-03-07 09:21:12.972829", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} ...ignoring TASK [shell] ******************************************************************* changed: [inst] TASK [Example assertion] ******************************************************* fatal: [inst]: FAILED! => { "assertion": "hoge.rc == 0", "changed": false, "evaluated_to": false, "msg": "Assertion failed" } ...ignoring PLAY RECAP ********************************************************************* inst : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=2 INFO Verifier completed successfully.
assertもignoreされた。これではダメだ。
shellモジュールに個別にignore_errors: true
を付けたら、上手くいったが、これはこれでテストの失敗がわかりづらい。
--- - name: Verify hosts: all gather_facts: false tasks: - shell: grep hoge /etc/group |grep -q 8888 ignore_errors: true register: hoge - shell: grep fuga /etc/group |grep -q 8888 ignore_errors: true register: fuga - name: Example assertion assert: that: - hoge.rc == 0 - fuga.rc == 0
> molecule verify INFO default scenario test matrix: verify INFO Running default > verify INFO Running Ansible Verifier INFO Sanity checks: 'docker' PLAY [Verify] ****************************************************************** TASK [shell] ******************************************************************* fatal: [inst]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": "grep hoge /etc/group |grep -q 8888", "delta": "0:00:00.003725", "end": "2021-03-07 09:24:25.994889", "msg": "non-zero return code", "rc": 1, "start": "2021-03-07 09:24:25.991164", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} ...ignoring TASK [shell] ******************************************************************* changed: [inst] TASK [Example assertion] ******************************************************* fatal: [inst]: FAILED! => { "assertion": "hoge.rc == 0", "changed": false, "evaluated_to": false, "msg": "Assertion failed" } PLAY RECAP ********************************************************************* inst : ok=2 changed=2 unreachable=0 failed=1 skipped=0 rescued=0 ignored=1 CRITICAL Ansible return code was 2, command was: ansible-playbook --inventory /Users/tambara/.cache/molecule/usergroup/default/inventory --skip-tags molecule-notest,notest /Users/tambara/study/ansible_study/roles/usergroup/molecule/default/verify.yml
とりあえず、これで全体を実行してみる。
> molecule test INFO default scenario test matrix: dependency, lint, cleanup, destroy, syntax, create, prepare, converge, idempotence, side_effect, verify, cleanup, destroy INFO Running default > dependency WARNING Skipping, missing the requirements file. WARNING Skipping, missing the requirements file. INFO Running default > lint COMMAND: yamllint . ansible-lint flake8 ./molecule/default/verify.yml 17:1 error too many blank lines (1 > 0) (empty-lines) WARNING Listing 9 violation(s) that are fatal 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 │ │ - '201' # Trailing whitespace │ │ - '301' # Commands should not change things if nothing needs doing │ │ - '502' # All tasks should be named │ │ - '701' # meta/main.yml should contain relevant info │ │ - '703' # meta/main.yml default values should be changed │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ 701 Role info should contain platforms meta/main.yml:1 {'meta/main.yml': {'galaxy_info': {'author': 'your name', 'description': 'your role description', 'company': 'your company (optional)', 'license': 'license (GPL-2.0-or-later, MIT, etc)', 'min_ansible_version': 2.1, 'galaxy_tags': [], '__line__': 2, '__file__': '/Users/tambara/study/ansible_study/roles/usergroup/meta/main.yml'}, 'dependencies': [], '__line__': 1, '__file__': '/Users/tambara/study/ansible_study/roles/usergroup/meta/main.yml', 'skipped_rules': []}} 703 Should change default metadata: author meta/main.yml:1 {'meta/main.yml': {'galaxy_info': {'author': 'your name', 'description': 'your role description', 'company': 'your company (optional)', 'license': 'license (GPL-2.0-or-later, MIT, etc)', 'min_ansible_version': 2.1, 'galaxy_tags': [], '__line__': 2, '__file__': '/Users/tambara/study/ansible_study/roles/usergroup/meta/main.yml'}, 'dependencies': [], '__line__': 1, '__file__': '/Users/tambara/study/ansible_study/roles/usergroup/meta/main.yml', 'skipped_rules': []}} 703 Should change default metadata: company meta/main.yml:1 {'meta/main.yml': {'galaxy_info': {'author': 'your name', 'description': 'your role description', 'company': 'your company (optional)', 'license': 'license (GPL-2.0-or-later, MIT, etc)', 'min_ansible_version': 2.1, 'galaxy_tags': [], '__line__': 2, '__file__': '/Users/tambara/study/ansible_study/roles/usergroup/meta/main.yml'}, 'dependencies': [], '__line__': 1, '__file__': '/Users/tambara/study/ansible_study/roles/usergroup/meta/main.yml', 'skipped_rules': []}} 703 Should change default metadata: license meta/main.yml:1 {'meta/main.yml': {'galaxy_info': {'author': 'your name', 'description': 'your role description', 'company': 'your company (optional)', 'license': 'license (GPL-2.0-or-later, MIT, etc)', 'min_ansible_version': 2.1, 'galaxy_tags': [], '__line__': 2, '__file__': '/Users/tambara/study/ansible_study/roles/usergroup/meta/main.yml'}, 'dependencies': [], '__line__': 1, '__file__': '/Users/tambara/study/ansible_study/roles/usergroup/meta/main.yml', 'skipped_rules': []}} 301 Commands should not change things if nothing needs doing molecule/default/verify.yml:6 Task/Handler: shell grep hoge /etc/group |grep -q 7777 502 All tasks should be named molecule/default/verify.yml:6 Task/Handler: shell grep hoge /etc/group |grep -q 7777 301 Commands should not change things if nothing needs doing molecule/default/verify.yml:9 Task/Handler: shell grep fuga /etc/group |grep -q 8888 502 All tasks should be named molecule/default/verify.yml:9 Task/Handler: shell grep fuga /etc/group |grep -q 8888 201 Trailing whitespace molecule/default/verify.yml:14 that: INFO Running default > cleanup WARNING Skipping, cleanup playbook not configured. INFO Running default > destroy INFO Sanity checks: 'docker' PLAY [Destroy] ***************************************************************** TASK [Destroy molecule instance(s)] ******************************************** changed: [localhost] => (item=inst) TASK [Wait for instance(s) deletion to complete] ******************************* FAILED - RETRYING: Wait for instance(s) deletion to complete (300 retries left). ok: [localhost] => (item={'started': 1, 'finished': 0, 'ansible_job_id': '352555244554.23499', 'results_file': '/Users/tambara/.ansible_async/352555244554.23499', 'changed': True, 'failed': False, 'item': {'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}, 'ansible_loop_var': 'item'}) TASK [Delete docker network(s)] ************************************************ PLAY RECAP ********************************************************************* localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 INFO Running default > syntax playbook: /Users/tambara/study/ansible_study/roles/usergroup/molecule/default/converge.yml INFO Running default > create PLAY [Create] ****************************************************************** TASK [Log into a Docker registry] ********************************************** skipping: [localhost] => (item={'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}) TASK [Check presence of custom Dockerfiles] ************************************ ok: [localhost] => (item={'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}) TASK [Create Dockerfiles from image names] ************************************* skipping: [localhost] => (item={'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}) TASK [Discover local Docker images] ******************************************** ok: [localhost] => (item={'changed': False, 'skipped': True, 'skip_reason': 'Conditional result was False', 'item': {'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}, 'ansible_loop_var': 'item', 'i': 0, 'ansible_index_var': 'i'}) TASK [Build an Ansible compatible image (new)] ********************************* skipping: [localhost] => (item=molecule_local/docker.io/pycontribs/centos:8) TASK [Create docker network(s)] ************************************************ TASK [Determine the CMD directives] ******************************************** ok: [localhost] => (item={'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}) TASK [Create molecule instance(s)] ********************************************* changed: [localhost] => (item=inst) TASK [Wait for instance(s) creation to complete] ******************************* FAILED - RETRYING: Wait for instance(s) creation to complete (300 retries left). changed: [localhost] => (item={'started': 1, 'finished': 0, 'ansible_job_id': '929437985046.23918', 'results_file': '/Users/tambara/.ansible_async/929437985046.23918', 'changed': True, 'failed': False, 'item': {'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}, 'ansible_loop_var': 'item'}) PLAY RECAP ********************************************************************* localhost : ok=5 changed=2 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0 INFO Running default > prepare WARNING Skipping, prepare playbook not configured. INFO Running default > converge PLAY [Converge] **************************************************************** TASK [Gathering Facts] ********************************************************* ok: [inst] TASK [Include usergroup] ******************************************************* TASK [usergroup : Make groups] ************************************************* changed: [inst] => (item={'name': 'hoge', 'gid': 7777}) changed: [inst] => (item={'name': 'fuga', 'gid': 8888}) PLAY RECAP ********************************************************************* inst : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 INFO Running default > idempotence PLAY [Converge] **************************************************************** TASK [Gathering Facts] ********************************************************* ok: [inst] TASK [Include usergroup] ******************************************************* TASK [usergroup : Make groups] ************************************************* ok: [inst] => (item={'name': 'hoge', 'gid': 7777}) ok: [inst] => (item={'name': 'fuga', 'gid': 8888}) PLAY RECAP ********************************************************************* inst : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 INFO Idempotence completed successfully. INFO Running default > side_effect WARNING Skipping, side effect playbook not configured. INFO Running default > verify INFO Running Ansible Verifier PLAY [Verify] ****************************************************************** TASK [shell] ******************************************************************* changed: [inst] TASK [shell] ******************************************************************* changed: [inst] TASK [Example assertion] ******************************************************* ok: [inst] => { "changed": false, "msg": "All assertions passed" } PLAY RECAP ********************************************************************* inst : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 INFO Verifier completed successfully. INFO Running default > cleanup WARNING Skipping, cleanup playbook not configured. INFO Running default > destroy PLAY [Destroy] ***************************************************************** TASK [Destroy molecule instance(s)] ******************************************** changed: [localhost] => (item=inst) TASK [Wait for instance(s) deletion to complete] ******************************* FAILED - RETRYING: Wait for instance(s) deletion to complete (300 retries left). changed: [localhost] => (item={'started': 1, 'finished': 0, 'ansible_job_id': '477983483623.24900', 'results_file': '/Users/tambara/.ansible_async/477983483623.24900', 'changed': True, 'failed': False, 'item': {'image': 'docker.io/pycontribs/centos:8', 'name': 'inst', 'pre_build_image': True}, 'ansible_loop_var': 'item'}) TASK [Delete docker network(s)] ************************************************ PLAY RECAP ********************************************************************* localhost : ok=2 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 INFO Pruning extra files from scenario ephemeral directory
Lintはいっぱい怒られているけど、とりあえず、一通りは流れたようだ。