HiveBrain v1.2.0
Get Started
← Back to all entries
snippetMinor

How to "inject" AWS Lambda code into a CloudFormation?

Submitted by: @import:stackexchange-devops··
0
Viewed 0 times
intocloudformationinjectawshowcodelambda

Problem

I'm exercising an idea of not using S3 bucket to refer to the code of a lambda function.

The usual example of a lambda CloudFormation code might look like:

MyLambda:
        Type: AWS::Lambda::Function
        Properties:
        FunctionName: hello
        Handler: index.handler
        Runtime: nodejs8.10
        Role: !GetAtt LambdaExecutionRole.Arn
        Code:
            ZipFile: |
            


But what I would like to do instead is:

  • inject that code from the file system, after potentially running my (unit) tests against that code;



  • maybe even just inject a compiled binary instead of actual code;



It is possible to do similar using CLI (create a zip manually, refer to it). I understand that CloudFormation changes would be running on the AWS infrastructure and not locally or a build server, so I'm open to other non-CloudFormation options.

So my question is - what is the best way to deploy the AWS functions sticking to "infrastructure as code", preferably sticking with CloudFormation. Or is S3 + CloudFormation really the best option?

Solution

You've got a couple of options:

  1. Embed the source code to the CloudFormation template



I do just that in my ec2-start-stop demo. You'll see file ec2-start-stop.template.yml with these lines:

StartStopLambda:
      Type: AWS::Lambda::Function
      Properties:
        [...]
        Runtime: python3.6
        Code: 
          ZipFile:
            Fn::Join:
            [...]
            -     
              - "%%{ec2-start-stop.lambda.py}%%"


Then I've got the actual Python script referred in the %%{ec2-start-stop.lambda.py}%% and a simple import-files.py script that somewhat intelligently embeds the python file into the yaml file and creates a valid standalone CloudFormation template with the lambda code in it.

Note that you're limited to 4096 bytes including new lines for your lambda code.

  1. Use aws cloudformation package / deploy



If you've got a more complex Lambda that needs external libraries or doesn't fit in the 4kB limit you can use aws cloudformation package and aws cloudformation deploy to facilitate the deployment to CI/CD.

In this case your Lambda resource in the template points to a local directory, e.g. lambda/. The package command then zips up the contents of the directory, uploads to the provided S3 Bucket with a unique name and generates an updated CFN template with the link to the uploaded file. The aws cloudformation deploy command then takes the template, creates a change set and applies the changes, thus updating the Lambda.

I've used both methods in CI/CD pipelines and both work well because the source files are kept in separate files until deployment.

Hope that helps :)

Code Snippets

StartStopLambda:
      Type: AWS::Lambda::Function
      Properties:
        [...]
        Runtime: python3.6
        Code: 
          ZipFile:
            Fn::Join:
            [...]
            -     
              - "%%{ec2-start-stop.lambda.py}%%"

Context

StackExchange DevOps Q#5089, answer score: 3

Revisions (0)

No revisions yet.