Deploy Python Lambda functions with container images in AWS CDK
- Published on
- Authors
- Name
- Binh Bui
- @bvbinh
Photo by Navi
This is a blog post about deploying Python Lambda functions with container images in AWS CDK.
You can deploy your Lambda function code as a container image.
AWS provides the following resources to help you build a container image for your Python function:
- AWS base images for Lambda
- Open-source runtime interface clients (RIC)
- Open-source runtime interface emulator (RIE)
The workflow for a function defined as a container image includes these steps:
- Build your container image using the resources listed in this topic.
- Upload the image to your Amazon ECR container registry.
- Create the Lambda function or update the function code to deploy the image to an existing function.
But with AWS CDK, you can do this in a single step. Let see how to do this.
First, build a simple lambda function
#!/usr/bin/env python3
import wikipedia
def handler(event, context):
print("{}".format(event))
if event:
result = wikipedia.page(event.get('wiki', 'los angeles'))
return "{}".format(result.summary)
else:
return "You didn't tell me to look anything up, much sad."
And then, create a Dockerfile to build the image.
FROM public.ecr.aws/lambda/python:3.8
# ${LAMBDA_TASK_ROOT}
WORKDIR ${LAMBDA_TASK_ROOT}
# copy all python files to lamda working directory
COPY main.py .
# Copy requirements.txt to lamda working directory
COPY requirements.txt .
RUN pip3 install -r requirements.txt
# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "main.handler" ]
Note: Source code of this tutorial is available GitHub
Use AWS CDK to deploy the image
import { Stack, StackProps, CfnOutput } from 'aws-cdk-lib'
import { Construct } from 'constructs'
import * as lambda from 'aws-cdk-lib/aws-lambda'
import * as path from 'path'
export class CdkStarterStackStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props)
const fn = new lambda.Function(this, 'TestContainerFunction', {
code: lambda.Code.fromAssetImage(path.join(__dirname, '..', 'lambda'), {
exclude: ['cdk.out'],
}),
handler: lambda.Handler.FROM_IMAGE,
runtime: lambda.Runtime.FROM_IMAGE,
architecture: lambda.Architecture.ARM_64,
})
const fnUrl = fn.addFunctionUrl({
authType: lambda.FunctionUrlAuthType.NONE,
cors: {
// Allow this to be called from websites on https://example.com.
// Can also be ['*'] to allow all domain.
allowedOrigins: ['https://example.com'],
},
})
// outputs the url of the function
new CfnOutput(this, 'TestContainerFunctionURL', {
value: fnUrl.url,
})
}
}
Let's over go what we did in the code snippet above.
- We created a lambda function from the code in the lambda directory.
- We created a lambda URL from the function. (this is for testing purpose).
Deploy stack and testing
npx cdk deploy --outputs-file ./cdk-outputs.json
After deploying the stack, we can test the function by visiting the URL exported by the stack.
If your container needs both languages, compare this Python-only example with the Lambda container using Node.js and a custom Python runtime.
Clean up
Don't forget to clean up the resources you created.
npx cdk destroy
Thanks for reading this tutorial. I hope you find it useful. If you have any questions, please feel free leave a comment.