Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Deep Dive into Modules
JULY TECH FESTA 2015 1
whoami
齊藤 秀喜(さいとう ひでき) / TwitterID: @saito_hideki
日本OpenStackユーザ会
株式会社インターネットイニシアティブ
著書
OpenStackクラウドインテグレーション
ISBN: 9784798141251
2
Agenda
• 本日のテーマ
• Ansibleとは
• モジュールの仕組み
• モジュールを開発する
3
トピック
★ 対象とするもの
• Ansibleの簡単な紹介
• Ansibleの仕組みの中核であるモジュールについての解説
• モジュールの作成・テスト方法
★ 対象外とするもの
• Ansibleそのもの
• モジュール以外の構成要素
4
本日のテーマ
Ansibleが行うさまざまな仕事を実現しているのがモ
ジュールです。
本セッションでは、このモジュールに焦点をあてて、
その構造や開発方法について、少し掘り下げて紹介し
ます。
5
Ansibleとは
6
Configuration
Management Tool
Ansibleは、シンプルで使い勝手の良いCMTです
オペレーションの自動化 システムの構成管理
7
Ansibleとは
★ 何をしてくれるのか?
• システムの構成管理を比較的容易に実現できる
• システムの設定やテストなどのオペレーションを自動化できる
★ 利点
• エージェントレス
• 操作対象ノードの増減など環境変化にも柔軟に対応可能
• シンプルな構成ゆえに拡張性が高い
• デフォルトで多くの操作モジュールが付属している(BATTERIES INCLUDED)
• AWSやOpenStackなどのクラウド基盤管理システムとの親和性が高い
• ドキュメントが充実している
★ 欠点
• リリース頻度が高く落ち着かない
• Windows対応が弱い
• スケールさせるには工夫が必要
8
6つの構成要素
本セッションで関係するのは5つ
1. コマンドラインインターフェイス
2. 設定ファイル
3. インベントリ/ダイナミックインベントリ
4. モジュール
5. プラグイン
6. Playbook
9
BATTERIES
INCLUDED
10
モジュールの定義
モジュールは、ansibleコマンドやansible-playbookコマン
ドから利用されるプログラムで、その役割は、大きく以下
の2つです。
Ansibleには標準で数多くのモジュールが付属しています。
1. 対象ノードの情報を収集する(gathering)
他のモジュールから再利用する目的で、操作対象ノードの情報
を取得する
2. 対象ノードを操作する(do something)
設定ファイルの配置や、パッケージのインストール、システム
の再起動などのさまざまな操作を行う
11
実行に必要な要素は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
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
対象ノードの情報を収集する
[例] 対象ホストの情報を収集する
$ 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
対象ノードを操作する
[例] ホスト名を変更(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
モジュールの実行
Ansibleが標準提供するCoreやExtrasモジュールはPythonで
記述されています。
これらのモジュールを利用した構成管理の流れは以下の通り
です。
モジュール
実行可能
プログラム
実行
掃除
変換 転送
コントロールノード ターゲットノード
17
デモ
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
モジュールを書いてみる
モジュールの働きを理解するために、現在の時刻を取得する
timetestモジュールを書いて実行してみましょう。
#!/usr/bin/env python
import datetime
import json
date = str(datetime.datetime.now())
print json.dumps({
"time": date
})
20
モジュールを実行してみる
[単体実行]
$ 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
生成される実行プログラム
シェル変数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
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
引数はどうなるの?
$ 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
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
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
lib/ansible/module_utils/basic.py
Ansibleは、モジュールに必要となる基本的な機能をライブ
ラリとして提供しています。
basic.pyには、モジュールの骨子となるAnsibleModuleクラ
スと、モジュールの振る舞いを決めるために利用できる便利
な関数があらかじめ定義されています。
モジュールから生成される実行可能プログラムは、基本的に
それ単体(1ファイル)で動作することが推奨されています。
basic.pyが提供しているコードは、モジュールから生成す
る実行可能プログラムにインライン展開される仕組みになっ
ており、実行可能プログラムの単独動作を実現しています。
28
標準モジュールに準拠させる(1/2)
自作モジュールをAnsibleの本家に取り込んでもらうには、
最低限、以下の3つの条件を満たしている必要があります。
1. DOCUMENTATION変数に概要説明を定義
2. EXAMPLES変数にモジュールの利用例を定義
3. AnsibleModuleクラスを利用する
注意) ansible.module_utils.basicは*でインポートする
29
標準モジュールに準拠させる(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
ドキュメンテーション
モジュールコード中の、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
標準モジュールでの
引数の扱い
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
常に実弾演習?
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
まとめ
本日お話したことを以下にまとめます。
★ Ansibleのモジュールの働き
★ モジュールが実行される過程と、その確認方法について
★ 自分でモジュールを書く方法
★ 標準モジュールとして必要な要件
★ テスト方法
Ansibleは数多くの機能を標準モジュールとして提供してい
ますが、求める機能がその中になければ、自作することも可
能です。
35
あれば使う・なければ作る
★ さまざまな機能を提供するモジュール群が標準提供
されています
★ しかし、あなたが必要とする全ての機能をカバーし
ているわけではありません
★ あれば使う・なければ作るの精神で、Ansibleを
構成管理フレームワークとして活用しましょう!
36
参考
★ Developing Modules
Ansibleの公式モジュール開発ガイド
• [本家]
http://docs.ansible.com/ansible/developing_modules.html
• [勝手な和訳]
http://tzpst.hatenablog.com/entry/2015/07/21/175159
37
ご静聴ありがとうございました
JULY TECH FESTA 2015 38

More Related Content

Deep Dive into Modules