Install Python packages in AWS Lambda using Elastic File System
This post is about installing packages in AWS Lambda using an Elastic File System.
Install Python packages in AWS Lambda using Elastic File System
Definitions
- Lambda - Service that enables you to use compute resources without having to launch or manage the underlying infrastructure - leveraged in serverless architectures.
- EFS - Fully managed NFS file system designed for Linux workloads.
- VPC - Logically isolated section of the AWS Cloud where you can launch AWS resources in a virtual network that you define (the lambda, EFS and the EC2 instance you use to install the packages must lie in the same VPC)
- Subnets - A range of IP addresses in your VPC. You can attach AWS resources, such as EFS filesystems, Lambda and EC2 instances to subnets.
- EC2 instances are associated with a single subnet
- EFS filesystems and Lambdas can work on a VPC across multiple subnets for higher availability
- Security Groups - Firewall-like controls for instances within a VPC that controls access for inbound and outbound traffic.
- EC2 - Service that provides secure and resizable virtual servers on AWS.
Steps:
What we are going to do is mount an EFS to a lambda function. Both these services can be in the same private subnet. Seperately, we are going to mount the same filesystem on an EC2 instance on a public subnet so that we can install our required packages. This requires public access as we need to SSH into our EC2 instance, and also so that we can download and install python packages. We also need to ensure that the Python version we use to install the packages is the same as the version running on Lambda.
Creating an IAM role
IAM>Role>Create Roleto create a new role.- In
Trusted entity typeselectAWS service. - In
Use caseselectLambda. - Next, you have to add permissions by choosing one or more policies to attach to your role. Attach the following :
AmazonElasticFileSystemClientFullAccessAWSLambdaExecuteAWSLambdaVPCAccessExecutionRole
- Then you can name the role, review and create it.
Creating a VPC with one private and one public subnet
VPC>Your VPCs>Create VPCto launch the VPC wizard.- In
Resources to create, click onVPC and more. This will allow us to create multiple resources we need in one step, such as subnets, security groups, route tables and internet gateways. - You can give the VPC a name, for auto generating all the other resource names.
- Create a VPC with 2 or more AZ’s for higher availability. For this example, 1 will suffice.
- this automatically creates one public and one private subnet (if you are using 2 AZ’s, this will create two public and private subnets, and so on)
- this also creates a default security group for the VPC, which applies on all the subnets in it.
Creating a Security Group
VPC>Security Groupsto view the security groups present.- You need two security groups, one for resources in your public subnets, and another for resources in your private subnet. Let us call them
sg-privateandsg-public. - A security group may already have been made for your new VPC. You can either :
- edit the one already there, and create a new security group
- make two new security groups
- Go to
VPC>Security Groups>Create security groupto create a new security group. Ensure you select the same VPC you created above. Create them with the following configurations. sg-publicwill be the security group for the EC2 instance you will use to install the packages on the public subnet. So:- for inbound rules:
sgr-xx...xx,IPv4,SSH,TCP,22,0.0.0.0/0(to allow us to SSH into the EC2 instance)
- for outbound rules:
sgr-0d859b39b65d36b24,IPv4,All traffic,All,All,0.0.0.0/0(to allow us to download packages, as well as mount the EFS)
- for inbound rules:
sg-privatewill be the security group for the Lambda and EFS resources you will use on the private subnet. So:- for inbound rules:
sgr-xx...xx,–,NFS,TCP,2049,sg-private(to allow the Lambda in the same security group to mount the EFS)sgr-xx...xx,–,NFS,TCP,2049,sg-public(to allow the EC2 in the other security group to mount the EFS)
- for outbound rules:
sgr-xx...xx,–,NFS,TCP,2049,sg-private(to allow the Lambda in the same security group to mount the EFS)
- for inbound rules:
Create an Elastic File System
Amazon EFS>File systemsto click onCreate file system.- Click on the
Customizeoption in the popup that shows up, to get more configuration options. - On Step 1,
File system settings, you can choose the default settings. If you have been following along, in theAvailability and durabilitysection chooseOne Zoneand the correct AZ. - On Step 2,
Network access, choose the correct VPC, subnet, andsg-privatesecurity group. - Click through Step 3 and 4 to create the file system.
- On the created filesystem, open the
Access pointstab. - Create an access point with the following example config:
- Root directory path -
/packages - User ID -
1000 - Group ID -
1000 - Owner user ID -
1000 - Owner group ID -
1000 - POSIX permissions to apply -
777
- Root directory path -
Creating a Lambda function
- Go to
Lambda>Functions>Create function. Enter the function name and the runtime you want. - Click on
Change default execution role>Use an existing roleand select the role you created above. - In
Advanced settings, click onEnable VPC. - Select your VPC, private subnet and
sg-privateas the security group. - Click on
Create functionand wait for the function to get created. - In the
Configurationtab, click onFilesystem. Select the filesystem and access point you had created earlier, then set the local mount path as/mnt/packages. - Now, the lambda should be connected to EFS. We are going to install packages in the
/mnt/packageslocation. To allow this, we can set an environment variable in Lambda by going toConfiguration>Environment variablesand creating a variable with Key =PYTHONPATHand Value =/mnt/packages. - In the function
Codetab, you can run this code to get the Python version. Note the version down for later use when installing the packages.1 2
import sys print (sys.version) # in my case, 3.9.11
Creating an EC2 instance
- Go to
EC2>Instances>Launch an instance. Select your chosen instance options. - If you haven’t created a key pair, create one. I create one by the name
efs-kp.pem. - Click to edit the network settings. Select your VPC, private subnet and
sg-publicas the security group. Make sureAuto assign public IPis enabled. - Click to create the instance.
Installing the packages
- Open the instance dashboard. Click on
Connect to instance. Follow the instructions given in theSSH clienttab to SSH into the instance. - Update the version of Python to the version in Lambda using the following steps:
- Update your system with
sudo yum update -y - Download the dependencies to build the package:
1 2
sudo yum groupinstall "Development Tools" -y sudo yum install wget openssl-devel bzip2-devel libffi-devel
- Download the required Python version 3.9.11:
1
sudo curl https://www.python.org/ftp/python/3.9.11/Python-3.9.11.tgz -O
- Extract the Python package:
tar -xvf Python-3.9.11.tgz - Change into the Python directory:
cd Python-3.9.11 - Run the configuration script and run the build process:
1 2
sudo ./configure --enable-optimizations sudo make install
- Verify the installation after it’s finished :
python3 -V
- Update your system with
- Once you enter the root directory, create a virtual environment with
python3 -m venv venv - Activate the virtual environment with
source venv/bin/activate - Verify the python version with :
python -V - Return to the root directory :
cd .. - Create a new directory to mount into :
mkdir efs - Go to the filesystem your created. Click on the
Attachbutton. Copy the NFS command from the popup that opens up. Run this command in the terminal.1
sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport fs-080005337xxxxxxxx.efs.us-east-1.amazonaws.com:/ efs
- Your EFS filesystem is now mounted. Now (with the virtual env enabled) install the required packages in the
efs/packages/directory with1
pip install --target=efs/packages/ pandas numpy
Verifying installation on Lambda
- Try running the following code on Lambda.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
import json import sys import numpy as np import pandas as pd print (sys.version) print (np.__version__) print (pd.__version__) def lambda_handler(event, context): # TODO implement return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') }
- This should print the versions of numpy and pandas respectively.
This post is licensed under CC BY 4.0 by the author.