[rails]cap deploy時に複数のAuto Scalingグループにもデプロイしたい
先日、AWSのAuto Scallingを使った際に、cap deploy時にAuto Scaleインスタンスにも自動でデプロイできるようにする必要があったので調べたところ、
jq - cap deploy時にAutoScalingで立ってるサーバにも同時にdeployさせる - Qiita
こちらの記事を参考にさせていただき、無事にデプロイを実行することができるようになりました。
その後、また別の機会でAuto Scallingを使ったのですが、この時は SQSを使って、appサーバからbatchサーバに処理を投げるという構成だったので、appサーバとbatchサーバそれぞれにAuto Scalingグループを設定する必要がありました。(batchのほうは Job Observerパターンと呼ばれるそうです)
前回と同様にcap deploy時にAuto Scalingで作成されたインスタンスにもデプロイできるようにしようとしたのですが、ここで問題が発生しました。
前回は1つのAuto Scalingグループのみだったので、起動中のAuto ScalingインスタンスのPrivateIpAddressを取得すればよかったのですが、今回は2つのAuto Scalingグループがあり、appロールとbatchロールに分けてサーバ設定を行う必要がありました。
そこで、まずAuto Scalling グループのタグ設定で、appサーバの場合は「app-auto」、batchサーバの場合は「batch-auto」というNameをつけるように設定しました。
そして、awsコマンドとjqコマンドを組み合わせて、以下のようなタグ名とipの組み合わせを取得するようにしました。
{
"ip": "xx.xx.xx.xx",
"name": "app-auto"
}
{
"ip": "xx.xx.xx.xx",
"name": "batch-auto"
}
取得した組み合わせを更に加工してjsonとしてparseできるように変換し、それぞれのタグ名に応じてロールを切り替えるようにしました。
最終的なdeploy.rbは以下のようになりました。
require 'json'
set :stage, :production
set :rails_env, fetch(:stage)
set :deploy_to, "/home/app/#{fetch(:application)}/#{fetch(:rails_env)}"
server 'xx.xx.xx.xx', user: 'app', roles: %w{app db}
server 'xx.xx.xx.xx', user: 'app', roles: %w{batch}
def installed?(cmd)
`which #{cmd.to_s} > /dev/null; echo $?`.to_i.zero?
end
if installed?(:aws) && installed?(:jq)
instance_ids = `aws autoscaling describe-auto-scaling-instances | jq ".AutoScalingInstances[].InstanceId"`.split("\n")
if instance_ids.size > 0
instance_list = `aws ec2 describe-instances --instance-ids #{instance_ids.join(' ')} | jq '.Reservations[].Instances[] | { ip: .PrivateIpAddress, name: (.Tags[] | select(.Key == "Name") | .Value) }'`.gsub(/\s/, '').gsub(/\n/, '').gsub(/}{/, "},{")
JSON.parse("[#{instance_list}]").each do |instance|
if instance['name'] =~ /batch/
eval "server '#{instance['ip']}', user: 'app', roles: %w{batch}"
elsif instance['name'] =~ /app/
eval "server '#{instance['ip']}', user: 'app', roles: %w{app}"
end
end
end
else
puts '[ deploy to autoscaling servers skipped. ]'
puts 'awscli and jq required. For Mac OS X, try "$ brew install awscli jq"'
end
jqの結果をjsonに変換する部分でgsubを使って力技でなんとかしてしまっているのを綺麗にしたかったのですが、うまくできず。。。
とりあえずはこれで、cap deploy時に複数のAuto Scalingグループにもデプロイできるようになりました。