如何从 AWS SAM 启动 lambda 函数并将自定义 AWS IAM 角色分配给 lambda

问题描述

现在在我们的 CloudFormation 模板中,我们正在创建几个 lambda 函数,然后使用多个 Cloudformation 模板来执行自动化任务,以便单击部署我们的产品堆栈。下面是 CF lambda 资源的示例 CF 模板。

HelmLambda:
  DependsOn: [ LambdaSGCleanup ]
  Type: AWS::Lambda::Function
  Properties:
    Handler: lambda_function.lambda_handler
    MemorySize: 512
    Role: !Ref EKSProvisionRoleArn
    Runtime: python3.7
    Timeout: 900
    Layers: [!Ref KubectlLayer,!Ref HelmLayer,!Ref CrhelperLayer]
    Code:
      S3Bucket: !Ref 'BucketName'
      S3Key: !Sub '${KeyPrefix}functions/packages/Helm/lambda.zip'
HelmLayer:
  Type: AWS::Lambda::LayerVersion
  Properties:
    Content:
      S3Bucket: !Ref 'BucketName'
      S3Key: !Sub '${KeyPrefix}functions/packages/helmLayer/lambda.zip'

在上面的 lambda 函数中,我们有两个依赖项。一种是 IAM 角色和层 ARN。这在运行时创建的 IAM 角色和层 ARN。

现在我们想将我们的产品放在 AWS-Marketplace 上,但我们知道 AWS-Marketplace 指南不支持创建上述 lambda 函数

我们正在考虑将 lambda 函数转换为 AWS SAM。但我们无法弄清楚如何使用在使用 AWS SAM 的 CF 堆栈部署期间在运行时创建的 IAM 角色和层 Arn 并创建 lambda 函数

对此的任何帮助或指导将不胜感激。

解决方法

因此,如果您想根据 documentation 引用 SAM 创建的角色和层,您需要在模板中定义它们,以下是一个工作模板:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-with-layers

  Sample SAM Template for sam-with-layers

Resources:
  LambdaRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${AWS::StackName}-lambda-role
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action: 'sts:AssumeRole'
            Principal:
              Service: lambda.amazonaws.com
      Policies:
        - PolicyName: WriteCloudWatchLogs
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                Resource: 'arn:aws:logs:*:*:*'
  HelloWorldFunction:
    Type: AWS::Serverless::Functionn
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Role: !GetAtt LambdaRole.Arn
      Layers:
        - !Ref MyLambdaLayer

  MyLambdaLayer:
        Type: AWS::Serverless::LayerVersion
        Properties:
            LayerName: MyLambdaLayer
            ContentUri: lambda-layer/
            CompatibleRuntimes:
              - python3.8
            RetentionPolicy: Retain

以下是我的目录结构:

.
├── README.md
├── hello_world
│   ├── app.py
│   └── requirements.txt
├── lambda-layer
│   └── python
│       └── lib
│           └── python3.8
│               └── site-packages
│                   └── hello.py
├── samconfig.toml
└── template.yaml
,

因此,如果您查看 documentation,您会发现您只是使用 Role 和 Layer 作为属性。无需为您进行太多重构。

,

以下是我们使用的示例片段,用于使通过 AWS SAM 模板创建的 AWS LAMBDA 函数使用在 CF 堆栈部署时创建的自定义 IAM 角色。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-with-layers

  Sample SAM Template for sam-with-layers

Parameters:
  EKSProvisionRoleArn:
    Type: String
Resources:
  HelmLambda:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: 's3://BUCKET/functions/packages/Helm/lambda.zip'
      Handler: lambda_function.lambda_handler
      Runtime: python3.7
      MemorySize: 512
      Timeout: 900
      Role: !Ref EKSProvisionRoleArn
      Layers:
        - !Ref HelmLambdaLayer
        - !Ref KubectlLambdaLayer
        - !Ref CrHelperLambdaLayer

  HelmLambdaLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: HelmLambdaLayer
      ContentUri: 's3://BUCKET/functions/packages/helmLayer/lambda.zip'
      CompatibleRuntimes:
        - python3.7
        - python3.6
      RetentionPolicy: Retain
  KubectlLambdaLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: KubectlLambdaLayer
      ContentUri: 's3://BUCKET/functions/packages/kubectlLayer/lambda.zip'
      CompatibleRuntimes:
        - python3.7
        - python3.6
      RetentionPolicy: Retain
  CrHelperLambdaLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: CrHelperLambdaLayer
      ContentUri: 's3://BUCKET/functions/packages/crhelperLayer/lambda.zip'
      CompatibleRuntimes:
        - python3.7
        - python3.6
      RetentionPolicy: Retain
Outputs:
  HelmLambdaArn:
    Description: Helm Lambda Function ARN
    Value: !GetAtt HelmLambda.Arn

下面是我们在 CF 模板中使用的片段,用于调用上面的 AWS SAM 模板来部署 lambda 函数:

  HelmLambda:
    Type: AWS::Serverless::Application
    Properties:
      Location:
        ApplicationId: 'ARN_TO_SAM'
        SemanticVersion: 0.0.5
      Parameters:
        EKSProvisionRoleArn: !Ref EKSProvisionRoleArn