このエントリーをはてなブックマークに追加

エクセルでAnsibleのホストを管理する

この記事はAnsible Advent Calendar 2013の24日分です。

注釈

これを書いた後に yamasakiさんがDynamic Inventoryを使ってみるというエントリーを公開しているのに気がついたのは秘密です。

みなさま、サーバーの管理はどうやっていますか?

もちろん、エクセルですよね(白目)

装飾はいろいろあるとして、超単純なものはこんな感じでしょうか。

../../../_images/excel-picture.png

Dynamic Inventory

Ansibleはinvenntoryというサーバーの属性を指定するファイルがあります。

通常はこんな感じのini形式のファイルです。

[web]
foo.example.com
bar.example.com

[db]
spam.example.com
egg.example.com
ham.example.com

しかし、このinventoryファイルに実行属性をつけてあげるとスクリプトと認識し、実行した結果をinventoryとして使用します。

ということで、以下のようなPythonスクリプトを使うことで、エクセルファイルをInventoryとして使うことができます。 xlrdが必要なので事前にpip install xlrdとしておきましょう。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import xlrd
import sys
import json

XLS_FILEPATH = '/path/to/host-list.xlsx'

book = xlrd.open_workbook(XLS_FILEPATH)  # エクセルファイルからBook作成
sheet = book.sheet_by_name(u"Sheet1")  # Sheet1を指定

hosts = {}  # ホスト一覧を格納する
host_vars = {}  # ホスト毎の属性を格納する

# ここから各行をループします
for row in range(1, sheet.nrows):  # 1からなのは最初のタイトル行をスキップするため
    if sheet.cell(row,0).value:
        group = sheet.cell(row,0).value  # 1列目のグループを取得

    if group not in hosts:
        hosts[group] = {"hosts": []}

    hostname = sheet.cell(row,1).value  # ホスト名取得
    hosts[group]["hosts"].append(hostname)  # ホスト一覧に追加

    host_vars[hostname] = {  # ホスト毎の属性に格納
        'ansible_ssh_host': sheet.cell(row,2).value,
        'ansible_ssh_user': sheet.cell(row,3).value,
        }

if sys.argv[1] == '--list':  # --listが付いているならホスト一覧を
    print json.dumps(hosts, sort_keys=True, indent=2)
else:
    hostname = sys.argv[2]   # それ以外であれば、当該ホストの属性を表示
    print json.dumps(host_vars[hostname], sort_keys=True, indent=2)

使い方は実行権限をつけておくだけで通常のInventoryファイル指定と同じです。

% chmod ugo+x xls-inventory.py  (実行権限付与)
% ansible-playbook -i xls-inventory.py ham.yml

仕様

inventoryスクリプトはJSONを書き出せる必要があります。その仕様は以下のとおりです。この仕様に沿っていればどんな言語で書かれていても動作します。

引数として以下の2種類を受け取ります。

  • --list
  • --host <ホスト名>

list

--listの場合は以下のようにグループごとにそのグループに属するホストのリストを用意しておきます。

{
  "Staging": {      グループ名
    "hosts": [      'hosts'決め打ち
      "example-C",  ホスト名
      "localhost"
    ]
  },
  "Web": {
    "hosts": [
      "example-A",
      "example-B"
    ]
  }
}

host

--hostの場合はさらにホスト名を取り、こういう結果を返します。これはホストごとの設定と同じですね。

{
  "ansible_ssh_host": "192.168.1.11",
  "ansible_ssh_user": "worker"
}

まとめ

今回はスクリプトによる動的なInventoryの作成について述べました。

これでエクセルの管理台帳でも大丈夫ですね!(白目)

もちろん、LDAPから取ったりChefサーバーから取ったりといった使い方も可能です。