share facebook facebook2 twitter menu hatena pocket slack

2015.03.04 WED

Ansible の Dynamic Inventory を Consul で試す

川原 洋平

WRITTEN BY川原 洋平

ども、 cloudpackかっぱ (@inokara) です。

はじめに

Ansible に Dynamic Inventory という便利そうな機能があるらしいのでこれを Consul と絡めて試してみる。

参考

Dynamic Inventory

とは…

  • Inventory ファイルを動的に生成する
  • 生成するスクリプトは色々とある
  • オフィシャルでも Consul 用のスクリプトはあるけど手元の環境で動かなかった
  • もちろん AWS もサポートしている(ec2.py とか…)

以下のような JSON を出力するならどんな言語でも OK

ちなみに Inventory ファイルを生成するスクリプトは以下のような JSON を出力するのであればどんな言語でも OK のようだ。

{
    "databases"   : {
        "hosts"   : [ "host1.example.com", "host2.example.com" ],
        "vars"    : {
            "a"   : true
        }
    },
    "webservers"  : [ "host2.example.com", "host3.example.com" ],
    "atlanta"     : {
        "hosts"   : [ "host1.example.com", "host4.example.com", "host5.example.com" ],
        "vars"    : {
            "b"   : false
        },
        "children": [ "marietta", "5points" ]
    },
    "marietta"    : [ "host6.example.com" ],
    "5points"     : [ "host7.example.com" ]
}

スクリプト

残念ながら github 上の Python スクリプトは動かなかったのでこちらを参考にして以下のようなスクリプトを作ってみた。

#!/usr/bin/env ruby
require 'net/http'
require 'uri'
require 'json'

consul_url = 'http://localhost:8500/v1/catalog'
output = {}

s_json = JSON.parse(Net::HTTP.get_response(URI.parse("#{consul_url}/services")).body)
services = s_json.keys
services.each do |srv|
  res = Net::HTTP.get_response(URI.parse("#{consul_url}/service/#{srv}")).body
  json = JSON.parse(res)
  json.each do |node|
    t = {}
    output.merge!({ srv => [node['Address']] }) do |key,old,new|
      old | new
    end
  end
end

puts JSON.generate(output)

このスクリプトを適当に consul_inventory.rb という名前で保存して実行権限を付与する。試しに実行すると以下のように出力される。

{
    "consul": [
        "172.17.x.1",
        "172.17.x.2"
    ],
    "redis": [
        "172.17.x.1",
        "172.17.x.2"
    ],
    "redis-read": [
        "172.17.x.1",
        "172.17.x.2"
    ]
}

実行

以下のように -i フラッグの後にスクリプトを指定して以下のように実行する。

$ ansible -i consul_inventory.rb all -m ping

172.17.x.1 | success >> {
    "changed": false,
    "ping": "pong"
}

172.17.x.2 | success >> {
    "changed": false,
    "ping": "pong"
}

telnet をインストールする

telnet をインストールする。

$ ansible -i consul_inventory.rb all -m shell -a 'yum -y install telnet'

172.17.x.1 | success | rc=0 >>
Loaded plugins: fastestmirror
Setting up Install Process
Loading mirror speeds from cached hostfile
 * base: ftp.nara.wide.ad.jp
 * extras: ftp.nara.wide.ad.jp
 * updates: ftp.nara.wide.ad.jp
Resolving Dependencies
--> Running transaction check
---> Package telnet.x86_64 1:0.17-48.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package          Arch             Version                 Repository      Size
================================================================================
Installing:
 telnet           x86_64           1:0.17-48.el6           base            58 k

Transaction Summary
================================================================================
Install       1 Package(s)

Total download size: 58 k
Installed size: 109 k
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : 1:telnet-0.17-48.el6.x86_64                                  1/1
  Verifying  : 1:telnet-0.17-48.el6.x86_64                                  1/1

Installed:
  telnet.x86_64 1:0.17-48.el6

Complete!

172.17.x.2 | success | rc=0 >>
Loaded plugins: fastestmirror
Setting up Install Process
Loading mirror speeds from cached hostfile
 * base: mirror.fairway.ne.jp
 * epel: ftp.kddilabs.jp
 * extras: mirror.fairway.ne.jp
 * updates: mirror.fairway.ne.jp
Resolving Dependencies
--> Running transaction check
---> Package telnet.x86_64 1:0.17-48.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package          Arch             Version                 Repository      Size
================================================================================
Installing:
 telnet           x86_64           1:0.17-48.el6           base            58 k

Transaction Summary
================================================================================
Install       1 Package(s)

Total download size: 58 k
Installed size: 109 k
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : 1:telnet-0.17-48.el6.x86_64                                  1/1
  Verifying  : 1:telnet-0.17-48.el6.x86_64                                  1/1

Installed:
  telnet.x86_64 1:0.17-48.el6

Complete!

おお、これは簡単。

ということで

Ansible はあまり利用していないけど Dynamic Inventory 便利やな。

元記事はこちらです。
Ansible の Dynamic Inventory を Consul で試す