この記事は、「赤帽エンジニア Advent Calendar 2018」16日目の記事です。
こんにちは、Ansibleのテクニカルサポートエンジニアをしている、八木澤(@hiyoko_taisa)です。 Ansibleを使う上で「こんなモジュールがあったらいいのに」「このモジュールにこんな機能があればいいのに」と思うことはありませんか?
Ansibleでは、Pythonの知識があればモジュールを自作することも可能です。 ここでは、そのやり方について下記の公式ドキュメントをベースに解説します。 https://docs.ansible.com/ansible/2.7/dev_guide/developing_modules.html
注: 自作モジュールの作成方法およびトラブルシュートはRed Hat Ansible Engineのサポート対象外となりますので、ご注意ください
モジュールを作る前に
1. 似たようなモジュールが存在しないか?
「モジュールを作ろう!」と意気込む前に、まず同様のモジュールが存在していないか確認しましょう。 公式ドキュメントにはAnsibleで利用可能なモジュールのリストがあります。下記を検索し、同じようなモジュールがないか見てみましょう。 https://docs.ansible.com/ansible/2.7/modules/list_of_all_modules.html#all-modules
2. Pull Requestが存在しないか?
現時点でモジュールに希望する機能がない場合でも、既にPull Requestとして機能拡張が予定されている場合があります。 下記を確認して、似たような機能を実現するPRが存在するか確認してみましょう。
- GitHub new module PRs (https://github.com/ansible/ansible/labels/new_module)
- All updates to modules (https://github.com/ansible/ansible/labels/module)
もし似たようなPRが存在すれば、テストしてみてPRへのフィードバックを送ることも可能です。 これにより、そのPRがマージされるまでの期間が短くなる可能性があります。
3. Action Pluginで実現できないか?
モジュールの開発ではなく、プラグインにより望む機能が実現できる可能性があります。 プラグインの開発については、下記ページを確認してみてください。 https://docs.ansible.com/ansible/2.7/dev_guide/developing_plugins.html#developing-plugins
4. Roleで実現できないか?
既存のモジュールを組み合わせたRoleを使うことで、要望する機能が実現できる可能性があります。 Roleについては、下記ドキュメントを確認してください。 https://docs.ansible.com/ansible/2.7/user_guide/playbooks_reuse_roles.html#playbooks-reuse-roles
5. 単一のモジュールではなく、複数のモジュールを作ったほうがいいか?
複数の機能を持つ巨大なモジュールよりも、単一の機能をもつシンプルなモジュールを複数作ったほうがよい場合があります。 UNIX哲学に基づいて、一つのことをうまくやれるモジュールが望ましいです。
上記すべてにおいて、現在のAnsibleの機能では実現できない場合は、新しいモジュールを作ることを検討しましょう。
モジュールを作成する
こちらを確認しながら、新しいモジュールを作成していきます。 https://docs.ansible.com/ansible/2.7/dev_guide/developing_modules_general.html#starting-a-new-module
モジュールのフォーマットについては、下記を確認してください。 https://docs.ansible.com/ansible/2.7/dev_guide/developing_modules_documenting.html#module-format-and-documentation
Python shebang
すべてのAnsibleモジュールはかならず #!/usr/bin/python
から始まっている必要があります。
CopyrightとLicense
shebangのあとに、下記のようにCopyrightとLicenseのコメントを記載します。
#!/usr/bin/python # Copyright: (c) 2018, Terry Jones <terry.jones@example.org> # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
ANSIBLE_MATADATA block
shebangとcopyrightのセクションの後に、 ANSIBLE_METADATA
を定義する必要があります。
下記のように metadata_version
, status
, supported_by
を定義しましょう。
ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'}
上記で定義するフィールドの詳細については、下記を確認してください。 https://docs.ansible.com/ansible/2.7/dev_guide/developing_modules_documenting.html#ansible-metadata-fields
DOCUMENTATION block
Ansibleの公式ドキュメントに存在するModuleページのドキュメントは、この DOCUMENTATION
ブロックから生成されます。
DOCUMENTATION
ブロックはYAMLで定義されている必要があります。
ここで定義すべき内容については、下記を参照してください。
https://docs.ansible.com/ansible/2.7/dev_guide/developing_modules_documenting.html#documentation-fields
EXAMPLES block
DOCUMENTATION
ブロックに続けて、Moduleの書式を説明するEXAMPLESブロックを定義する必要があります。
下記のように、実際のPlaybookでの使用例を記載します。
EXAMPLES = ''' - name: Ensure foo is installed modulename: name: foo state: present '''
RETURN block
Moduleが返却する値の一覧を定義します。 下記を確認して、返却する値を定義してください。 https://docs.ansible.com/ansible/2.7/dev_guide/developing_modules_documenting.html#return-block
python imports
最後に、python importを記載します。 すべてのモジュールは、下記をimportする必要があります。
from module_utils.basic import AnsibleModule
下記のようなワイルドカードを使ったimportは許可されていないので注意してください。
from module_utils.basic import *
モジュールを作り込む
あとは自分が実現したい機能に応じて、Pythonで作り込んでいけばモジュールは作ることが出来ます。 GitHub上に存在する他のモジュールを参考にしながら進めるのがよいと思います。
その他
モジュールのPython3対応については、下記を確認してください。 https://docs.ansible.com/ansible/2.7/dev_guide/developing_python_3.html
最後に
Ansibleには数え切れないほどのモジュールが存在し、日々コミュニティによって開発が続けられています。 新規モジュールを作るだけではなく、既存モジュールへのPRやバグ報告などのコントリビュートは、今後のAnsibleの発展に必要不可欠です。 皆様もぜひ、一度気になるモジュールの中身を眺めてみて、どうやってモジュールが動いているのか調べてみるのもいいと思います。
モジュールをもっと深く知って、Happy Automation!