概要

Sidekiqなどの非同期処理システムをEC2の複数のインスタンスで実行する場合に、
EC2のタグ情報から動的に設定値を取ってこれたら便利だなーと思ったのでやり方を調べた。

やりたいこと

サービス起動時にポーリングするキューと並列実行数をタグ情報から取得して設定する。

def instance_env(key)
  self_instance_id = %x( curl -s http://169.254.169.254/latest/meta-data/instance-id )

  region      = "--region '#{ENV['AWS_REGION']}'"
  instance_id = "--instance-ids '#{self_instance_id}'"
  query       = "--query 'Reservations[].Instances[].Tags[?Key==`#{key}`].Value'"
  output      = "--output text"
  %x( aws ec2 describe-instances #{region} #{instance_id} #{query} #{output} ).chomp
end

configatron.app.setting.queues      = Configatron::Delayed.new { instance_env('Queues') }
configatron.app.setting.concurrency = Configatron::Delayed.new { instance_env('Concurrency') }

やってること

EC2のインスタンスから特定のURLにアクセスすることで自身のメタデータを取得できる。
以下は自身のインスタンスIDを取得している。

self_instance_id = %x( curl -s http://169.254.169.254/latest/meta-data/instance-id )

awsコマンドを使ってインスタンスに設定されたタグの設定値を取得している。

region      = "--region '#{ENV['AWS_REGION']}'"
instance_id = "--instance-ids '#{self_instance_id}'"
query       = "--query 'Reservations[].Instances[].Tags[?Key==`#{key}`].Value'"
output      = "--output text"
%x( aws ec2 describe-instances #{region} #{instance_id} #{query} #{output} ).chomp

定数の管理にconfigatronを使用している。
メタデータの取得には数秒のラグが発生するため、Configatron::Delayedを使うことで実際にアクセスがあるまでリクエストを送信しないようにしている。

configatron.app.setting.queues      = Configatron::Delayed.new { instance_env('Queues') }
configatron.app.setting.concurrency = Configatron::Delayed.new { instance_env('Concurrency')