cloudpack あら便利カレンダー 2019 の記事となります。誕生秘話 はこちら。
AWS CloudFormation(CFn)のLambda-Backedカスタムリソースを利用するとCFnが対応していないリソースでもAWS Lambdaを利用して管理できます。
AWS Lambda-backed カスタムリソース - AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.html
その際に、リソース作成するとレスポンスはすぐに返ってくるけど、リソースが利用できるまでに時間がかかるものを取り扱えるようにしてみました。
テンプレート
CFnでリソース作成を待ってから関連するリソース作成などができるようにするテンプレートです。
Resources:
CreateResource:
Type: Custom::CustomResource
Properties:
ServiceToken: !GetAtt CreateResourceFunction.Arn
CustomResource:
Type: Custom::CustomResource
Properties:
ServiceToken: !GetAtt CustomResourceFunction.Arn
ResourceId: !GetAtt CreateResource.Id
DependsOn: CreateResource
CreateResourceFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role: !GetAtt FunctionExecutionRole.Arn
Code:
ZipFile: !Sub |
import cfnresponse
def handler(event, context):
response = {}
if event['RequestType'] == 'Create':
try:
# ほんとはここでリソース作成
response = {
"Id": "hoge"
}
except Exception as e:
response = {'error': str(e)}
cfnresponse.send(event, context, cfnresponse.FAILED, response)
return
cfnresponse.send(event, context, cfnresponse.SUCCESS, response)
Runtime: python3.7
CustomResourceFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role: !GetAtt FunctionExecutionRole.Arn
Code:
ZipFile: !Sub |
import cfnresponse
import time
def handler(event, context):
Id = event['ResourceProperties']['ResourceId']
# リソース作成完了を待ち受ける
response = {}
while True:
# ホントはここでリソース取得
response = {
"Id": Id,
"Status": "AVAILABLE"
}
# 特定のステータスになったら抜ける
if response['Status'] == 'AVAILABLE':
break
print('create wait...')
time.sleep(60)
cfnresponse.send(event, context, cfnresponse.SUCCESS, response)
Runtime: python3.7
Timeout: 900
FunctionExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: root
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "arn:aws:logs:*:*:*"
ポイント
カスタムリソースを2つ用意する
リソースを作成するCreateResource
とリソース情報を取得するCustomResource
のカスタムリソースを定義することで、リソース作成を待ち受けできるようにしています。
Lambda関数のタイムタウト x 3回まで待ち受けできる
AWS Lambdaの関数は最大15分のタイムタウト設定ができます。またLambda-Backedカスタムリソースで関数実行に失敗すると3回までリトライしてくれるのでそれを利用して最大45分間待ち受けできるようになります。
AWS Lambda の制限 - AWS Lambda
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/limits.html
※Lambda-Backedカスタムリソースでのリトライ回数について必ず3回実行されるのかはドキュメントが見当たらず不明確となります。
AWS Lambda 再試行動作 - AWS Lambda
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/retries-on-errors.html
DependsOn
属性を利用してリソース作成順を制御する
CFnのDependsOn
属性を利用することで、リソース作成CreateResource
後、リソース情報取得CustomResource
が実行されるようにします。
後続するリソースはCustomResource
をDependsOn
属性に指定することでリソース作成完了してから実行されるようにできます。
DependsOn 属性 - AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html
カスタムリソースの更新・削除と絡めて利用する
下記記事の内容と組み合わせることで、カスタムリソースの更新・削除が実現できます。
AWS CloudFormationのLambda-backedカスタムリソースでリソースの更新・削除をする方法 - Qiita
https://qiita.com/kai_kou/items/7be2eb9a36611bb5da12
参考
AWS Lambda-backed カスタムリソース - AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.html
AWS Lambda の制限 - AWS Lambda
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/limits.html
AWS Lambda 再試行動作 - AWS Lambda
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/retries-on-errors.html
DependsOn 属性 - AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html
AWS CloudFormationのLambda-backedカスタムリソースでリソースの更新・削除をする方法 - Qiita
https://qiita.com/kai_kou/items/7be2eb9a36611bb5da12