RightScaleで生成したEC2インスタンスを動的にCapistranoのRoleにセットする拡張書いた

CapistranoはDeployツールですが、これを使用すると複数のサーバを効率的に管理できます。
通常は設定ファイルに管理するサーバのホスト名またはIPアドレスをroleと呼ばれるものとセットで記述するのですが、
EC2インスタンスは意外とよく落ちるのでその度にホストを書き換えなければなりません。

EC2インスタンスをRightScaleというWebベースの管理ツールを使用して管理しているのですが、
これを使用すると、起動時の初期セットアップを自動化できたりインスタンスをグループ化したり、インスタンスに名前をつけたりすることが可能で管理がずいぶん楽になります。

また、APIも公開されているためこのAPIを使って管理を自動化することも可能です。

題名のCapistranoの拡張書いたのはずいぶん前なのですが、RightScaleを使ってEC2インスタンスを管理している場合
APIを使ってEC2インスタンスの一覧が取得できるのでこれを使用してCapistranoのRoleを動的にセットするような機能をつけました。

ここではその使い方を備忘録として記録しておきたいと思います。

前提

  • RightScaleを使用してEC2インスタンスを管理していること
  • それらのインスタンスは、RightScaleのDeploymentと呼ばれる単位でグループ化していること
  • RightScaleのServerArray(Auto Scaling機能)の使用有無は問わない
  • Capistranoをインストールしたホストから管理対象のインスタンスSSH接続可能になっていること

環境

  • CentOS5.4
    • AMIはRightImage_CentOS_5.4_x64_v5.6.28あたりを使用(RightScaleのTag機能が使えればOK)
  • Capistrano v2.5.1(capistrano-extとかは必要ならインストール)
  • Ruby v1.8.5

インストール

RightScaleのAMIを使用すれば必要なものはだいたいインストールされているので、足りないものをインストールします。

1. 必要なPackageのインストール

ruby-develが必要なのでインストール

$ sudo yum install ruby-devel


rubygemsはyumでインストールするよりも新しいバージョンがあらかじめインストールされているのでそっちを使います。

2. capistranoのインストール

capistrano本体と今回開発した拡張: cap-rightscaleをインストールします。
下記のコマンドで一緒に入ります。

$ sudo gem install cap-rightscale
$ sudo gem install capistrano-ext #必要であればインストール

動作確認

簡単な設定は下記の通りです。

  • RightScale認証情報の設定

capistrano実行ユーザのホームディレクトリに''.rsconf''を作成し、下記の形式でファイルを作成します。
ツールで使用するRightScaleのユーザを別途作成した方がいいでしょう。

$ mkdir $HOME/.rsconf
$ vim $HOME/.rsconf/rsapiconfig.yml
# rsapiconfig.yml
username: user@example.com  #RightScaleのログインID
password: yourpassword      #RightScaleのログインパスワード
account: 1                  #RightScaleのAccountページのURL末尾の番号
  • capifyを実行して必要なファイルの生成
$ cd work/cap_test
$ capify .
  • deploy.rbの編集
$ vim config/deploy.rb


下記のように書き換えます。

# config/deploy.rb
require 'rubygems'
require 'cap-rightscale'
require 'cap-rightscale/recipes'

DEPLOYMENT_ID = xxxxx       # RightScale Deployment IDを指定します。(RightScaleの該当のDeploymentページのURLの末尾の番号)
SERVER_ARRAY_ID = xxxx      # RightScale ServerArray IDを指定します。(RightScaleの該当のServerArrayページのURLの末尾の番号)

# set roles
nickname :web, :name_prefix => "lb", :deployment => DEPLOYMENT_ID
server_array :app, :array_id => SERVER_ARRAY_ID
tag :dbm, :tags => "xx_db:role=master", :deployment => DEPLOYMENT_ID
tag :dbs, :tags => "xx_db:role=slave", :deployment => DEPLOYMENT_ID, :no_release => true


Roleをセットするメソッドを3種類あるのですが、

  • nicknameで指定すると、指定したDevploymentの範囲内で、RightScaleで設定した名前(nickname)が:name_prefixに部分一致するインスタンス
  • server_arrayで指定すると、RightScaleで作成した該当のIDを持つServerArrayの現在起動しているインスタンス
  • tagで指定すると、指定したDevploymentの範囲内で、RightScaleでインスタンスにつけた指定のtagを持つインスタンス

