How to "inject" AWS Lambda code into a CloudFormation? 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: |
            &lt;can we "inject" the code and/or binary here?&gt;


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