You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过AWS CloudFormation自定义资源动态生成Lambda应用配置文件

结论

完全可以通过CloudFormation自定义资源实现该需求,不需要进行本地文件写入操作,通过云上托管的配置存储结合资源依赖即可实现配置预生成后再部署Lambda的流程。

实现核心逻辑

  • 首先通过一个辅助Lambda支撑自定义资源的执行逻辑,在自定义资源的Create/Update生命周期中完成动态配置生成,将生成的配置存入SSM参数存储、Secrets Manager或S3对象存储,自定义资源执行成功后才会进入后续资源创建流程
  • 给目标Lambda资源添加DependsOn属性,指定依赖上述自定义资源,强制CloudFormation在配置生成完成后才启动Lambda的创建流程
  • 目标Lambda可以在启动时直接拉取预先生成的配置,也可以在部署阶段将配置作为环境变量注入,或者把配置文件打包进Lambda的部署包中使用
CloudFormation模板示例

以下是完整的YAML模板示例,实现动态生成配置后再创建目标Lambda的流程:

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  DatabaseHost:
    Type: String
  AppApiKey:
    Type: String
    NoEcho: true
  Environment:
    Type: String
    Default: prod

Resources:
  # 自定义资源执行角色,授予配置写入和日志上报权限
  CustomResourceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: CustomResourcePolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - ssm:PutParameter
                  - ssm:DeleteParameter
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"

  # 生成配置的辅助Lambda
  ConfigGeneratorLambda:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.9
      Role: !GetAtt CustomResourceRole.Arn
      Handler: index.lambda_handler
      Code:
        ZipFile: |
          import json
          import boto3
          import cfnresponse
          ssm = boto3.client('ssm')
          
          def lambda_handler(event, context):
              response_data = {}
              try:
                  if event['RequestType'] in ['Create', 'Update']:
                      # 此处可编写自定义的动态配置生成逻辑,支持拼接其他资源的输出参数
                      app_config = {
                          "db_host": event['ResourceProperties']['DbHost'],
                          "api_key": event['ResourceProperties']['ApiKey'],
                          "env": event['ResourceProperties']['Env'],
                          "enable_feature": True
                      }
                      # 配置写入SSM参数存储,敏感配置可使用SecureString类型加密存储
                      ssm.put_parameter(
                          Name="/app/lambda/runtime_config",
                          Value=json.dumps(app_config),
                          Type="SecureString",
                          Overwrite=True
                      )
                      response_data['ConfigParameterName'] = "/app/lambda/runtime_config"
                  elif event['RequestType'] == 'Delete':
                      # 栈删除时自动清理生成的配置
                      ssm.delete_parameter(Name="/app/lambda/runtime_config")
                  cfnresponse.send(event, context, cfnresponse.SUCCESS, response_data)
              except Exception as e:
                  cfnresponse.send(event, context, cfnresponse.FAILED, {"Error": str(e)})

  # 自定义资源,触发配置生成流程
  GenerateAppConfig:
    Type: Custom::GenerateAppConfig
    Properties:
      ServiceToken: !GetAtt ConfigGeneratorLambda.Arn
      DbHost: !Ref DatabaseHost
      ApiKey: !Ref AppApiKey
      Env: !Ref Environment

  # 目标业务Lambda角色,授予配置读取权限
  TargetLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: LambdaConfigReadPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - ssm:GetParameter
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"

  # 目标业务Lambda,依赖配置生成完成后才会创建
  TargetLambda:
    Type: AWS::Lambda::Function
    DependsOn: GenerateAppConfig
    Properties:
      Runtime: python3.9
      Role: !GetAtt TargetLambdaRole.Arn
      Handler: index.lambda_handler
      Environment:
        Variables:
          CONFIG_PARAM_NAME: !GetAtt GenerateAppConfig.ConfigParameterName
      Code:
        ZipFile: |
          import json
          import boto3
          ssm = boto3.client('ssm')
          
          # Lambda冷启动时拉取预先生成的配置
          runtime_config = json.loads(ssm.get_parameter(
              Name="/app/lambda/runtime_config", 
              WithDecryption=True
          )['Parameter']['Value'])
          
          def lambda_handler(event, context):
              # 业务逻辑直接使用预生成的配置即可
              return {
                  'statusCode': 200,
                  'body': json.dumps({'config_loaded': True, 'env': runtime_config['env']})
              }

注意事项

  • 示例中的Resource: "*"仅作演示使用,生产环境请按最小权限原则限制到具体的SSM参数ARN、日志组ARN等资源
  • 如果你需要将配置作为独立文件嵌入Lambda部署包,可以在自定义资源中生成配置后上传到S3存储桶,将S3对象地址和版本作为自定义资源的输出,目标Lambda的Code属性直接引用该S3地址即可
  • 敏感配置建议使用SSM SecureString或Secrets Manager存储,不要直接明文写入Lambda环境变量

内容的提问来源于stack exchange,提问作者Hakuna Matata

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 12:45:03