3

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: |
            <can we "inject" the code and/or binary here?>

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?

1
  • As soon as your lambda code require non standard lib, you need to package it first, pushing it as base64 works, but you'll be missing the required libs at run. You have to upload a zip package of the lambda before running cloudformation
    – Tensibai
    Commented Sep 30, 2018 at 20:51

1 Answer 1

3

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.


2. 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 :)

1
  • Thank you, didn't know about package / deploy. It is just a little bit of automation on top of manual upload to S3 but might be just enough to keep it "clean"-ish. This goes into CF generation solution so I wonder if there are some good tools without too much abstraction? Terraform? Commented Oct 1, 2018 at 16:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.