Search code examples
aws-cloudformationboilerplate

CloudFormation template: reduce boilerplate code


I'm trying to compose CF template to deploy a serverless system consisting of several Lambdas. In my case, Lambda resource descriptions share a lot of properties; the only difference is filename and handler function.

How can I define something like common set of parameters in my template?

This boilerplate is awful:

  LambdaCreateUser:
    Type: AWS::Lambda::Function
    Properties: 
      Code:
        S3Bucket:
          Ref: BucketForLambdas
        S3Key: create_user.zip
      Handler: create_user.lambda_handler
      Runtime: python3.7
      Role: 
        Fn::GetAtt: [ LambdaRole , "Arn" ]
      Environment:
        Variables: { "EnvTable": !Ref EnvironmentTable, "UsersTable": !Ref UsersTable }
  LambdaDeleteUser:
    Type: AWS::Lambda::Function
    Properties: 
      Code:
        S3Bucket:
          Ref: BucketForLambdas
        S3Key: delete_user.zip 
      Handler: delete_user.lambda_handler  
      Runtime: python3.7   
      Role:
        Fn::GetAtt: [ LambdaRole , "Arn" ]
      Environment:
        Variables: { "EnvTable": !Ref EnvironmentTable, "UsersTable": !Ref UsersTable }

Solution

  • What you're looking for is AWS SAM which is a layer of syntactic sugar on top on CloudFormation. A basic representation of your template with AWS SAM would look like this:

    AWSTemplateFormatVersion: '2010-09-09'
    Transform: 'AWS::Serverless-2016-10-31'
    
    Globals:
      Function:
        Runtime: python3.7
        Environment:
          Variables:
            EnvTable: !Ref EnvironmentTable
            UsersTable: !Ref UsersTable
    
    Resources:
      LambdaCreateUser:
        Type: AWS::Serverless::Function
        Properties: 
          Code:
            S3Bucket:
              Ref: BucketForLambdas
            S3Key: create_user.zip
          Handler: create_user.lambda_handler
          Role: !GetAtt LambdaRole.Arn
      LambdaDeleteUser:
        Type: AWS::Serverless::Function
        Properties: 
          Code:
            S3Bucket:
              Ref: BucketForLambdas
            S3Key: delete_user.zip 
          Handler: delete_user.lambda_handler  
          Role: !GetAtt LambdaRole.Arn
    

    But that's not the end. You can replace the code definition with a path to your code or even inline code and use sam build and sam package to build and upload your artifacts. You can also probably replace the role definition with SAM policy templates for further reduction of boilerplate code.