0
votes

Right now in our CloudFormation templates we are creating few lambda functions, which then used multiple Cloudformation templates to do the automation task in order to have single click deployment of our product stack. Below is the sample CF template for CF lambda resources.

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'

In above lambda function we have two dependencies. One is IAM role and Layer ARN. IAM role and Layer ARN this create on run time.

Now we want to put our product on AWS-Marketplace and we came to know that creating lambda function as above is not supported by AWS-Marketplace guidelines.

We are thinking of converting our lambda functions to AWS SAM. but we are not able to figure out how to use IAM role and Layer Arn which are created at run time during the CF stack deployment with AWS SAM and create lambda functions.

Any help or guidance on this will be highly appreciated.

3

3 Answers

1
votes

So if you want to reference the role and layer created by SAM as per the documentation you need to define them in the template, below is a working template :

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

and below is my dir structure:

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

So if you look at the documentation, you can see that you just use Role and Layer as properties. There isn't much of a refactoring to do for you.

0
votes

below is the sample snippet which we are using in order to make AWS LAMBDA functions which are created through AWS SAM templates to use custom IAM role which get created at the time of CF stack deployment.

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

below is snippet which we are using in CF templates to call above AWS SAM template to deploy lambda functions:

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