【问题标题】:Why Custom Resource failed to stabilize in expected time in AWS Cloudformation?为什么自定义资源未能在 AWS Cloudformation 中按预期时间稳定?
【发布时间】:2020-07-14 19:20:12
【问题描述】:

我想用 CloudFormation 创建一个新的自定义资源来获得当前日期减去 X 天的结果,当我创建 lambda 函数时,我得到错误:

资源未能在预期时间内稳定。

我的代码是:

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  Environment:
    Description: Environment
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - test
      - prod
      - sbx
  DaysToSubstract:
    Description: Days To Substract to calculate dates to ingest with RedshiftLoader
    Type: Number
    Default: 1
Resources:
  lambdaDateRedshiftLoader:
    Type: 'AWS::Lambda::Function'
    DependsOn:
      - lambdaDateRedshiftLoaderRole
    Properties:
      Code:
        ZipFile: !Sub |
          from datetime import date, timedelta
          import cfnresponse
          def lambda_handler(event, context):
              current_delta = date.today() - timedelta(days=event['DaysToSubstract'])
              current_delta_str = current_delta.strftime("%Y-%m-%d")
              responseData['Dates'] = current_delta_str
              cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
      Environment:
        Variables:
          DaysToSubstract: !Sub '${DaysToSubstract}'
      Description: >-
        Calculate yesterday date to obtain start and end date to load the data
        with RedshiftLoader
      Handler: index.lambda_handler
      MemorySize: 128
      Role: !GetAtt lambdaDateRedshiftLoaderRole.Arn
      Runtime: python3.7
      Timeout: 30
  lambdaDateRedshiftLoaderRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: !Sub 'a3m${Environment}-datesRL-lambda-role'
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Action:
              - 'sts:AssumeRole'
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      Path: /service-role/
      Policies:
        - PolicyName: !Sub 'a3m${Environment}-lambda-datesRL-lambda-logs-policy'
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                Effect: Allow
                Resource:
                  - !Sub >-
                    arn:aws:logs:eu-west-1:${AWS::AccountId}:log-group:/aws/lambda/lambda-datesRL-uyc:*
  lambdaRL:
    Type: 'Custom::Value'
    Properties:
      ServiceToken: !GetAtt lambdaDateRedshiftLoader.Arn
Outputs:
  LambdaFunctionOutput:
    Value: !GetAtt lambdaRL.Dates
    Description: Return Value of Lambda Function (Date minus x days)

我在输出中使用cfnresponseSUCCESS 并使用!GetAtt lambdaRL.Dates

提前谢谢你

【问题讨论】:

  • 对于失败的 lambda,它们是否有任何 CloudWatch Logs 错误?

标签: amazon-web-services aws-lambda amazon-cloudformation aws-cloudformation-custom-resource


【解决方案1】:

您的 Lambda 函数出现错误,因此它从来没有机会调用 cfnresponse.send()。这意味着 CloudFormation 一直在等待响应。

这是 Lambda 函数的更新版本:

from datetime import date, timedelta
import cfnresponse, os

def lambda_handler(event, context):
    current_delta = date.today() - timedelta(days=int(os.environ['DaysToSubtract']))
    current_delta_str = current_delta.strftime("%Y-%m-%d")
    responseData = {}
    responseData['Dates'] = current_delta_str
    cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)

问题是:

  • 环境变量是通过os.environ()传递的,而不是event()
  • DaysToSubtract 值作为 string 传递,而不是 int,因此 timedelta() 函数失败(小心...SubstractSubtract 的拼写)
  • responseData 字典没有初始化,所以它给出了一个NameError: name 'responseData' is not defined 错误

我强烈建议您先在控​​制台中开发 Lambda 函数。然后,一旦它们开始工作,就将它们移动到 CloudFormation 模板中。这使调试变得容易得多。

哦,另外请注意在创建、更新和删除堆栈时调用自定义资源。这可能会导致一些意外行为,尤其是在 Delete 操作期间。插入if 语句以仅在Create 阶段运行代码通常是个好主意:

if event['RequestType'] == 'Create':

【讨论】:

    猜你喜欢
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    • 1970-01-01
    • 2019-08-02
    • 2018-03-02
    • 2023-04-11
    • 2018-03-10
    相关资源
    最近更新 更多