Search code examples
aws-lambdaaws-cloudformationserverless-frameworkserverlessaws-sam

How do you deploy cloudformation with a lambda function without inline code?


the lambda function size is over 4096 characters, so I can't deploy lambda function as inline codes in cloudformation template.

(https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html)

ZipFile

Your source code can contain up to 4096 characters. For JSON, you must escape quotes and special characters such as newline (\n) with a backslash.

I have to zip it first, upload to a s3 bucket, set s3 bucket and file details in cloudformation, and deploy it.

I can't find a way to deploy with one command. If I update the lambda code, I have to repeat the above steps

But with both AWS SAM or Serverless Framework, they can deploy lambda functions without inline codes.

The only issue is, AWS SAM or serverless framework create API gateway as default, that I don't need it to be created

Any solution or recommendations for me?

Updates

SAM does support to deploy lambda functions without creating API gateway. So problem is fixed


Solution

  • If you're managing your deployment with plain CloudFormation and the aws command line interface, you can handle this relatively easily using aws cloudformation package to generate a "packaged" template for deployment.

    aws cloudformation package accepts a template where certain properties can be written using local paths, zips the content from the local file system, uploads to a designated S3 bucket, and then outputs a new template with these properties rewritten to refer to the location on S3 instead of the local file system. In your case, it can rewrite Code properties for AWS::Lambda::Function that point to local directories, but see aws cloudformation package help for a full list of supported properties. You do need to setup an S3 bucket ahead of time to store your assets, but you can reuse the same bucket in multiple CloudFormation projects.

    So, let's say you have an input.yaml with something like:

      MyLambdaFunction:
        Type: AWS::Lambda::Function
        Properties:
          Code: my-function-directory
    

    You might package this up with something like:

    aws cloudformation package \
        --template-file input.yaml \
        --s3-bucket my-packaging-bucket \
        --s3-prefix my-project/ \
        --output-template-file output.yaml
    

    Which would produce an output.yaml with something resembling this:

      MyLambdaFunction:
        Properties:
          Code:
            S3Bucket: my-packaging-bucket
            S3Key: my-project/0123456789abcdef0123456789abcdef
        Type: AWS::Lambda::Function
    

    You can then use output.yaml with aws cloudformation deploy (or any other aws cloudformation command accepting a template).

    To truly "deploy with one command" and ensure you always do deployments consistently, you can combine these two commands into a script, Makefile, or something similar.