Skip to content

Commit 2caba7a

Browse files
committed
Merge pull request #1 from nemborkar/develop
Develop
2 parents fd910e4 + 703b57d commit 2caba7a

8 files changed

Lines changed: 82 additions & 58 deletions

File tree

Dockerfile

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
# amazonlinux:2023 has python 3.9 + venv
1+
ARG PYTHON_VERSION=3.14
2+
23
FROM amazonlinux:2023
34

4-
# We will need pip3 and zip
5-
RUN yum -y update && yum -y install \
6-
python3-pip \
7-
zip
5+
RUN yum -y update && \
6+
yum -y install \
7+
python${PYTHON_VERSION} \
8+
rsync \
9+
zip
10+
11+
ENV PYTHON_VERSION=${PYTHON_VERSION}

README.md

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,50 @@
1-
# lambda-layers
2-
To run Python functions in AWS Lambda with extra imported packages, we need to have these packages in Lambda Layers
3-
However making the layers locally uses your local environment's Python Runtime, OS and CPU Architecture.
4-
So the zip files we upload to the Lambda layers can be very hit or miss (mostly miss)
1+
# Lambda Layers for Python Runtimes
2+
### Problem
3+
To import packages in AWS Lambda Functions, they are required as Lambda Layers
54

6-
This repo tries to solve that problem with the following steps,
7-
1. Create an Amazon Linux container
8-
2. Install the required packages with requirements.txt and pip3
9-
3. Generate the zip file INSIDE the container
10-
4. Output the zip file to your local machine
5+
These layers need to match the language runtime/version, architecture, lambda operating system, etc. Creating these in local environments can cause unforeseen inconsistencies and potential compatibility issues
6+
7+
### Solution
8+
This repo tries to solve the problem by standardising the environment using a container. The packages are baked into layers inside this standard container. A .zip artifact is generated, which can be easily uploaded to Lambda Layers
9+
10+
 
1111

1212
# Usage
13-
1. update requirements.txt with the packages you want in the layer
14-
- Use specific versions, if possible. eg: ```requests==2.31.0``` instead of ```requests```
15-
- [Syntax for requirements.txt](https://pip.pypa.io/en/stable/reference/requirements-file-format/)
16-
- [Introduction to requirements.txt](https://www.freecodecamp.org/news/python-requirementstxt-explained/)
17-
18-
2. run the runner.sh script and it will generate the python.zip file
19-
```./runner.sh```
20-
21-
3. upload this python.zip file to Lambda layers and use with,
22-
Python Runtime : Python 3.9
23-
Architecture : x86_64
24-
25-
# Change Python Runtime or Architecture
26-
- If you wish to use a different Python runtime like 3.11, 3.12 etc, you can import a newer [Amazon Linux base image](https://hub.docker.com/_/amazonlinux) in the Dockerfile.
27-
This generally comes with a new stable version of Python
28-
- You can also install a [specific version of Python](https://www.python.org/downloads/) by updating the ```yum install``` lines of the Dockerfile
29-
- arm64 has known unresolved issues on Lambda with Python as of 20240322, so I recommend against it for now
13+
1. Update `requirements.txt` with the packages you want in the layer
14+
[Syntax options for requirements.txt](https://pip.pypa.io/en/stable/reference/requirements-file-format/)
15+
2. Make sure podman or docker daemon is running
16+
3. Execute `runner.sh` script and it will generate the `python_layer.zip` artifact
17+
4. Upload `python_layer.zip` to Lambda Layers and use it in your Python Lambda function(s)
18+
> [!NOTE]
19+
> Stating package versions explicitly lowers dependencies, layer size and attack surface
20+
21+
22+
### Following is done automatically by `runner.sh`
23+
1. Create an Amazon Linux container
24+
2. Install the required packages written in requirements.txt with pip
25+
3. Generate the zip file INSIDE the container so as to match the Lambda environment
26+
4. Output the zip file to your local machine which you can upload to Lambda Layers
27+
5. Delete the Amazon Linux container and image to free up space (can be disabled in `runner.sh` file)
28+
29+
 
30+
31+
# Supported Defaults
32+
> [!NOTE]
33+
> Python Runtime: Python 3.14
34+
> Lambda Operating System: Amazon Linux 2023
35+
> Architecture: x86_64
36+
> Container Runtimes: Podman, Docker
37+
38+
# Support for other Python versions
39+
If you wish to build layers for Python runtimes/versions other than 3.14,
40+
1. [Note the operating system necessary for your python runtime.](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtimes-supported)
41+
This repo uses Amazon Linux 2023 by default. But if your runtime/version needs a different operating system, you can find the specific image tags on [amazonlinux dockerhub](https://hub.docker.com/_/amazonlinux). Use that tag in the `Dockerfile`
42+
43+
2. Update the `PYTHON_VERSION` argument in the `Dockerfile`
44+
3. Execute `runner.sh`
45+
46+
47+
# Future Considerations
48+
- Support for arm64 architecture
49+
- Support runtimes for other languages
50+
- Support other popular container runtimes

docker_install.sh

Lines changed: 0 additions & 6 deletions
This file was deleted.

install.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
python${PYTHON_VERSION} -m venv python
2+
source /python/bin/activate
3+
4+
pip install --upgrade pip
5+
pip install -r requirements.txt -t /python/lib/python*/site-packages
6+
7+
mkdir /tmp/python
8+
rsync -av --exclude=pip* /python/lib/python*/site-packages/* /tmp/python
9+
cd tmp/
10+
zip -r9 python_layer.zip python

python.zip

-9.94 MB
Binary file not shown.

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
requests
1+
requests==2.33.1

runner.sh

100644100755
Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
container_name=layer_builder_docker
2-
docker_image=layer_builder_image
1+
CONTAINER=layer_builder
2+
IMAGE=layer_builder_img
3+
RUNTIME=$(command -v podman || command -v docker)
34

4-
docker build -t $docker_image .
5-
docker run -td --name=$container_name $docker_image
6-
docker cp ./requirements.txt $container_name:/
5+
$RUNTIME build -t $IMAGE .
6+
$RUNTIME run -td --name=$CONTAINER $IMAGE
7+
$RUNTIME cp ./requirements.txt $CONTAINER:/
78

8-
docker exec -i $container_name /bin/bash < ./docker_install.sh
9-
docker cp $container_name:/python.zip python.zip
10-
docker stop $container_name
11-
docker rm $container_name
9+
$RUNTIME exec -i $CONTAINER /bin/bash < ./install.sh
10+
$RUNTIME cp $CONTAINER:/tmp/python_layer.zip python_layer.zip
11+
$RUNTIME stop $CONTAINER
12+
13+
$RUNTIME rm $CONTAINER
14+
$RUNTIME rmi $IMAGE:latest
15+
16+
echo "Layer is ready..."
17+
echo "Size: $(du -sh python_layer.zip)"

runner_podman.sh

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)