Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Deep Dive into Modules

4,906 views

Published on

July Tech Festa 2015での講演資料です。
Ansibleのモジュールの仕組みや開発方法について、ちょっと掘り下げて話しています。

Published in: Technology

Deep Dive into Modules

  1. 1. Deep Dive into Modules JULY TECH FESTA 2015 1
  2. 2. whoami 齊藤 秀喜(さいとう ひでき) / TwitterID: @saito_hideki 日本OpenStackユーザ会 株式会社インターネットイニシアティブ 著書 OpenStackクラウドインテグレーション ISBN: 9784798141251 2
  3. 3. Agenda • 本日のテーマ • Ansibleとは • モジュールの仕組み • モジュールを開発する 3
  4. 4. トピック ★ 対象とするもの • Ansibleの簡単な紹介 • Ansibleの仕組みの中核であるモジュールについての解説 • モジュールの作成・テスト方法 ★ 対象外とするもの • Ansibleそのもの • モジュール以外の構成要素 4
  5. 5. 本日のテーマ Ansibleが行うさまざまな仕事を実現しているのがモ ジュールです。 本セッションでは、このモジュールに焦点をあてて、 その構造や開発方法について、少し掘り下げて紹介し ます。 5
  6. 6. Ansibleとは 6
  7. 7. Configuration Management Tool Ansibleは、シンプルで使い勝手の良いCMTです オペレーションの自動化 システムの構成管理 7
  8. 8. Ansibleとは ★ 何をしてくれるのか? • システムの構成管理を比較的容易に実現できる • システムの設定やテストなどのオペレーションを自動化できる ★ 利点 • エージェントレス • 操作対象ノードの増減など環境変化にも柔軟に対応可能 • シンプルな構成ゆえに拡張性が高い • デフォルトで多くの操作モジュールが付属している(BATTERIES INCLUDED) • AWSやOpenStackなどのクラウド基盤管理システムとの親和性が高い • ドキュメントが充実している ★ 欠点 • リリース頻度が高く落ち着かない • Windows対応が弱い • スケールさせるには工夫が必要 8
  9. 9. 6つの構成要素 本セッションで関係するのは5つ 1. コマンドラインインターフェイス 2. 設定ファイル 3. インベントリ/ダイナミックインベントリ 4. モジュール 5. プラグイン 6. Playbook 9
  10. 10. BATTERIES INCLUDED 10
  11. 11. モジュールの定義 モジュールは、ansibleコマンドやansible-playbookコマン ドから利用されるプログラムで、その役割は、大きく以下 の2つです。 Ansibleには標準で数多くのモジュールが付属しています。 1. 対象ノードの情報を収集する(gathering) 他のモジュールから再利用する目的で、操作対象ノードの情報 を取得する 2. 対象ノードを操作する(do something) 設定ファイルの配置や、パッケージのインストール、システム の再起動などのさまざまな操作を行う 11
  12. 12. 実行に必要な要素は3つ 1. ansibleコマンド 2. インベントリファイル 3. モジュール [書式] ansible <ホストパターン> -i <インベントリファイル> -m <モジュール> [実行例] $ ansible web -i ansible_hosts -m setup $ ansible 192.168.0.1 -i ansible_hosts -m hostname -a name=hogehoge -u vagrant -k -s 12
  13. 13. ansibleコマンドの動き 1.インベントリ内で、ホストパターンにマッチするノー ドをリストアップする => ターゲットノード 2.ターゲットノードに対してモジュールを適用する [localhost] 127.0.0.1 ansible_connection=local [test] 192.168.0.1 ansible_connection=ssh 192.168.0.2 ansible_connection=ssh 192.168.0.3 ansible_connection=ssh [web] web0[0:3] ansible_connection=ssh インベントリファイル [localhost] 127.0.0.1 ansible_connection=local [test] 192.168.0.1 ansible_connection=ssh 192.168.0.2 ansible_connection=ssh 192.168.0.3 ansible_connection=ssh [web] web0[0:3] ansible_connection=ssh ホストパターン=> web webグループにマッチ 13
  14. 14. 対象ノードの情報を収集する [例] 対象ホストの情報を収集する $ ansible localhost -i ansible_hosts -m setup 127.0.0.1 | success >> { "ansible_facts": { "ansible_all_ipv4_addresses": [ …(中略)… ], "ansible_all_ipv6_addresses": [ …(中略)… ], "ansible_architecture": “x86_64", …(中略)… }, "module_setup": true }, "changed": false } 収集したホストの情報は、ansible_*変数に代入される。 Playbookでは、この変数を他のモジュールから再利用可能。 14
  15. 15. 対象ノードを操作する [例] ホスト名を変更(web00->foo)する $ ansible web00 -i ansible_hosts -m hostname -a name=foo -u vagrant -k -s SSH password: ******** web00 | success >> { "changed": true, "name": "foo" } ホスト名が変更された場合はtrue 変更されなかった場合はfalse 現在のホスト名は”foo” どのような実行結果を返すのかは、モジュール の作り方しだい。 15
  16. 16. モジュールの仕組み 16
  17. 17. モジュールの実行 Ansibleが標準提供するCoreやExtrasモジュールはPythonで 記述されています。 これらのモジュールを利用した構成管理の流れは以下の通り です。 モジュール 実行可能 プログラム 実行 掃除 変換 転送 コントロールノード ターゲットノード 17
  18. 18. デモ 2台のホストをAnsibleから操作してみます。 1. setupモジュールによる情報収集 $ ansible members -i ansible_hosts -m setup 2. commandモジュールによる任意のコマンド実行 $ ansible members -i ansible_hosts -m command -a ‘uname -a’ 3. hostnameモジュールによるホスト名の変更 $ ansible members -i ansible_hosts -m hostname -a ‘name=foo’ -s 18
  19. 19. 本題:モジュールを開発する 19
  20. 20. モジュールを書いてみる モジュールの働きを理解するために、現在の時刻を取得する timetestモジュールを書いて実行してみましょう。 #!/usr/bin/env python import datetime import json date = str(datetime.datetime.now()) print json.dumps({ "time": date }) 20
  21. 21. モジュールを実行してみる [単体実行] $ python timetest {"time": "2015-07-23 16:39:22.283407”} [モジュールとして実行] $ ansible localhost -i ansible_hosts --module-path . -m timetest 127.0.0.1 | success >> { "time": "2015-07-23 16:52:29.755416" } 21
  22. 22. 生成される実行プログラム シェル変数ANSIBLE_KEEP_REMOTE_FILESを1にセットし てansibleコマンドを実行すると… $ export ANSIBLE_KEEP_REMOTE_FILES=1 $ ansible localhost -i ansible_hosts -M . -m timetest -mで指定したモジュールから生成された実行可能プログラ ムは、$HOME/.ansible/tmp/に配置されます。 通常、このプログラムは実行後に削除されますが、 ANSIBLE_KEEP_REMOTE_FILESに1がセットされている場 合は、削除されずに残ります。 22
  23. 23. timetestモジュールの 実行可能プログラム 自作したtimetestモジュールと、Ansibleが生成した実行可能 プログラムを確認してみると、内容に差異がなく、そのまま 転送されて実行されているようです。 [モジュール] $ md5 timetest MD5 (timetest) = ca381d31af18e5bce5d6e4e260362062 [実行可能プログラム] $ md5 ~/.ansible/tmp/ansible-tmp-1437633590.03-115993239580867/timetest MD5 (/Users/saitou/.ansible/tmp/ansible-tmp-1437633590.03-115993239580867/ timetest) = ca381d31af18e5bce5d6e4e260362062 23
  24. 24. 引数はどうなるの? $ ansible 192.168.0.1 -i ansible_hosts -M . -m timetest2 -a time=072411352015.45 -u saitou -k -K -s SSH password: ******** SUDO password[defaults to SSH password]: ******** 192.168.0.1 | success >> { "changed": true, "time": "2015-07-24 11:35:45.001731" } モジュールの引数は、実行可能プログラムと同じディレクトリにあ るargumentsファイルに文字列として格納されます。 $ cd ~/.ansible/tmp/ansible-tmp-1437705347.69-147453231832727 $ ls arguments timetest2 $ cat arguments time=072411352015.45 24
  25. 25. pingモジュールの 実行可能プログラム [モジュール] $ wc ansible/lib/ansible/modules/core/system/ping.py 61 235 1702 ansible/lib/ansible/modules/core/system/ping.py [実行可能プログラム] $ wc ~/.ansible/tmp/ansible-tmp-1437620077.92-75246064236647/ping 1665 6089 63273 ~/.ansible-tmp-1437620077.92-75246064236647/ping ファイルサイズ激増 何かいろいろとやっていそう Ansibleの標準モジュールは、ちょっと違います。 25
  26. 26. この差は何!? 26
  27. 27. pingモジュールの コードを読んでみる import exceptions def main(): module = AnsibleModule( argument_spec = dict( data=dict(required=False, default=None), ), supports_check_mode = True ) result = dict(ping='pong') if module.params['data']: if module.params['data'] == 'crash': raise exceptions.Exception("boom") result['ping'] = module.params['data'] module.exit_json(**result) from ansible.module_utils.basic import * main() このあたりが あきらかに怪しい 27
  28. 28. lib/ansible/module_utils/basic.py Ansibleは、モジュールに必要となる基本的な機能をライブ ラリとして提供しています。 basic.pyには、モジュールの骨子となるAnsibleModuleクラ スと、モジュールの振る舞いを決めるために利用できる便利 な関数があらかじめ定義されています。 モジュールから生成される実行可能プログラムは、基本的に それ単体(1ファイル)で動作することが推奨されています。 basic.pyが提供しているコードは、モジュールから生成す る実行可能プログラムにインライン展開される仕組みになっ ており、実行可能プログラムの単独動作を実現しています。 28
  29. 29. 標準モジュールに準拠させる(1/2) 自作モジュールをAnsibleの本家に取り込んでもらうには、 最低限、以下の3つの条件を満たしている必要があります。 1. DOCUMENTATION変数に概要説明を定義 2. EXAMPLES変数にモジュールの利用例を定義 3. AnsibleModuleクラスを利用する 注意) ansible.module_utils.basicは*でインポートする 29
  30. 30. 標準モジュールに準拠させる(2/2) #!/usr/bin/python import datetime DOCUMENTATION = ''' module: timetest version_added: 1.9.2 short_description: Get date and time description: - Get date and time on target node options: {} author: - "Hideki Saito" ''' EXAMPLES = ''' # Get date and time ansible target -m timetest ''' def main(): module = AnsibleModule(argument_spec={}) date = dict(now=str(datetime.datetime.now())) module.exit_json(**date) from ansible.module_utils.basic import * main() 本家にPull Requestするなら このような形式が必須です 30
  31. 31. ドキュメンテーション モジュールコード中の、DOCUMENTとEXAMPLESに書いた 概要や利用例は、ansible-docコマンドで利用されます。 [例] timetestモジュールのドキュメントを読む $ ansible-doc -M . timetest [実行結果] > TIMETEST Get date and time on target node EXAMPLES: # Get date and time ansible target -m timetest DOCUMENTATION に定義した概要説明 EXAMPLESに定義し た利用例 31
  32. 32. 標準モジュールでの 引数の扱い Ansible ver1.9の場合、モジュールのオプションとして指定 されたパラメータは、実行可能プログラムのMODULE_ARGS に文字列として展開されます。 [例] statモジュールで指定したオプションの展開例 $ ansible localhost -i ansible_hosts -m stat -a "path=/etc/hosts get_md5=no get_checksum=no” [展開例] 実行可能プログラム中のMODULE_ARGS #!/usr/bin/python …(中略)… MODULE_ARGS = 'path=/etc/hosts get_md5=no get_checksum=no’ …(以下略)… 32
  33. 33. モジュールのテスト 33
  34. 34. 常に実弾演習? Ansibleは、モジュールのテストスクリプト(test-module)を提供しています。 モジュールのテストには、test-moduleスクリプトを利用しましょう。 $ git clone git@github.com:ansible/ansible.git --recursive $ source ansible/v1/hacking/env-setup $ ansible/v1/hacking/test-module -m ./timetest * including generated source, if any, saving to: .ansible_module_generated * this may offset any line numbers in tracebacks/debuggers! *********************************** RAW OUTPUT {"now": "2015-07-24 17:31:38.794721", "changed": false} *********************************** PARSED OUTPUT { "changed": false, } 34
  35. 35. まとめ 本日お話したことを以下にまとめます。 ★ Ansibleのモジュールの働き ★ モジュールが実行される過程と、その確認方法について ★ 自分でモジュールを書く方法 ★ 標準モジュールとして必要な要件 ★ テスト方法 Ansibleは数多くの機能を標準モジュールとして提供してい ますが、求める機能がその中になければ、自作することも可 能です。 35
  36. 36. あれば使う・なければ作る ★ さまざまな機能を提供するモジュール群が標準提供 されています ★ しかし、あなたが必要とする全ての機能をカバーし ているわけではありません ★ あれば使う・なければ作るの精神で、Ansibleを 構成管理フレームワークとして活用しましょう! 36
  37. 37. 参考 ★ Developing Modules Ansibleの公式モジュール開発ガイド • [本家] http://docs.ansible.com/ansible/developing_modules.html • [勝手な和訳] http://tzpst.hatenablog.com/entry/2015/07/21/175159 37
  38. 38. ご静聴ありがとうございました JULY TECH FESTA 2015 38

×