LoginSignup
18

More than 5 years have passed since last update.

Capistrano 3とaws-sdk 2でELB配下にあるインスタンスへデプロイする奴

Last updated at Posted at 2015-03-18

概要

私はAWSへCapistrano 3を使ってCircle CIで自動デプロイしています。
サーバが1台の時はCapistranoの設定ファイルにデプロイ先のサーバIP直書きでも良いのですが(良いのか?)、ここでAutoScalingに対応してELB配下にあるインスタンス全部へ自動デプロイしたいとなりました。(ちなみにインスタンスの立ち上げからの自動デプロイはBootStrapパターンを使用しています)
Gemやらあるかなと思ったのですが、現在のCapistrano 3およびaws-sdk 2に対応していて鉄板なものが見つからず、社内制手工業で依存が少なく安心して使えるものを書きました。

実際の方法

Gemの設定

2015/03/18現時点で最新のaws-sdk 2系を使います。

Gemfile
group :development do
  gem 'aws-sdk'
end

aws-sdkのrequire

そしてちょっとハマりどころなのですが、aws-sdk 2で定義されているメソッドがcapistrano 3で定義されているメソッドとコンフリクトしてエラーが出るので、それを回避するために以下をCapfile冒頭に加えます。(capistrano3とaws-sdk v2を組み合わせるとDefinitionErrorにハマった話に助けられました、ありがとうございます ( _ _))

Capfile
require 'aws-sdk'
Aws::EC2::Resource

環境変数の設定

で、aws-sdkを使うために以下の環境変数を設定してあげます。

AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_access_key
AWS_REGION=ap-northeast-1 (this is for tokyo region)

デプロイ時、ELB配下にあるインスタンスをデプロイ先に設定するコードを追加

最後に任意のdeploy設定ファイルに以下を加え完成です。Capistranoの設定ファイルは言語内DSLなので、こういう作業も楽ちんです。以下のSampleLoadBalancerNameは目的のロードバランサの名前に置き換えてください。環境変数にしてしまうのも良いと思います。

ここではInService状態のインスタンスにのみデプロイするようにしています。

config/deploy/production.rb
elasticloadbalancing = Aws::ElasticLoadBalancing::Client.new
instance_states = elasticloadbalancing.describe_instance_health(load_balancer_name: 'SampleLoadBalancerName').instance_states

target_instance_ids = []
instance_states.each do |instance_state|
  target_instance_ids.push instance_state.instance_id if instance_state.state == 'InService'
end

ec2 = Aws::EC2::Client.new
response = ec2.describe_instances instance_ids: target_instance_ids
ip_addresses = response.reservations.map {|r| r.instances.map {|i| i.public_ip_address } }.flatten

ip_addresses.each do |ip|
  server ip.to_s, user: 'deploy', roles: %w{web app db}
end

これはいわゆる以下の代わりです。

config/deploy/production.rb
server 'under-elb-server1.com', user: 'deploy', roles: %w{web app db}
server 'under-elb-server2.com', user: 'deploy', roles: %w{web app db}
server 'under-elb-server3.com', user: 'deploy', roles: %w{web app db}
...

サーバとの認証についてワンポイント

最後にもう一つ。今回予期できない複数のホストへデプロイするので公開鍵認証で躓く場合があります。設定で秘密鍵の場所を指定してあげると良いかもしれません。

config/deploy/production.rb
if ENV['DEPLOY_ORIGIN'] == 'local'
  set :ssh_options, {
    keys: %w(~/.ssh/hogehoge/id_rsa),
    auth_methods: %w(publickey)
  }
end

ENVで分岐させてるのは、Circle CIでは指定してあげなくても何故か上手くいき(誰か教えて頂けると嬉しいです)、なおかつそれ以前にキーの場所が分からなかったからです。

こちらからは以上です。

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
18