CloudFormationのStackSetsをやってみる
2022/11/05 CloudFormation StackSetsのAPIに更新がありました。
-
DescribeStackSetOperation
で、失敗したスタックの数を返すようになりました -
ListStackInstances
で、operation IDを返すようになりました
そもそもStackSetsを使ったことがなかったのですが、やってみました。
基本知識、準備
スタックセットとは、1つのテンプレートで、複数リージョン、複数アカウントにスタックを作成する機能です。
準備として、IAM Roleが2つ必要です。こちらで書いてあるYAMLテンプレートを使わせていただきました。手順も丁寧に書かれているので、このページでは割愛します。
複数リージョンにデプロイして失敗させたい
今回は、失敗したときにAPIを使った出力を見たいので、そのためのテンプレートを用意します。リージョンを固定したリソースをいろいろなリージョンのLambdaに紐付けて失敗させることにしました。
こちらからSQSとLambdaのマッピングをしているテンプレートを拝借してきました。
Type: AWS::Lambda::EventSourceMapping
で、Lambdaの名前かArnと、EventSourceのArnを設定すればマッピングされます。
EventSourceMapping:
Type: AWS::Lambda::EventSourceMapping
Properties:
Enabled: true
EventSourceArn: arn:aws:sqs:ap-northeast-1:111122223333:your-sqs-name
FunctionName: !GetAtt Lambda.Arn
デプロイした場合、コンソール上だとこういう表示になります。
テンプレート用意
SQSを先に作る
先に東京リージョンでSQSを作ります。コンソールで作ったほうが早いです(CreateQueue -> 名前入れてあとはデフォルトで作成、Arnをコピーしておく)。
テンプレートでも作るならこんな具合でしょうか。
AWSTemplateFormatVersion: "2010-09-09"
Resources:
Queue:
Type: AWS::SQS::Queue
Properties:
QueueName: sqs-sample
デプロイして、
aws cloudformation deploy \
--template-file sqs-sample.yaml \
--stack-name SQS-Sample \
--capabilities CAPABILITY_NAMED_IAM
Outputの値だけ取り出します。
aws cloudformation describe-stacks --stack-name SQS-Sample | jq -r '.Stacks[0].Outputs[0]'
SQSとLambdaをマッピングさせるテンプレート
次に以下のテンプレートで、作成したSQSのARNを、arn:aws:sqs:ap-northeast-1:111122223333:your-sqs-name
の部分(2箇所)にハードコードします。
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
Name:
Description: identifier
Type: String
Default: sqs-lambda-event
Resources:
EventSourceMapping:
Type: AWS::Lambda::EventSourceMapping
Properties:
Enabled: true
EventSourceArn: arn:aws:sqs:ap-northeast-1:111122223333:your-sqs-name
FunctionName: !GetAtt Lambda.Arn
BatchSize: 1
Lambda:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Ref Name
Handler: index.lambda_handler
Role: !GetAtt LambdaRole.Arn
Runtime: nodejs16.x
Code:
ZipFile: |
exports.lambda_handler = async (event, context) => {
const util = require('util');
console.log(util.inspect(event,false,null));
return 200;
}
LambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
Policies:
- PolicyName: sqs-access
PolicyDocument:
Statement:
- Sid: 1
Effect: Allow
Action:
- sqs:DeleteMessage
- sqs:GetQueueAttributes
- sqs:ReceiveMessage
Resource:
- arn:aws:sqs:ap-northeast-1:111122223333:your-sqs-name
デプロイ
上のテンプレートsqs-mappling.yaml
を使ってスタックを作成します。デプロイは、コンソールでもCLIでもどちらでもできます。パラメータは適宜変更します。
項目 | 値 |
---|---|
スタック名 | sqs-mapping |
アカウント | 自分のみ 111122223333
|
リージョン | 東京(ap-northeast-1)、大阪(ap-northeast-3)、N.Virginia(us-east-1) |
Maximum concurrent accounts | 1(default) |
FailureToleranceCount | 0(default) |
StackSetを作って、
aws cloudformation create-stack-set --stack-set-name sqs-mapping --template-body file://sqs-mappling.yaml --capabilities CAPABILITY_IAM
StackのInstanceを作ります。
aws cloudformation create-stack-instances \
--stack-set-name my-stack-set \
--accounts 123456789012 \
--regions ap-northeast-1 ap-northeast-3 us-east-1 \
--operation-preferences FailureToleranceCount=0
(--operation-preferences FailureToleranceCount=0はなくても大丈夫です。ここを1に変えてみたりすると、別の結果が出せて面白いかも)
OperationIDが出力されるので、この値を次で使います。
予定通り失敗する
しばらくすると、2つめのスタックの作成で失敗して終了します。
想定通り、SQSが東京リージョンなので、大阪リージョンのとマッピングしようとして失敗しています。囲んだところのエラー文はこういうのです→Resource handler returned message: "Invalid request provided: Event source region must match Lambda region us-east-1 (Service: Lambda...
StackSetsをデプロイしたリージョンのStackSetsのページでまとめた情報が見れますが、他リージョンの各スタックの確認は、そのリージョンで見る必要があります。
DescribeStackSetOperation
ここからはCLIを使います。describe-stack-set-operation
でオペレーションの結果を見ます(途中でも見れます)。
aws cloudformation describe-stack-set-operation --stack-set-name sqs-mapping --operation-id 2da494d3-78e7-4df3-9a42-6fa73491b57d
CREATEがFAILEDしたことや、設定情報が出ていますが、下の方に"FailedStackInstancesCount": 1
があります。これが今回追加された機能です。
{
"StackSetOperation": {
"OperationId": "2da494d3-78e7-4df3-9a42-6fa73491b57d",
"StackSetId": "sqs-mapping:aac80512-b702-42ec-9a3f-daa5236c1e8f",
"Action": "CREATE",
"Status": "FAILED",
"OperationPreferences": {
"RegionConcurrencyType": "SEQUENTIAL",
"RegionOrder": [
"ap-northeast-1",
"ap-northeast-3",
"us-east-1"
],
"FailureToleranceCount": 0,
"MaxConcurrentCount": 1
},
"AdministrationRoleARN": "arn:aws:iam::111122223333:role/AWSCloudFormationStackSetAdministrationRole",
"ExecutionRoleName": "AWSCloudFormationStackSetExecutionRole",
"CreationTimestamp": "2022-11-05T02:09:01.920000+00:00",
"EndTimestamp": "2022-11-05T02:13:49.064000+00:00",
"StatusDetails": {
"FailedStackInstancesCount": 1
}
}
}
ListStackInstances
続いてスタックインスタンスを見てみます。以下は失敗してから実行した結果ですが、実行中でも見れます。
aws cloudformation list-stack-instances --stack-set-name sqs-mapping
- 各リージョンのスタックの情報の中に、LastOperationIdが入っていて、これが今回追加された機能です。
- ちなみに、上のコンソールキャプチャの画面でもこの項目はあります。
- 1つめのap-northeast-1は
SUCCEEDED
、2つめのap-northeast-3はFAILED
、3つめのus-east-1はCANCELLED
になっています。これは、FailureToleranceCountが0なので、失敗すると次のスタックに行かずにキャンセルしているということです(StatusReasonにも書いてある)。
{
"Summaries": [
{
"StackSetId": "sqs-mapping:aac80512-b702-42ec-9a3f-daa5236c1e8f",
"Region": "ap-northeast-1",
"Account": "111122223333",
"StackId": "arn:aws:cloudformation:ap-northeast-1:111122223333:stack/StackSet-sqs-mapping-a943d1b4-9e2f-40e4-9a37-d3547bf801e7/d32f7100-5cae-11ed-943e-0e04d872daa5",
"Status": "CURRENT",
"StackInstanceStatus": {
"DetailedStatus": "SUCCEEDED"
},
"OrganizationalUnitId": "",
"DriftStatus": "NOT_CHECKED",
"LastOperationId": "2da494d3-78e7-4df3-9a42-6fa73491b57d"
},
{
"StackSetId": "sqs-mapping:aac80512-b702-42ec-9a3f-daa5236c1e8f",
"Region": "ap-northeast-3",
"Account": "111122223333",
"StackId": "arn:aws:cloudformation:ap-northeast-3:111122223333:stack/StackSet-sqs-mapping-86f59d85-1ce2-4841-8d81-cf5fee5be2fb/fce75f80-5cae-11ed-b93c-0e319530c894",
"Status": "OUTDATED",
"StatusReason": "ResourceLogicalId:EventSourceMapping, ResourceType:AWS::Lambda::EventSourceMapping, ResourceStatusReason:Resource handler returned message: \"Invalid request provided: Event source region must match Lambda region ap-northeast-3 (Service: Lambda, Status Code: 400, Request ID: c51c41e2-7837-448f-863e-f1fccefa328e, Extended Request ID: null)\" (RequestToken: 4a0c1f48-4d2c-463e-278e-ea8ef6c4dc77, HandlerErrorCode: InvalidRequest).",
"StackInstanceStatus": {
"DetailedStatus": "FAILED"
},
"OrganizationalUnitId": "",
"DriftStatus": "NOT_CHECKED",
"LastOperationId": "2da494d3-78e7-4df3-9a42-6fa73491b57d"
},
{
"StackSetId": "sqs-mapping:aac80512-b702-42ec-9a3f-daa5236c1e8f",
"Region": "us-east-1",
"Account": "111122223333",
"Status": "OUTDATED",
"StatusReason": "Cancelled since failure tolerance has exceeded",
"StackInstanceStatus": {
"DetailedStatus": "CANCELLED"
},
"OrganizationalUnitId": "",
"DriftStatus": "NOT_CHECKED",
"LastOperationId": "2da494d3-78e7-4df3-9a42-6fa73491b57d"
}
]
}
削除する
先にスタックインスタンスを消して、
aws cloudformation delete-stack-instances \
--stack-set-name sqs-mapping \
--accounts 111122223333 \
--regions ap-northeast-1 ap-northeast-3 us-east-1 \
--no-retain-stacks
StackSetを消します。
aws cloudformation delete-stack-set --stack-set-name sqs-mapping
# 何も出力されない
まとめ
- CloudFormationのStackSetsをやってみました
- CLIで、DescribeStackSetOperationとListStackInstances新しい機能を確認しました
Discussion