Tambourine作業メモ

主にスキル習得のためにやった作業のメモ。他人には基本的に無用のものです。

Ansibleで遊んでみる(2)

さて、ロールを作ってみよう。

molecule.readthedocs.io

これに従ってやってみる。

とりあえず、ユーザーグループを作るロールを作ってみよう。rolesというディレクトリを作って、その下で以下を実行する。

> molecule init role user-group --driver-name docker
INFO     Initializing new role user-group...
No config file found; using defaults
- Role user-group was created successfully
INFO     Initialized role in /Users/tambara/study/ansible_study/roles/user-group successfully.

user-groupディレクトリが作られて、その下にロールに必要なものが作られる。 このあたりはAnsibleのガイドライン通りが作られるが、それ以外にmoleculeというディレクトリが作られてそれがテストに関するものである。その下にdefaultというディレクトリがあって、これがデフォルトのテストケースにあたる。

Moleculeのgetting-startedには、defaultの下に4つのファイルが作られると書いてあるが3つしか作られなかった。作られなかった奴はインストドキュメントらしいんで気にしないことにする。

> ls
converge.yml  molecule.yml  verify.yml

molecule.ymlはこんな感じ

> cat molecule.yml
---
dependency:
  name: galaxy
driver:
  name: docker
platforms:
  - name: instance
    image: docker.io/pycontribs/centos:8
    pre_build_image: true
provisioner:
  name: ansible
verifier:
  name: ansible

docker run hello-worldしてdockerが動いてることが確認出来たら、テストを実行するインスタンス作成を試してみる。

> molecule create
INFO     default scenario test matrix: dependency, create, prepare
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': 'instance', 'pre_build_image': True})

TASK [Check presence of custom Dockerfiles] ************************************
ok: [localhost] => (item={'image': 'docker.io/pycontribs/centos:8', 'name': 'instance', 'pre_build_image': True})

TASK [Create Dockerfiles from image names] *************************************
skipping: [localhost] => (item={'image': 'docker.io/pycontribs/centos:8', 'name': 'instance', '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': 'instance', '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': 'instance', 'pre_build_image': True})

TASK [Create molecule instance(s)] *********************************************
changed: [localhost] => (item=instance)

TASK [Wait for instance(s) creation to complete] *******************************
FAILED - RETRYING: Wait for instance(s) creation to complete (300 retries left).
FAILED - RETRYING: Wait for instance(s) creation to complete (299 retries left).
FAILED - RETRYING: Wait for instance(s) creation to complete (298 retries left).
FAILED - RETRYING: Wait for instance(s) creation to complete (297 retries left).
FAILED - RETRYING: Wait for instance(s) creation to complete (296 retries left).
FAILED - RETRYING: Wait for instance(s) creation to complete (295 retries left).
FAILED - RETRYING: Wait for instance(s) creation to complete (294 retries left).
changed: [localhost] => (item={'started': 1, 'finished': 0, 'ansible_job_id': '897685659497.84151', 'results_file': '/Users/tambara/.ansible_async/897685659497.84151', 'changed': True, 'failed': False, 'item': {'image': 'docker.io/pycontribs/centos:8', 'name': 'instance', '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.

大丈夫っぽい。

> molecule list
INFO     Running default > list
                ╷             ╷                  ╷               ╷         ╷
  Instance Name │ Driver Name │ Provisioner Name │ Scenario Name │ Created │ Converged
╶───────────────┼─────────────┼──────────────────┼───────────────┼─────────┼───────────╴
  instance      │ docker      │ ansible          │ default       │ true    │ false
                ╵             ╵                  ╵               ╵         ╵

ちゃんといる。

試しにタスクをいじってみる。

試しにタスクをいじってみる。

> cat tasks/main.yml
---
- name: Molecule Hello world!
  debug:
    msg: Hello, world!

実行する

> 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
WARNING  Skipping, instances already created.
INFO     Running default > prepare
WARNING  Skipping, prepare playbook not configured.
INFO     Running default > converge
INFO     Sanity checks: 'docker'

PLAY [Converge] ****************************************************************

TASK [Gathering Facts] *********************************************************
ok: [instance]

TASK [Include user-group] ******************************************************

TASK [user-group : Molecule Hello world!] **************************************
ok: [instance] => {
    "msg": "Hello, world!"
}

PLAY RECAP *********************************************************************
instance                   : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

出来たテストインスタンスにログインも簡単にできる。

> molecule login
INFO     Running default > login
[root@instance /]#
[root@instance /]# pwd
/
[root@instance /]# exit
exit

最後に、インスタンスを削除して終わり

> molecule destroy
INFO     default scenario test matrix: dependency, cleanup, destroy
INFO     Running default > dependency
WARNING  Skipping, missing the requirements file.
WARNING  Skipping, missing the requirements file.
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=instance)

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': '366507610977.86463', 'results_file': '/Users/tambara/.ansible_async/366507610977.86463', 'changed': True, 'failed': False, 'item': {'image': 'docker.io/pycontribs/centos:8', 'name': 'instance', '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が動いてない。デフォルトではLintが動かなくなったので、動かしたかったらmolecule.ymlを修正する。

とりあえず、公式にある通りだけど、set -eはfishではエラーになるので除いた。

> cat molecule/default/molecule.yml 
---
dependency:
  name: galaxy
lint: |
  yamllint .
  ansible-lint
  flake8
driver:
  name: docker
platforms:
  - name: instance
    image: docker.io/pycontribs/centos:8
    pre_build_image: true
provisioner:
  name: ansible
verifier:
  name: ansible

実行してみる。

> molecule lint
INFO     default scenario test matrix: dependency, lint
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

WARNING  Listing 5 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                                                              │
│   - '106'  # Role name {} does not match ``^[a-z][a-z0-9_]+$`` pattern                                               │
│   - '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/user-group/meta/main.yml'}, 'dependencies': [], '__line__': 1, '__file__': '/Users/tambara/study/ansible_study/roles/user-group/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/user-group/meta/main.yml'}, 'dependencies': [], '__line__': 1, '__file__': '/Users/tambara/study/ansible_study/roles/user-group/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/user-group/meta/main.yml'}, 'dependencies': [], '__line__': 1, '__file__': '/Users/tambara/study/ansible_study/roles/user-group/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/user-group/meta/main.yml'}, 'dependencies': [], '__line__': 1, '__file__': '/Users/tambara/study/ansible_study/roles/user-group/meta/main.yml', 'skipped_rules': []}}

106 Role name user-group does not match ``^[a-z][a-z0-9_]+$`` pattern
tasks/main.yml:1
---

ロール名からしてルールに合ってないと言われてヘコんだ。