<p>You've got a couple of options:</p>

<h3>1. Embed the source code to the CloudFormation template</h3>

<p>I do just that in my <a href="https://github.com/mludvig/ec2-start-stop" rel="nofollow noreferrer">ec2-start-stop</a> demo. You'll see file <code>ec2-start-stop.template.yml</code> with these lines:</p>

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

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

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

<hr>

<h3>2. Use <code>aws cloudformation package / deploy</code></h3>

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

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

<hr>

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

<p>Hope that helps :)</p>

CC BY-SA 4.0
2018-10-01T16:34:53.137Z
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?
Dmytrii Nagirniak
CC BY-SA 4.0
2018-09-30T21:50:55.490Z
2018-09-30T21:50:55.490Z
MLu
<p>I'm exercising an idea of not using S3 bucket to refer to the code of a lambda function.</p>

<p>The usual example of a lambda CloudFormation code might look like:</p>

<pre><code>    MyLambda:
        Type: AWS::Lambda::Function
        Properties:
        FunctionName: hello
        Handler: index.handler
        Runtime: nodejs8.10
        Role: !GetAtt LambdaExecutionRole.Arn
        Code:
            ZipFile: |
            &lt;can we "inject" the code and/or binary here?&gt;
</code></pre>

<p>But what I would like to do instead is:</p>

<ul>
<li>inject that code from the file system, after potentially running my (unit) tests against that code;</li>
<li>maybe even just inject a compiled binary instead of actual code;</li>
</ul>

<p>It is <a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-go-how-to-create-deployment-package.html" rel="nofollow noreferrer">possible to do similar</a> 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.</p>

<p>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?</p>

CC BY-SA 4.0
2018-09-30T20:51:01.990Z
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
<amazon-web-services><amazon-s3><infrastructure-as-code><aws-lambda>
How to "inject" AWS Lambda code into a CloudFormation?
Dmytrii Nagirniak
# How to "inject" AWS Lambda code into a CloudFormation?

(Asked by: username_0 on 2018-09-30)

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?

**Tags:** amazon-web-services, amazon-s3, infrastructure-as-code, aws-lambda

> **Comments:**
> **username_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  

---

## 1 answers

### Answer by username_2 on 2018-09-30. Score: 3 | Accepted answer

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

> **Comments:**
> **username_0**: 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?  

---

