プロの現場で「Ansibleの既存モジュールだけではどうにもならない」という壁にぶつかったとき、多くのエンジニアはシェルスクリプトを書いて`command`や`shell`モジュールで無理やり解決しようとします。
しかし、それをやってしまうと「冪等性(何度実行しても結果が同じになること)」が崩壊し、運用は泥沼化します。
今日は、Ansibleの作法に則り、Pythonで「真に自動化された」カスタムモジュールを書くための、極めて実践的なガイドをお届けします。これをマスターすれば、あなたのインフラコードは「ただのスクリプト」から「堅牢なシステム」へと進化します。
—
1. なぜ「カスタムモジュール」なのか?
Ansibleの標準モジュール(`copy`, `yum`, `service`など)は強力ですが、自社の独自APIを叩いたり、複雑なレガシーシステムのステータスを判定したりする際には限界があります。
シェルスクリプトで実装すると、実行するたびに「変更がありました」と判定されたり、エラーハンドリングが不十分で構築に失敗したことに気づかなかったりします。Ansibleのカスタムモジュールを書くということは、Ansibleのエンジンに「この操作は、この条件の時に成功し、この時に変更とみなす」という知能を直接教え込むことなのです。
—
2. 環境セットアップ:まずはここから
カスタムモジュールは、AnsibleがPythonコードとして読み込める場所に配置します。ディレクトリ構造は以下のようにするのがベストプラクティスです。
my_project/
├── library/ # ここにカスタムモジュールを置く
│ └── my_custom.py
└── playbook.yml
`library/` という名前のディレクトリをプロジェクトルートに作れば、Ansibleは自動的にそれをカスタムモジュールの場所として認識します。
—
3. HelloWorld:カスタムモジュールの骨格
まずは、入力された値をそのまま返すだけの最小構成を作成します。`library/my_custom.py` を作成してください。
!/usr/bin/python
— coding: utf-8 —
from ansible.module_utils.basic import AnsibleModule
def run_module():
# 入力値の定義
module_args = dict(
name=dict(type=’str’, required=True),
enabled=dict(type=’bool’, default=False)
)
# モジュールの初期化(バリデーションを自動化してくれる!)
module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True
)
# 戻り値の準備
result = dict(
changed=False,
original_message=module.params[‘name’],
message=’Hello, ‘ + module.params[‘name’]
)
# ここにロジックが入る
module.exit_json(result)
if __name__ == ‘__main__’:
run_module()
ここがプロのポイント:
- `argument_spec`: ここで型や必須チェックを定義します。これで「値がない」「型が違う」という初歩的なミスをAnsibleが勝手に弾いてくれます。
- `AnsibleModule`: これがAnsibleの心臓部です。これを使うことで、JSONのパースからエラー出力までを統一されたインターフェースで行えます。
—
4. 実践:冪等性を担保するロジックの実装
次に、「ファイルが存在しなければ作成する」という、冪等性を担保した実装をしてみましょう。
# … 上記コードの続き …
import os
# 変更判定のフラグ
changed = False
path = “/tmp/my_custom_test.txt”
if not os.path.exists(path):
# 実際のアクション
with open(path, ‘w’) as f:
f.write(module.params[‘name’])
changed = True
result[‘changed’] = changed
result[‘path’] = path
module.exit_json(result)
このコードを実行すると、「一度目は `changed: true`」になり、「二度目は `changed: false`」になります。これこそが、IaCにおける「あるべき姿」です。
—
5. 現場で震えるほど役立つ運用Tips
1. `check_mode`への対応:
`supports_check_mode=True` を設定しておくと、`ansible-playbook –check` を実行した際に、実際にファイルを作らずに「作られるはずである」ことをシミュレートできます。これに対応しているモジュールは、現場で非常に重宝されます。
2. `fail_json`の活用:
エラーが発生したときは、必ず `module.fail_json(msg=”エラーメッセージ”)` を使ってください。これで、Ansibleのログに正しくエラーが記録され、後続のタスクが正しく中断されます。
3. デバッグ方法:
カスタムモジュールが期待通り動かない場合、`ansible-playbook -vvvv` で実行してください。JSONのやり取りがすべて可視化されるため、どこで詰まっているか一目瞭然です。
—
さあ、自動化の深淵へ
カスタムモジュールを書くことは、Ansibleという道具を「使う側」から「創る側」へと回る入り口です。最初は難しく感じるかもしれませんが、一度この作法を覚えてしまえば、どんな複雑なインフラ要件も、美しく、冪等なコードで制御できるようになります。
「面倒な手作業」を「コードによる芸術」に変えるその瞬間の快感を、ぜひ体験してください。応援しています!