LoginSignup
5
1

More than 5 years have passed since last update.

capistranoでec2のipをハードコーディングせず、いい感じにデプロイしたい

Last updated at Posted at 2017-05-10

これまでサーバの増減がほとんどなかったので、デプロイ対象はハードコーディングしていたのですが、そろそろ台数が増えそうなので、ハードコーディングを止める方法を考えてみました。

lib/capistrano/tasks/aws_ec2.rake

aws-sdkを使って、describe_instancesするだけなんですが、これを設定ファイルに書いてしまうと読みづらいので、taskに分離します。

require 'aws-sdk'

namespace :aws_ec2 do
  desc 'aws ec2'
  task :roles do
    run_locally do
      ec2 = Aws::EC2::Client.new
      default_filters = [{name: "tag:Env", values: [fetch(:aws_ec2_env)]}, {name: 'instance-state-name', values: ['running']}]

      %w(app web job).each do |target|
        tag_filters = fetch("role_tags_#{target}".to_sym, [])
        next if tag_filters.empty?
        filters = default_filters + tag_filters

        instances = ec2.describe_instances(filters: filters).reservations.map(&:instances).flatten
        hosts = instances.map{|k| k.tags.select{|t| t.key == "Name"} }.flatten.map(&:value)
        ip_addresses = instances.map{|k| k.private_ip_address }

        output = "#{target}:" + hosts.join(',')
        info output

        role target, ip_addresses
      end
    end
  end
end

実行すると role に動的に private_ip_address がセットされます。

config/deploy/production.rb

あとはフィルタリングルールを書いてあげて、デプロイステップの最初の方でroleをセットしてあげればOK。

set :aws_ec2_env, :sandbox
set :role_tags_app, -> { [{name: "tag:Role", values: ['app']}]}
set :role_tags_job, -> { [{name: "tag:Role", values: ['job']}]}

before 'deploy:starting', 'aws_ec2:roles'

References

5
1
1

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
5
1