先行研究
CDKではないけど参考になる
TL; DR
- PhysicalResourceId はちゃんと指定しよう。何も考えずに
context.logStreamName
をそのまま使うのはやめよう。
custom_resource_lambda.js
function sendResponse(event, context, responseStatus, responseData) {
var responseBody = JSON.stringify({
Status: responseStatus,
Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,
// ↓ ここをちゃんと管理しないとカスタムリソースのDELETEが無駄に発生するので、
// ↓ `context.logStreamName` をそのまま使うのはやめよう
PhysicalResourceId: context.logStreamName,
StackId: event.StackId,
RequestId: event.RequestId,
LogicalResourceId: event.LogicalResourceId,
Data: responseData
});
- ちゃんと公式のドキュメントを読もう。クラスメソッドの技術ブログだからといってそのまま使うのはやめよう。
見るべき記事
- https://ks888.hatenablog.com/entry/2017/05/18/123000
- https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref-responses.html
- https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cfn-customresource.html
- https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-lambda-function-code-cfnresponsemodule.html
見るべきではない記事(見るべきではないのでリンクしない)
https://dev.classmethod.jp/articles/get-latest-ami-by-using-lambda-backed-custom-resources/
https://dev.classmethod.jp/articles/cloudformation-lambda-backed/
何が問題か?
カスタムリソースの応答を返す為に作られた、この関数が問題です。
lambda.js
//Sends response to the pre-signed S3 URL
function sendResponse(event, context, responseStatus, responseData) {
var responseBody = JSON.stringify({
Status: responseStatus,
Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,
PhysicalResourceId: context.logStreamName,
StackId: event.StackId,
RequestId: event.RequestId,
LogicalResourceId: event.LogicalResourceId,
Data: responseData
});
ここでカスタムリソースの削除を検知するために PhysicalResourceId
へ文字列を設定するのですが、デフォルトの値は Amazon CloudWatch のログストリームの名前です。
この名前は時間経過とともに変わっていくため、久しぶりにカスタムリソースを更新したつもりが、(PhysicalResourceId
が変わってしまって)更新のあとに削除が入り込む流れになってしまうことがあります。そのため、設定したカスタムリソースの削除とは何なのかをちゃんと把握して PhysicalResourceId
を設定する必要があります。デフォルト実装(あるいはクラスメソッドの技術ブログの実装の単純コピペ)で設定してしまうと、忘れた頃に酷い目に遭うかも知れません……。
ちゃんと公式のドキュメントを読もう。クラスメソッドの技術ブログだからといってそのまま使うのはやめよう。理解しないままパラメータに適当な値を指定するのはやめよう。