LoginSignup
4
3

More than 5 years have passed since last update.

Ansibleモジュールのサンプルコードを実行してみた

Last updated at Posted at 2015-05-23

ansibleで動作するモジュールを自作する方法を調べてみました。参考にしたのは、docs.ansible.com の Developing Modules です。掲載されているpythonのサンプルコードを実際に動かして、モジュールの挙動を確認してみました。実行環境は CentOS 7 + ansible 1.9.1 です。

モジュール配置先パスの設定

モジュールの配置先のパスを /etc/ansible/ansible.cfg に記述します。
"library = 配置先ディレクトリ" の行を追加します。

[記述例]

[defaults]
inventory               = /etc/ansible/hosts
library                 = /root/ansible/modules/    # 追加

サンプルコードの作成

Developing Modules に掲載されているサンプルコード(time.py)を ansible.cfg で記載したモジュール配置先に作成します。

$ vi /root/ansible/modules/time.py

サンプルコードの内容は以下の通りです。datetimeモジュールを呼び出して、現在時刻の設定や取得を行うことができます。必要なクラスのインポート、モジュールに渡されるパラメタの解析方法、処理結果の出力方法など、基本的な手続きがコメント付きで記述されています。

#!/usr/bin/python

# import some python modules that we'll use.  These are all
# available in Python's core

import datetime
import sys
import son
import os
import shlex

# read the argument string from the arguments file
args_file = sys.argv[1]
args_data = file(args_file).read()

# for this module, we're going to do key=value style arguments
# this is up to each module to decide what it wants, but all
# core modules besides 'command' and 'shell' take key=value
# so this is highly recommended

arguments = shlex.split(args_data)
for arg in arguments:

    # ignore any arguments without an equals in it
    if "=" in arg:

        (key, value) = arg.split("=")

        # if setting the time, the key 'time'
        # will contain the value we want to set the time to

        if key == "time":

            # now we'll affect the change.  Many modules
            # will strive to be 'idempotent', meaning they
            # will only make changes when the desired state
            # expressed to the module does not match
            # the current state.  Look at 'service'
            # or 'yum' in the main git tree for an example
            # of how that might look.

            rc = os.system("date -s \"%s\"" % value)

            # always handle all possible errors
            #
            # when returning a failure, include 'failed'
            # in the return data, and explain the failure
            # in 'msg'.  Both of these conventions are
            # required however additional keys and values
            # can be added.

            if rc != 0:
                print json.dumps({
                    "failed" : True,
                    "msg"    : "failed setting the time"
                })
                sys.exit(1)

            # when things do not fail, we do not
            # have any restrictions on what kinds of
            # data are returned, but it's always a
            # good idea to include whether or not
            # a change was made, as that will allow
            # notifiers to be used in playbooks.

            date = str(datetime.datetime.now())
            print json.dumps({
                "time" : date,
                "changed" : True
            })
            sys.exit(0)

# if no parameters are sent, the module may or
# may not error out, this one will just
# return the time

date = str(datetime.datetime.now())
print json.dumps({
    "time" : date
})

ansibleコマンドによるサンプルモジュールの実行

モジュールは処理対象のサーバに転送されてから実行され、その結果がjson形式で返されます。

・現在時刻の取得

パラメタを指定せずにモジュールを実行すると、現在時刻が json形式で出力されます。

[実行例]

$ ansible localhost -m time -k
SSH password: 
localhost | success >> {
    "time": "2015-05-23 21:50:50.921787"
}

・現在の設定

パラメタとして、-a オプションで時刻を指定して実行すると、モジュール内で "date -s" コマンドを実行してから、datetimeモジュールで変更後の時刻を取得し、その結果が json形式で出力されます。

[実行例]

$ ansible localhost -m time -k -a "time=21:50:50"
SSH password: 
localhost | success >> {
    "changed": true, 
    "time": "2015-05-23 21:50:50.006286"
}

 この場合、実行結果に "changed": true と表示されますが、これは時刻変更が行われたことを示すためのものです。

・エラー発生時の動作

パラメタとして、-a オプションで不正な値(時刻ではない文字列)して実行すると、モジュール内での "date -s" コマンドの実行が失敗し、実行結果として以下のようなエラー情報が出力されます。

[実行例]

# ansible localhost -m time -k -a "time=hoge"
SSH password: 
localhost | FAILED >> {
    "failed": true, 
    "msg": "failed setting the time"
}

 この場合、実行結果に "failed": true と表示されますが、これは処理が失敗したことを示すためのものです。また、"msg": には処理が失敗した理由を出力します。

playbook によるサンプルモジュールの実行

サンプルモジュールをplaybookから実行する場合は、playbookを以下のように記述します。

[記述例]

---
- hosts: "{{ target }}"
  tasks:
  - name: set time
    time: time="{{ time }}"

 tasks: セクションに実行するモジュール名 "time" と モジュールに渡すパラメータ "time="{{ time }}" を記述します。

playbookを実行する際には、-e オプションでモジュールを実行するノード(target)と設定する時刻(time)を指定します。

[実行例]

$ ansible-playbook time.yml -k -e "target=localhost time=23:27:00"
SSH password: 

PLAY [localhost] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [localhost]

TASK: [set time] ************************************************************** 
changed: [localhost]

PLAY RECAP ******************************************************************** 
localhost                  : ok=2    changed=1    unreachable=0    failed=0   

playbookの実行結果でモジュールの実行結果のサマリが出力されます。

おまけ

サンプルモジュールのテストが済んだら、NTPで時刻を正しい値に戻しておく事を強くお勧めします:sweat_smile:

$ ntpdate time.asia.apple.com
4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3