今回はCloudFormationのデプロイをより便利にする rain
コマンドを試しました。
rainとは
rainは複数のコマンドが用意されており、それぞれの特徴は公式リポジトリ に記載されています。特によく使いそうなものをいくつか取り上げます。
- rain deployによるインタラクティブなデプロイ:
rain deploy
コマンドはaws cloudformation deploy
コマンドのように、CloudFormationテンプレートの定義に従ってAWS環境にリソースを作成・更新するコマンドです。rain deploy
コマンドの場合、未指定のパラメータの入力の案内や変更内容の提示、実行後の進行状況の表示など、インタラクティブな要素が特徴となります。また、初回のStackデプロイに失敗しても前回分のStackの削除を実行することなく、deployコマンドを続けて実行することが可能です ( 先日の CloudFormationへのアップデートにより、DeletionPolicy
にRetainExceptOnCreate
を使うことで同様の効果を得ることはできるようになりました) 。 - rain fmtによるテンプレートのフォーマット:
rain fmt
コマンドはCloudFormationテンプレートのフォーマットやJSON/YAML間の変換を行います。AWS CLIではaws cloudformation validate-template
などでテンプレートの検証はできましたが、テンプレートのフォーマットを行うことはできませんでした。 - rain logによるログの表示:
rain log
コマンドはStackで発生したログを表示します。表示するログは、指定したStackに加えてそれに関連付けられたNested Stackからのログも結合します。これまではStackのログを見るためにAWSマネジメントコンソールに移動する必要がありました。 - rain buildコマンドによるテンプレートの構築:
rain build
コマンドは指定したAWSリソースのCloudFormationテンプレートを表示します。これによりCloudFormationテンプレートを作り始めるときのinitialテンプレートが簡単に手に入ります。
rainを試す
ここからrainコマンドを試してみます。実行した環境はAWS Cloud9になります。
インストール
インストール方法はいくつかありますが、ここではリポジトリで提供されたバイナリをダウンロードして使います。rainはGo言語製なのでバイナリを配置すれば使えます。
$ wget https://github.com/aws-cloudformation/rain/releases/download/v1.4.3/rain-v1.4.3_linux-amd64.zip $ unzip rain-v1.4.3_linux-amd64.zip Archive: rain-v1.4.3_linux-amd64.zip creating: rain-v1.4.3_linux-amd64/ inflating: rain-v1.4.3_linux-amd64/README.md inflating: rain-v1.4.3_linux-amd64/LICENSE inflating: rain-v1.4.3_linux-amd64/rain $ sudo mv rain-v1.4.3_linux-amd64/rain /usr/local/bin/ # インストール後の確認 $ rain --version Rain v1.4.2 linux/amd64
rain build / deployによるリソースの作成
初回のStack作成成功時
まずは基本的な操作として、テンプレートの生成とデプロイを行います。今回はAmazon SQSをターゲットにリソースを作成します。
まずは rain build
コマンドでinitialテンプレートを生成します。
$ rain build AWS::SQS::Queue > sqs-test.yaml $ cat sqs-test.yaml AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyQueue: Type: AWS::SQS::Queue Properties: ContentBasedDeduplication: false # Optional DeduplicationScope: CHANGEME # Optional DelaySeconds: 0 # Optional FifoQueue: false # Optional FifoThroughputLimit: CHANGEME # Optional KmsDataKeyReusePeriodSeconds: 0 # Optional KmsMasterKeyId: CHANGEME # Optional MaximumMessageSize: 0 # Optional MessageRetentionPeriod: 0 # Optional QueueName: CHANGEME # Optional ReceiveMessageWaitTimeSeconds: 0 # Optional RedriveAllowPolicy: '{"JSON": "CHANGEME"}' # Optional RedrivePolicy: '{"JSON": "CHANGEME"}' # Optional SqsManagedSseEnabled: false # Optional Tags: - Key: CHANGEME Value: CHANGEME VisibilityTimeout: 0 # Optional Outputs: MyQueueArn: Value: !GetAtt MyQueue.Arn MyQueueQueueName: Value: !GetAtt MyQueue.QueueName MyQueueQueueUrl: Value: !GetAtt MyQueue.QueueUrl
コマンドを実行して # Optional
と書かれた箇所は必須でないパラメータになります。ここではQueneName
とタグだけを指定しました。
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyQueue: Type: AWS::SQS::Queue Properties: QueueName: test-sqs Tags: - Key: test Value: rain
次にテンプレートを指定してQueueリソースを作成しますが、 rain ls
コマンドを実行すると、新規Stackを作成する前に既存のStackの状態を知ることができます(例えば新規に作成するStack名を検討するときなど)。
$ rain ls CloudFormation stacks in ap-northeast-1: aws-cloud9-test01-1fd0ca9e39c449608d7d6484a29f4069: CREATE_COMPLETE (以降割愛)
次にrain deploy
コマンドを実行し、Stackを作成します。なお、特にオプションで指定しない場合、テンプレートのファイル名がStack名に使われます。
$ rain deploy sqs-test.yaml Rain needs to create an S3 bucket called 'rain-artifacts-123456789012-ap-northeast-1'. Continue? (Y/n) Y # 1. S3バケットの作成 CloudFormation will make the following changes: # 2. 変更予定内容の表示 Stack sqs-test: + AWS::SQS::Queue MyQueue Do you wish to continue? (Y/n) Y Deploying template 'sqs-test.yaml' as stack 'sqs-test' in ap-northeast-1. Stack sqs-test: CREATE_COMPLETE # 3. 進行状況の表示 Successfully deployed sqs-test # 4. 完了メッセージ
コマンド実行時の流れを簡単に記載します。
rain deploy
コマンドの初回実行時は、テンプレートを配置するためのS3バケットの作成が必要となります。- 変更予定内容を表示します。ここでは新規リソースの追加が表示されています
- ここはデプロイ後の進行状況が表示されます。テキストだけではイメージが湧かないと思うので、公式リポジトリのデモの様子を見たり、実際に使ってもらえればと思います。
- デプロイが完了するとその旨が表示されます。
もう一度 rain ls
コマンドを実行すると、先ほどはなかった sqs-test
というStackが追加されています。
$ rain ls CloudFormation stacks in ap-northeast-1: aws-cloud9-test01-1fd0ca9e39c449608d7d6484a29f4069: CREATE_COMPLETE (一部抜粋) sqs-test: CREATE_COMPLETE
ここで rain log
コマンドを実行すると、先ほどのStack作成で発生したログが表示されます。ただしデフォルトではエラーなどの重要なログしか表示されないため、ここでは --all
オプションを追加します。
$ rain logs sqs-test No interesting log messages to display. To see everything, use the --all flag $ rain logs sqs-test --all Aug 5 07:29:41 sqs-test/sqs-test (AWS::CloudFormation::Stack) CREATE_COMPLETE Aug 5 07:29:40 sqs-test/MyQueue (AWS::SQS::Queue) CREATE_COMPLETE Aug 5 07:28:29 sqs-test/MyQueue (AWS::SQS::Queue) CREATE_IN_PROGRESS "Resource creation Initiated" Aug 5 07:28:28 sqs-test/MyQueue (AWS::SQS::Queue) CREATE_IN_PROGRESS Aug 5 07:28:25 sqs-test/sqs-test (AWS::CloudFormation::Stack) CREATE_IN_PROGRESS "User Initiated" Aug 5 07:28:11 sqs-test/sqs-test (AWS::CloudFormation::Stack) REVIEW_IN_PROGRESS "User Initiated"
また rain cat
コマンドを実行すると、指定したStackのテンプレート情報を取得できます。テンプレートファイルの記載内容と差分がないかを見たりするのに使えそうです。
$ rain cat sqs-test AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyQueue: Type: AWS::SQS::Queue Properties: QueueName: test-sqs Tags: - Key: test Value: rain
なお、テンプレートを修正してStackに再デプロイする時も、先ほどと同じく rain deploy
コマンドを使えば実行されます。
# テンプレートを一部修正 $ cat sqs-test.yaml AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyQueue: Type: AWS::SQS::Queue Properties: QueueName: test-sqs DelaySeconds: 60 # 追加 Tags: - Key: test Value: rain # 修正内容の反映 $ rain deploy sqs-test.yaml CloudFormation will make the following changes: Stack sqs-test: > AWS::SQS::Queue MyQueue Do you wish to continue? (Y/n) Deploying template 'sqs-test.yaml' as stack 'sqs-test' in ap-northeast-1. Stack sqs-test: UPDATE_COMPLETE Successfully updated sqs-test
初回のStack作成失敗時
次に初回のStack作成に失敗した場合を見てみます。ここでは先ほど作成したのと同じ QueueName
を持つSQSリソースを指定した、別のテンプレートを用意します。
このテンプレートを指定して rain deploy
コマンドを実行すると、以下のように作成に失敗します。エラーメッセージも表示されるので、簡単なケースならエラー原因をすぐに特定できます。
$ rain deploy fmt-sqs-test.yaml CloudFormation will make the following changes: Stack fmt-sqs-test: + AWS::SQS::Queue MyQueue Do you wish to continue? (Y/n) Deploying template 'fmt-sqs-test.yaml' as stack 'fmt-sqs-test' in ap-northeast-1. Stack fmt-sqs-test: ROLLBACK_COMPLETE Messages: - MyQueue: Resource handler returned message: "Resource of type 'AWS::SQS::Queue' with identifier 'test-sqs' already exists." (RequestToken: dae75161-d420-a85a-8610-f8af52a9f060, HandlerErrorCode: AlreadyExists) failed deploying stack 'fmt-sqs-test'
この後に rain ls
コマンドを実行すると、先ほど作成に失敗したStack名が確認できます。
$ rain ls CloudFormation stacks in ap-northeast-1: aws-cloud9-test01-1fd0ca9e39c449608d7d6484a29f4069: CREATE_COMPLETE (一部抜粋) fmt-sqs-test: ROLLBACK_COMPLETE
ここでQueneName
を別名に修正し、再度 rain deploy
コマンドを実行します。すると、Stackの作成前に既存のStackを削除している様子が確認できます。
$ rain deploy fmt-sqs-test.yaml Deleted existing, empty stack. # Stackを削除している CloudFormation will make the following changes: Stack fmt-sqs-test: + AWS::SQS::Queue MyQueue Do you wish to continue? (Y/n) n # ここではデプロイは実施していません user cancelled deployment
なお、Stackの初回作成以外でのエラー(例えば UPDATE_ROLLBACK_FAILED
など)が発生している状態では rain deploy
コマンドを実行してもエラーが返されるため、実行前にエラーを解消する必要があります。
※参考: AWS re:Post
$ rain deploy sqs-test.yaml stack 'sqs-test' could not be updated: UPDATE_ROLLBACK_FAILED
rain fmtによるテンプレートの修正
次に rain fmt
コマンドを使ってみます。まずは以下のような、ハイフンの位置をどうするか迷うTagsの部分を少しいじったテンプレートを使ってみます。
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyQueue: Type: AWS::SQS::Queue Properties: QueueName: test-sqs Tags: - Key: test # ハイフンの位置を変更 Value: rain
上記テンプレートにfmtコマンドを適用すると、以下のように修正されます。
$ rain fmt sqs-test.yaml AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyQueue: Type: AWS::SQS::Queue Properties: QueueName: test-sqs Tags: - Key: test # 修正されている Value: rain # 修正されている
ただし、 rain fmt
は極端にフォーマットが崩れたテンプレートに対しては効果は発揮されないかもしれません。例えば以下のように、各行をすべて先頭列に持ってきたテンプレートに対してfmtを実行します。
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyQueue: Type: AWS::SQS::Queue Properties: QueueName: test-sqs FakeParam: test-value Tags: - Key: test
すると、以下のように想定通りにはフォーマットされない結果となりました。
$ rain fmt fmt-sqs-test-01.yaml AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyQueue: Type: AWS::SQS::Queue Properties: QueueName: test-sqs FakeParam: test-value Tags: - Key: test
また、以下のように存在しないパラメータを追加したテンプレートに対してもfmtを実行してみます。
AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyQueue: Type: AWS::SQS::Queue Properties: QueueName: test-sqs FakeParam: test-value # 存在しないパラメータ Tags: - Key: test Value: rain
ここでは特にエラーも発生せず正常終了してしまいました。
$ rain fmt fake-param-sqs-test.yaml AWSTemplateFormatVersion: "2010-09-09" Description: Template generated by rain Resources: MyQueue: Type: AWS::SQS::Queue Properties: QueueName: test-sqs FakeParam: test-value Tags: - Key: test Value: rain
そもそも rain build
などでテンプレートを生成してから作業することを想定しているかもしれませんが、fmtコマンドはあまり過信せず、cfn-lint などで構文チェックをしてから rain fmt
を実行するのがよさそうです。
その他コマンド
rain forecast
rain foecast
コマンドは実験的なコマンドとして用意されており、AWSアカウント内の制約やテンプレートの依存関係の設定ミスなど、デプロイに失敗する可能性のある要素がある場合に警告するものです。forecastのhelpオプションによると、コマンド実行ユーザーの権限やクォータ、ドリフトの問題などを検知してくれるようです。
$ rain forecast --help Outputs warnings about potential deployment failures due to constraints in the account or misconfigurations in the template related to dependencies in the account. NOTE: This is an experimental feature! To use this command, add --experimental or -x as an argument. This command is not a linter! Use cfn-lint for that. The forecast command is concerned with things that could go wrong during deployment, after the template has been checked to make sure it has a valid syntax. This command checks for some common issues across all resources: - The resource already exists - You do not have permissions to create/update/delete the resource - (More to come.. service quotas, drift issues) Resource-specific checks: - S3 bucket is not empty - S3 bucket policy has an invalid principal - (Many more to come...) Usage: rain forecast --experimental <template> [stackName] Flags: -c, --config string YAML or JSON file to set tags and parameters --debug Output debugging information -x, --experimental Acknowledge that this is an experimental feature -h, --help help for forecast --no-colour Disable colour output --params strings set parameter values; use the format key1=value1,key2=value2 -p, --profile string AWS profile name; read from the AWS CLI configuration file -r, --region string AWS region to use --role-arn string An optional execution role arn to use for predicting IAM failures --skip-iam Skip permissions checks, which can take a long time --tags strings add tags to the stack; use the format key1=value1,key2=value2 --type string Optional resource type to limit checks to only that type
なおこちらのコマンドはlinterとして利用することはできないことが明記されており、試しに fmtコマンドで使った不要なパラメータを含むテンプレートを指定してもエラーは発生しませんでした。
$ rain forecast --experimental fake-param-sqs-test.yaml sqs-test Clear skies! All 1 checks passed.
テンプレートの構文チェックをしたい場合はcfn-lintなど別のツールを使いましょう。
rain merge
rain merge コマンドは指定したテンプレートの内容を結合した結果を出力します。正直利用するケースがあまり思い浮かばなかったのですが、例えば以下のように、別のテンプレートで同じリソース名(ここでは MyQueue
)を使っている場合はエラーが発生します。
$ rain merge sqs-test.yaml fmt-sqs-test.yaml templates have clashing Resources: MyQueue
成功した場合は以下のようになり、Descriptionの内容も結合している様子などが見えます。
$ rain merge sqs-test.yaml fmt-sqs-test.yaml AWSTemplateFormatVersion: "2010-09-09" Description: |- Template generated by rain Template generated by rain Resources: FmtMyQueue: Type: AWS::SQS::Queue Properties: QueueName: fmt-test-sqs Tags: - Key: test Value: rain MyQueue: Type: AWS::SQS::Queue Properties: QueueName: test-sqs Tags: - Key: test Value: rain
rain rm
rain rm
コマンドは既存のStackを削除します。ここでは先ほど rain deploy
コマンドで作成したStackを削除します。なお、デフォルトでは削除実行可否の選択が Noになっているため、誤って削除する危険性は少し軽減されています。
$ rain rm sqs-test Stack sqs-test: UPDATE_COMPLETE Are you sure you want to delete this stack? (y/N) y Successfully deleted stack 'sqs-test'