が設定されます。

設定通りインスタンスがセットされるかどうかは、下記のコマンドで確認できます。

$ cap rs:none

使い方

通常のCapistranoの使い方と同じです。
RightScaleAPIから取得したインスタンスのリストをキャッシュしているのですが、そのキャッシュをクリアするTaskを追加しています。
キャッシュの有効期限はデフォルトでは1日ですが、設定で変更可能です。

キャッシュのクリア
$ cap rs:cache:clear
OR
$ cap rs:cc
キャッシュを使用しない
$ cap invoke COMMAND='hostname' RS_CACHE=false

設定など

Role定義
  • RightScaleのnicknameでRoleをセット
# config/deploy.rb

# Deployment ID:12345でグループ化しているインスタンスのうち、RightScaleのnickname: ''lb''に一致するものをRole '':web''にセットする
nickname :web, :name_prefix => "lb", :deployment => 12345
#=> 通常のCapistranoの設定だと: role :web, *%w[lb-001 lb-002 lb-003]
  • RightScaleのServerArray(Auto scaling)でRoleをセット
#RightScaleのServerArray(Auto scaling) ID:6789で管理しているインスタンスをRole'':app''にセットする
server_array :app, :array_id => 6789, :backup => true
#=> 通常のCapistranoの設定だと: role(:app, :backup => true) { %w[web-001 web-002 web-003] }
  • RightScaleのTagでRoleをセット
#RightScaleのTag: "xx_db:env=prod", "xx_db:role=master"が設定されているインスタンスをRole'':dbm''にセットする
tag :dbm, :name_prefix => "db", :tags => ["xx_db:env=prod", "xx_db:role=master"], :deployment => 12345, :primary => true
#=> 通常のCapistranoの設定だと: role(:dbm, :primary => true) { %w[db-001 db-002] }^4
キャッシュ設定

下記の設定により、キャッシュの有効期限を変更することが可能です。

  • キャッシュ保持時間変更
# config/deploy.rb
set :rs_lifetime, 86400         # 1日(default)
set :rs_lifetime, 86400 * 7     # 1週間
set :rs_lifetime, 7200          # 2時間
set :rs_lifetime, 0             # 無効
rs_disable :use_rs_cache        # 同じく無効
set :rs_lifetime, -1            # 無期限
Roleにセットするホスト情報

デフォルトではAmazonEC2 Local IP address(10.から始まる)を使用します。

rs_enable :use_public_ip        # EC2 Public IP addressを使用する場合
rs_enable :use_nickname         # RightScaleのnicknameをそのまま使う(DNSやhostsファイルによる名前解決の設定が事前に必要)


ServerArray(Auto scaling機能)で起動する各インスタンスのnicknameの末尾には''[スペース]#番号''が付与されるので、nicknameをDNSホスト名に置き換えるには工夫する必要があります。
nickname: ''web #1'' => DNS hostname: ''web-001''に変換している場合は、Capistranoでは下記のように設定します。

rs_array_number_format "-%03d"  # sprintf formatを使って変換後の書式を指定
Validate

無効なホストを除外するために、pingによる死活確認とDNSにホストが登録されているかどうかをチェックすることができます。
ただし、既にインスタンスがキャッシュされている場合は実行しませんので、キャッシュクリアする必要があります。

rs_enable :validate_echo, :validate_resolv
#=> :validate_echo[ハングアップしたホストを除外]
#=> :validate_resolv[名前解決できないホストを除外]

おわりに

RightscaleAPIを使うとインスタンスの管理を自動化するツールを作成することが可能です。
このほかにも、Nagiosのホスト設定の自動化やPuppetのmanifest適用制御を行ったりと様々のことができます。

このcapistrano拡張で、自分で作成したRubyで書いたRightScaleAPIのWrapperライブラリを使用しているのですが、その頃はRubyとか全くわかっていなかった時期に作ったので
Mixinって何? メタプログラミングすぎて解読できなくてつらい...とかでいろいろ妥協した部分があるため、今度どっかで使用することになったら書き直したいなと思ってます。