想定環境
- AutoScalingされたりしてるアプリケーション用EC2インスタンス tagに
app:true
と設定 - RDSはMasterとRead Replicaが複数台
やってること
- EC2はIPアドレスをとってきてRole設定。稼働中かつ
app:true
としたサーバがデプロイ対象になる。 - RDSはtagに対応していないので、Masterか否かを判断してendpointでアクセス。
必要なもの
環境変数
$ export AWS_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxx"
$ export AWS_SECRET_ACCESS_KEY="xxxxxxxxxxxxxx"
$ export EC2_URL="http://ec2.ap-northeast-1.amazonaws.com"
Roleの設定
production.rb
require 'aws-sdk'
set :aws_access_key_id, ENV['AWS_ACCESS_KEY_ID']
set :aws_secret_access_key, ENV['AWS_SECRET_ACCESS_KEY']
#EC2
if ENV['EC2_URL']
ec2=AWS::EC2.new(:ec2_endpoint => ENV['EC2_URL'].sub(/^https?:\/\//,""))
else
ec2=AWS::EC2.new
end
instances = ec2.instances.select {|instance| instance.tags[:app] == 'true' && instance.status == :running}.map(&:private_ip_address)
role :app, *instances, :behind_loadbalancer => true
#RDS
if ENV['EC2_URL']
rds=AWS::RDS.new(:rds_endpoint => ENV['EC2_URL'].sub(/^https?:\/\/ec2/,"rds"))
else
rds=AWS::RDS.new
end
rds_master = rds.instances.select {|instance| instance.read_replica_source_db_instance_identifier == nil }.map(&:endpoint_address)
rds_slave = rds.instances.select {|instance| instance.read_replica_source_db_instance_identifier != nil }.map(&:endpoint_address)
role :db_host, *rds_master, :no_release => true, :primary => true, :name => "default", :rds => true
rds_slave.each_with_index{ |slave, i| @slave_num = i + 1
role :db_host, slave, :no_release => true, :name => "slave" + @slave_num.to_s }
参考
CapistranoでELB配下のEC2インスタンスを取得してデプロイ
eXcale | Blog : CapstranoでAWSのAPIを使って実行時にroleを設定する