LoginSignup
4
2

More than 3 years have passed since last update.

AWS CloudFormationのLambda-Backedカスタムリソースでリソース作成を待ち受けできるようにする

Last updated at Posted at 2019-07-10

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 が実行されるようにします。
後続するリソースはCustomResourceDependsOn 属性に指定することでリソース作成完了してから実行されるようにできます。

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

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2