AWS CLIがCloudFormationの状態遷移ポーリング(waiters)に対応しました

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

本日はCloudFormation職人の生産性を上げるAWS CLIのwaiters機能を紹介します。

AWS CLIのポーリング(waiters)機能について

AWS CLIからEC2インスタンスを起動後、何か処理を実行する時のことを考えましょう。

コマンド$ aws ec2 run-instances ...でEC2インスタンスを起動すると、EC2インスタンスのステータスは pending(起動中)->running(起動完了) と遷移します。

aws-ec2-state-change

いざ、ポーリング処理でステータスチェックをしようにも、エラーやタイムアウト処理も必要で、シェルスクリプトで自前実装するのは地味に面倒です。

そういった理由からAWS CLIにはwaitersという機能が存在し、期待する状態に遷移するまでいい感じにポーリングする機能が存在します。

先ほどの例を持ち出すと

# run instance
aws ec2 run-instances ...
# check status
while check_status;
do
  # タイムアウトチェックやりつつ
  sleep N
  describe_instance_status
done
# after running
do_something

というように書いていた処理を

# run instance
aws ec2 run-instances ...
# check status
aws ec2 wait instance-running ...
# after running
do_something

とすっきり書けます。

CloudFormation のwaitersについて

### CloudFormationについて

AWS CloudFormationは、開発や本運用に必要な、互いに関連するAWSリソースのコレクションを作成しておき、そのリソースを適切な順序でプロビジョニングするためのサービスです。

例えば、VPCを作ってEC2とRDSを起動するといったことをJSONで記述できます。 一方で、複雑に絡みあったリソースを操作するだけに、処理が完了するまでには、様々な状態の遷移と長い時間を要します。

そんなわけでCloudFormationはwaitersと相性がよいのですが、このたびAWS CLIがようやくwaitersに対応しました。

AWS CLIのインストール

CloudFormation waitersはAWS CLI 1.10.13 以降で対応しています。 AWS CLIを最新にしましょう。

$ sudo pip install -U awscli
$ aws --version
aws-cli/1.10.13 Python/2.7.10 Linux/4.4.4-13.24.amzn1.x86_64 botocore/1.4.4
$ aws cloudformation wait help
WAIT()                                                                  WAIT()

NAME
       wait -

DESCRIPTION
       Wait until a particular condition is satisfied.

AVAILABLE COMMANDS
       o stack-create-complete
       o stack-delete-complete
       o stack-exists
       o stack-update-complete
                                                                        WAIT()

CloudFormation Waitersについて

CloudFormation waitersには以下の4コマンドが存在します。

  1. stack-create-complete スタック作成が完了するまで待つ
  2. stack-update-complete スタック更新が完了するまで待つ
  3. stack-delete-complete スタック削除が完了するまで待つ
  4. stack-exists スタックが存在するまで待つ

4つ目は用途があまりないと思うので、先頭3つについて紹介します。

スタック作成完了を待つ stack-create-complete

CloudFormationでスタックを作成するAPIを投げると、状態は下図のように遷移します(知らんけど)。

cfn-create-stack

CREATE_COMPLETEステートになると正常終了します。

使い方

$ aws cloudformation create-stack \
  --stack-name foo \
  --template-body file://...
$ aws cloudformation wait stack-create-complete \
  --stack-name foo

ひとくちメモ

CloudFormationテンプレートを新規開発するようなケースにおいて、一発で CREATE_COMPLETEステータスに持っていくのは難しく、すべてのリソースをCREATE_COMPLETEさせるまでは険しい道のりが待っているわけです。

正常系のフローから外れると(ROLLBACK_IN_PROGRESSステータスなど)、すぐにwaitが異常終了する親切設計になっています。

スタック更新完了を待つ stack-update-complete

CloudFormationでスタックを更新するAPIを投げると、状態は下図のように遷移します(知らんけど)。

cfn-update-stack

UPDATE_COMPLETEステートになると正常終了します。

使い方

$ aws cloudformation update-stack \
  --stack-name foo \
  --template-body file://...
$ aws cloudformation wait stack-update-complete \
  --stack-name foo

ひとくちメモ

CloudFormation管理されているリソースがうっかり削除されると、更新処理は失敗します。 軽微な修正もCloudFormationに落として更新し続けないと、リソース設定が簡単に ロールバックしてしまいます。 そんなわけで、リソース更新もCloudFormationを使っている現場はかなり限られているかもしれません。

正常系のフローから外れると(UPDATE_ROLLBACK_IN_PROGRESSステータスなど)、すぐにwaitが異常終了します。

スタック削除完了を待つ stack-delete-complete

CloudFormationでスタックを削除するAPIを投げると、状態は下図のように遷移します(知らんけど)。

cfn-delete-stack

DELETE_COMPLETEステートになると正常終了します。

使い方

$ aws cloudformation create-stack \
  --stack-name foo \
  --template-body file://...
$ aws cloudformation wait stack-create-complete \
  --stack-name foo

ひとくちメモ

作ったばかりのリソース群がDELETE_FAILEDで消しきれなかったりすると悲しくなります。

boto3(Python SDK)での使い方

boto3とAWS CLIは低レベルライブラリを共有しています。 今回の修正に伴い、boto3もCloudFormation waitersに対応しました。

次のようにしてwaitを呼び出すことができます。

import boto3
client = boto3.client('cloudformation')
client.create_stack(
    StackName='Foo',
    ...)
waiter = client.get_waiter('stack_completed')
waiter.wait(StackName='Foo')
# DO SOMETHING

まとめ

今回はCloudFormationのwaiters対応を紹介しました。

Ruby SDKでは半年位前から対応していたましたが、AWS CLI/boto3でもようやく対応しました。 更新するにもロールバックするにも時間のかかるCloudFormationは、waitersを使うことでフローを見通しよく記述出来るようになります。

ぜひ一度お試しください。

参考リンク