Help us understand the problem. What is going on with this article?

AWS SDK for Ruby v2のwaitersの解説

More than 5 years have passed since last update.

何の機能か?

AWSのAPIは、基本的にあるリクエストに対するレスポンスを即座に返してしまい、そのリクエストで意図した結果が必ず起こるとは限りません。
APIリクエストに成功すると、HTTPコード200 とともにインスタンスの情報が返ってきます。

ですが、HTTP 200を受け取ったからといって、このインスタンスがrunningになるとは限りません。
APIレスポンスが返ってきた後、その対象が望むべきStatusになっているかどうかを暫くの間監視しておく必要があります。
このような場合aws-sdk v2から導入されたwaitersを使うと便利です。

まずv2をインストール

gem 'aws-sdk', '2.0.11.pre'
gem 'aws-sdk-core'

環境変数をセットしておくこと

$ export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
$ export AWS_REGION=ap-northeast-1

使い方の例

簡単な使い方

wait_untilメソッドで処理をブロックしています。

require 'aws-sdk'

ec2 = Aws::EC2::Client.new
ec2.start_instances(instance_ids: ['i-12345678'])
ec2.wait_until(:instance_running,  instance_ids:['i-12345678'])

waitの細かい制御方法

以下のケースは一時間ec2が起動するまで待つ例です。(15秒おきに240回待つ)

ec2 = Aws::EC2::Client.new
ec2.wait_until(:instance_running, instance_ids:['i-12345678']) do |w|
  w.interval = 15
  w.max_attempts = 240
end

RDSでDBがavailableになるまで待つ

rds.create_db_instance(db_instance_identifier:'db01')
rds.wait_until(:db_instance_available, db_instance_identifier:'db01')
  • 与えるパラメータもResourceによって違うので注意

interval毎に処理を挟む

ec2 = Aws::EC2::Client.new
ec2.wait_until(:instance_running, instance_ids:['i-12345678']) do |w|
  w.before_attempt do |attempt|
    puts "before interval..."
  end

  w.before_wait do |attempt, prev_response|
    puts "after interval..."
  end
end
  • before_waitはintervalの後に処理を挟むことが出来る
  • before_attemptはintervalの前に処理を挟むことが出来る

rescueでエラーを拾う

指定時間待ってもステータスが変わらない場合、Aws::Waiters::Errors::WaiterFailedが発生する。

ec2 = Aws::EC2::Client.new

begin
  ec2.wait_until(:instance_running,  instance_ids:['i-1234567']) do |w|
    w.interval = 15
    w.max_attempts = 240
  end
rescue Aws::Waiters::Errors::WaiterFailed => error
  puts "failed waiting for instance running: #{error.message}"
end

Resource別statusの確認

主なResourceのstatusを調べてみる。

wait_untilの引数にすればそのステータスになるまで処理をブロックできます。

EC2

Aws::EC2::Client.new.waiter_names
=> [:system_status_ok,
 :instance_status_ok,
 :image_available,
 :instance_running,
 :instance_stopped,
 :instance_terminated,
 :export_task_completed,
 :export_task_cancelled,
 :snapshot_completed,
 :subnet_available,
 :volume_available,
 :volume_in_use,
 :volume_deleted,
 :vpc_available,
 :vpn_connection_available,
 :vpn_connection_deleted,
 :bundle_task_complete,
 :conversion_task_completed,
 :conversion_task_cancelled,
 :customer_gateway_available,
 :conversion_task_deleted,
 :spot_instance_request_fulfilled]

S3

Aws::S3::Client.new.waiter_names
=> [:bucket_exists, :bucket_not_exists, :object_exists, :object_not_exists]

RDS

Aws::RDS::Client.new.waiter_names
=> [:db_instance_available, :db_instance_deleted]

Redshift

Aws::Redshift::Client.new.waiter_names
=> [:cluster_available, :cluster_deleted, :snapshot_available]

DynamoDB

Aws::DynamoDB::Client.new.waiter_names
=> [:table_exists, :table_not_exists]

ステータスが存在しないケース

Aws::EMR::Client.new.waiter_names
=> []
  • ElastiCache、Kinesis、SQSなどもステータスが存在しません。

まとめ

APIリクエスト後Statusの値をintervalを設けてPollingし、何回以内に成功しなければ異常と判断されるので例外を投げると言った処理を自分で作っていたかと思うのですが、その部分をSDKで吸収してくれるようになりました。

toyama0919
Data Engineer.
dena_coltd
    Delight and Impact the World
https://dena.com/jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした