DEV Community

Cover image for Deploy Python Lambda Functions With Container Image
πŸš€ Vu Dao πŸš€
πŸš€ Vu Dao πŸš€

Posted on • Edited on

Deploy Python Lambda Functions With Container Image

Deploy Python Lambda functions with container images

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

    • These base images are preloaded with a language runtime and other components that are required to run the image on Lambda. AWS provides a Dockerfile for each of the base images to help with building your container image.
  • Open-source runtime interface clients

    • If you use a community or private enterprise base image, add a runtime interface client to the base image to make it compatible with Lambda.

What’s In This Document

πŸš€ Create Docker image container

Create an image from AWS base image

Dockerfile.aws



FROM amazon/aws-lambda-python:3.8

COPY app.py ./

CMD ["app.handler"]


Enter fullscreen mode Exit fullscreen mode

πŸš€ Create app.py as lambda handler



import sys


def handler(event, context):
    return 'Hello from AWS Lambda using Python' + sys.version + '!'


Enter fullscreen mode Exit fullscreen mode

πŸš€ Build and push the image to ECR



aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin 111111111111.dkr.ecr.ap-southeast-1.amazonaws.com
docker build -t pythonlambda .
docker tag pythonlambda:latest 111111111111.dkr.ecr.ap-southeast-1.amazonaws.com/pythonlambda:latest
docker push 111111111111.dkr.ecr.ap-southeast-1.amazonaws.com/pythonlambda:latest


Enter fullscreen mode Exit fullscreen mode

πŸš€ Create Lambda container image

Alt Text

πŸš€ Test the lambda function

1. Invoke lambda function

  • Start container ```

docker rm -f lambdaimagetest
docker run -d --name lambdaimagetest -it pythonlambda:latest bash
docker exec -it lambdaimagetest bash

- Invoke lambda function
Enter fullscreen mode Exit fullscreen mode

⚑ $ aws lambda invoke --function-name python-lambda-image --region ap-southeast-1 outfile

{
"StatusCode": 200,
"ExecutedVersion": $LATEST"
}
⚑ $ cat outfile

"Hello from AWS Lambda using Python3.8.5 (default, Aug 5 2020, 08:22:02) \n[GCC 8.3.0]!"


#### **2. Call lambda API from local container**
- This should be performed from AWS image base
- Run container
Enter fullscreen mode Exit fullscreen mode

⚑ $ docker run -d --name testapi -p 9000:8080 pythonlambda:latest

- Call API
Enter fullscreen mode Exit fullscreen mode

⚑ $ curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
"Hello from AWS Lambda using Python3.8.6 (default, Dec 16 2020, 01:05:15) \n[GCC 7.3.1 20180712 (Red Hat 7.3.1-11)]!"

- Deploy new image
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bdrihq86bqmtnm4ei5xe.png)
- Invoke lambda function
Enter fullscreen mode Exit fullscreen mode

⚑ $ aws lambda invoke --function-name python-lambda-image --region ap-southeast-1 outfile

{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
⚑ $ cat outfile
"Hello from AWS Lambda using Python3.8.6 (default, Dec 16 2020, 01:05:15) \n[GCC 7.3.1 20180712 (Red Hat 7.3.1-11)]!"


**Mirror**:
- https://github.com/vumdao/lambda-container-image
- https://vumdao.hashnode.dev/deploy-python-lambda-functions-with-container-image

**Read More**
- [Pelican-resume with docker-compose and AWS + CDK](https://dev.to/vumdao/pelican-resume-with-docker-compose-and-aws-cdk-33e5)
- [Using Helm Install Botkube Integrate With Slack On EKS](https://dev.to/vumdao/using-helm-install-botkube-integrate-with-slack-on-eks-gmn)
- [Ansible AWS EC2 Dynamic Inventory Plugin](https://dev.to/vumdao/ansible-aws-ec2-dynamic-inventory-plugin-3bme)
- [How To List All Enabled Regions Within An AWS account](https://dev.to/vumdao/list-all-enabled-regions-within-an-aws-account-4oo7)
- [Using AWS KMS In AWS Lambda](https://dev.to/vumdao/using-aws-kms-in-aws-lambda-2jm2)
- [Create AWS Backup Plan](https://dev.to/vumdao/create-aws-backup-plan-a0f)
- [Techniques For Writing Least Privilege IAM Policies](https://dev.to/vumdao/techniques-for-writing-least-privilege-iam-policies-4fc7)
- [EKS Persistent Storage With EFS Amazon Service](https://dev.to/vumdao/eks-persistent-storage-with-efs-amazon-service-14ei)
- [Create k8s Cronjob To Schedule Delete Expired Files](https://dev.to/vumdao/create-k8s-cronjob-to-schedule-delete-expired-files-1i41)
- [Amazon ECR - Lifecycle Policy Rules](https://dev.to/vumdao/amazon-ecr-lifecycle-policy-rules-1l59)
- [Connect Postgres Database Using Lambda Function](https://dev.to/vumdao/connect-postgres-database-using-lambda-function-1mca)
- [Using SourceIp in ALB Listener Rule](https://dev.to/vumdao/using-sourceip-in-alb-listener-rule-377b)
- [Amazon Simple Systems Manager (SSM)](https://dev.to/vumdao/amazon-simple-systems-manager-ssm-2pb0)
- [Invalidation AWS CDN Using Boto3](https://dev.to/vumdao/invalidation-aws-cdn-using-boto3-2k9g)
- [Create AWS Lambda Function Triggered By S3 Notification Event](https://dev.to/vumdao/create-aws-lambda-function-triggered-by-s3-notification-event-9p0)
- [CI/CD Of Invalidation AWS CDN Using Gitlab Pipeline](https://dev.to/vumdao/ci-cd-of-invalidation-aws-cdn-using-gitlab-pipeline-34op)
- [Create CodeDeploy](https://dev.to/vumdao/create-codedeploy-4425)
- [Gitlab Pipeline With AWS Codedeploy](https://dev.to/vumdao/gitlab-pipeline-with-aws-codedeploy-30cl)
- [Create AWS-CDK image container](https://dev.to/vumdao/create-aws-cdk-image-container-43ei)

<h3 align="center">
  <a href="https://dev.to/vumdao">:stars: Blog</a>
  <span> Β· </span>
  <a href="https://vumdao.hashnode.dev/">Web</a>
  <span> Β· </span>
  <a href="https://www.linkedin.com/in/vu-dao-9280ab43/">Linkedin</a>
  <span> Β· </span>
  <a href="https://www.linkedin.com/groups/12488649/">Group</a>
  <span> Β· </span>
  <a href="https://www.facebook.com/CloudOpz-104917804863956">Page</a>
  <span> Β· </span>
  <a href="https://twitter.com/VuDao81124667">Twitter :stars:</a>
</h3>
Enter fullscreen mode Exit fullscreen mode

Top comments (5)

Collapse
 
ymmark01 profile image
ymmark01

Hi, when testing with curl, where does the path "2015-03-31/functions/function/invocations" come from?

Collapse
 
vumdao profile image
πŸš€ Vu Dao πŸš€

That API path is in the container image where there's process listens to, you should have a check

Collapse
 
jason_yuen_5481b9088043d7 profile image
Jason Yuen

I am trying to follow step 1 but getting this os.environ error. Any help would be greatly appreciated.

File "/usr/local/lib/python3.8/runpy.py", line 194, in run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/local/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/usr/local/lib/python3.8/site-packages/awslambdaric/
main.py", line 21, in
main(sys.argv)
File "/usr/local/lib/python3.8/site-packages/awslambdaric/
main.py", line 14, in main
lambda_runtime_api_addr = os.environ["AWS_LAMBDA_RUNTIME_API"]
File "/usr/local/lib/python3.8/os.py", line 675, in __getitem
_
raise KeyError(key) from None
KeyError: 'AWS_LAMBDA_RUNTIME_API'

Collapse
 
chachan profile image
Cherny

you should use aws-lambda-rie (emulator) instead of aws-lambda-ric - docs.aws.amazon.com/lambda/latest/.... I believe that environment variable is set by AWS, so if it's not present that script will execute the emulator. This is an example

entry_script.sh

#!/bin/sh

if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
    exec /usr/local/bin/aws-lambda-rie /usr/local/bin/python -m awslambdaric $@
else
    exec /usr/local/bin/python -m awslambdaric $@
fi

Enter fullscreen mode Exit fullscreen mode

Dockerfile

FROM python:3.9-bullseye

ARG FUNCTION_DIR="/function"
WORKDIR ${FUNCTION_DIR}

RUN curl -Lo /usr/local/bin/aws-lambda-rie \
    https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \
    chmod +x /usr/local/bin/aws-lambda-rie

COPY entry_script.sh ${FUNCTION_DIR}

# Install dependencies
RUN pip install \
    --target ${FUNCTION_DIR} \
    awslambdaric

# Copy function code
COPY src/* ${FUNCTION_DIR}

ENTRYPOINT [ "sh", "entry_script.sh" ]
CMD [ "app.handler" ]
Enter fullscreen mode Exit fullscreen mode
Collapse
 
vumdao profile image
πŸš€ Vu Dao πŸš€

Hi Jason,

I guess you're trying to build lambda image from alternative base image but I recommend to use image base from AWS such as public.ecr.aws/lambda/python:3.8 or amazon/aws-lambda-python:3.8

For your issue, you're missing setting ENV AWS_LAMBDA_RUNTIME_API=, this variable env must be defined but you will still get following error after that

  File "/function/awslambdaric/lambda_runtime_client.py", line 76, in wait_next_invocation
    response_body, headers = runtime_client.next()
RuntimeError: Failed to get next
Enter fullscreen mode Exit fullscreen mode