- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- Ansible/development/module へ行く。
Ansible Moduleの開発 †
moduleのロード †
Ansibleがデフォルトでmoduleを探索するパスに設置する、または、ansible.cfgでmoduleのパスを指定しすればよい。そうすればAnsibleがプレイブックを実行時にロードしてくれる。
- 環境変数
ANSIBLE_LIBRARY
~/.ansible/plugins/modules/
/usr/share/ansible/plugins/modules/
ansible.cfgに指定 †
ansible.cfg
のlibrary
というパラメタに自作したmoduleのパスを指定する。
ディレクトリ構成は以下のとおり。
$ tree . ├── ansible.cfg ├── mod │ └── hello.py └── test.yaml 1 directory, 3 files
ansible.cfg
以下では、mod
というディレクトリを相対パスでしている。
# Python2と3で同様の振る舞いをするようなおまじない from __future__ import (absolute_import, division, print_function) __metaclass__ = type # https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_documenting.html#ansible-metadata-block # Ansibleが使用するメタデータ ANSIBLE_METADATA = { # moduleのバージョンではない!metadata schemaのバージョン 'metadata_version': '1.1', # 以下のステータスはAnsible Core Teamのメンバによって判断される 'status': ['preview'], 'supported_by': 'community' } # ドキュメント生成に使用される # 以下でドキュメントを表示できる # $ ansible-doc -M /path/to/moduledir-t module hello DOCUMENTATION = r''' --- module: hello short_description: my hello requirements: description: - echo message options: seealso: author: - moritetu ''' EXAMPLES = r''' - hello: echo: hello world ''' RETURN = r''' message: description: echo message returned: always type: str sample: hello world ''' # AnsibleModuleの読み込み from ansible.module_utils.basic import AnsibleModule def main(): module = AnsibleModule( # moduleのパラメータ argument_spec=dict( echo=dict(type='str', required=True), ), supports_check_mode=True ) if module.check_mode: module.exit_json(**result) result = dict( changed=False, message=module.params['echo'], ) # moduleの出力 module.exit_json(**result) if __name__ == '__main__': main()
以下では、ansible.cfg
があるディレクトリでplaybookを実行する。
$ ansible-playbook test.yaml -v Using /test/ansible/module_test/ansible_cfg_module_test/ansible.cfg as config file PLAY [localhost] ********************************************************************************** TASK [hello] ************************************************************************************** ok: [localhost] => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "message": "world"} PLAY RECAP **************************************************************************************** localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
サンプル ansible_cfg_module_test.tar.gz
libraryのローカルロード †
playbook及び特定のroleに対しmoduleをロードさせることができる。
playbookや特定のroleの下にlibraryフォルダを設定することで可能である。
実際に自作moduleがロードされるか確認する。
テストで使用するソースは以下のとおり。
hello.py
import json from ansible.module_utils.basic import AnsibleModule def main(): module = AnsibleModule( argument_spec=dict( _path=dict(type='path', required=False), _raw=dict(type='raw', required=False), _jsonarg=dict(type='jsonarg', required=False), _json=dict(type='json', required=False), _bytes=dict(type='bytes', required=False), _bits=dict(type='bits', required=False), ), supports_check_mode=True ) module.exit_json( _path=module.params['_path'], _raw=module.params['_raw'], _jsonarg=json.loads(module.params['_jsonarg']), _json=json.loads(module.params['_json']), _bytes=module.params['_bytes'], _bits=module.params['_bits'], ) if __name__ == '__main__': main()
実験 プレイブックに適用する †
playbookのあるパスにlibrary
というディレクトリを配置する。
ディレクトリ構成は以下。
$ tree . ├── library │ └── hello.py └── test.yaml 1 directory, 2 files
test.yaml
- hosts: localhost connection: local gather_facts: no tasks: - hello: _path: ${HOME} _raw: raw _jsonarg: {"hoge":[1,2,3]} _json: {"hoge":[1,2,3]} _bytes: 8Kbyte _bits: 16bit register: facts - debug: msg={{ facts }}
プレイブックを実行する。(簡単のためconnectionはlocal)
$ ls library test.yaml $ ansible-playbook test.yaml -v Using /etc/ansible/ansible.cfg as config file PLAY [localhost] ********************************************************************************** TASK [hello] ************************************************************************************** ok: [localhost] => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "message": "world"} PLAY RECAP **************************************************************************************** localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
実験 特定のroleに適用する †
roleの下にlibrary
というディレクトリを配置する。
$ tree . ├── db.yaml ├── roles │ ├── db │ │ └── tasks │ │ └── main.yaml │ └── web │ ├── library │ │ └── hello.py │ └── tasks │ └── main.yaml └── web.yaml 6 directories, 5 files
web.yaml
username=dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME']))
roles/web/tasks/main.yaml
# str mode=dict(required=True, type='str', choices=['init', 'update']) # list mode=dict(required=True, type='list', choices=['init', 'update'])
db.yaml
secret=dict(required=True, type='str', no_log=True)
roles/db/tasks/main.yaml
elm=dict(required=True, type='list', elements='str')
プレイブックを実行する。
$ ansible-playbook web.yaml -v Using /etc/ansible/ansible.cfg as config file PLAY [localhost] ********************************************************************************** TASK [web : hello] ******************************************************************************** ok: [localhost] => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "message": "web"} PLAY RECAP **************************************************************************************** localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
roleがdbの場合はmoduleのロードに失敗しエラーとなる。
$ ansible-playbook db.yaml -v Using /etc/ansible/ansible.cfg as config file ERROR! couldn't resolve module/action 'hello'. This often indicates a misspelling, missing collection, or incorrect module path. The error appears to be in '/test/ansible/module_test/roles_test/roles/db/tasks/main.yaml': line 1, column 3, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: - hello: echo=db ^ here
サンプル roles_test.tar.gz
参考
- https://docs.ansible.com/ansible/latest/dev_guide/developing_locally.html#developing-locally
- https://docs.ansible.com/ansible/latest/reference_appendices/config.html