Have you ever wanted Lambda functions to be able to save and load files locally without needing to transfer data between an S3 bucket? This article is for you.
By using AWS EFS
we can attach a persistent filesystem to your Lambda function!
CDK init & deploy
I won’t cover setting up CDK and bootstrapping the environment. You can find that information here.
Once you have set up CDK, we need to set up the project:
mkdir cdk_docker_lambda && cd cdk_docker_lambda
cdk init --language python
source .venv/bin/activate
-
pip install -r requirements.txt && pip install -r requirements-dev.txt
Now deploy empty stack to AWS:
cdk deploy
Stack design
Our CDK stack is going to deploy an EFS
filesystem, a Lambda function, and an access point which will allow us to attach the filesystem to the function.
cdk_lambda_efs/cdk_lambda_efs_stack.py
from aws_cdk import Stack from aws_cdk import aws_ec2 as ec2 from aws_cdk import aws_efs as efs from aws_cdk import aws_lambda as _lambda from constructs import Construct from aws_cdk import RemovalPolicy class CdkLambdaEfsStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # I like to define all my pieces in __init__ self.vpc = None self.access_point = None self.lambda_func = None self.build_infrastructure() def build_infrastructure(self): self.build_vpc() self.build_filesystem() self.build_lambda_func() def build_vpc(self): # Build the VPC where both EFS and Lambda will sit self.vpc = ec2.Vpc(self, "VPC") def build_filesystem(self): file_system = efs.FileSystem( scope=self, id="Efs", vpc=self.vpc, file_system_name="ExampleLambdaAttachedEFS", # Makes sure to delete EFS when stack goes down removal_policy=RemovalPolicy.DESTROY, ) # create a new access point from the filesystem self.access_point = file_system.add_access_point( "AccessPoint", # set /export/lambda as the root of the access point path="/export/lambda", # as /export/lambda does not exist in a new efs filesystem, the efs will create the directory with the following createAcl create_acl=efs.Acl( owner_uid="1001", owner_gid="1001", permissions="750" ), # enforce the POSIX identity so lambda function will access with this identity posix_user=efs.PosixUser(uid="1001", gid="1001"), ) def build_lambda_func(self): # I'm just using the normal CDK lambda function here. See my other articles for additional building methods. _lambda.Function( self, "LambdaWithEFS", runtime=_lambda.Runtime.PYTHON_3_9, # lambda function file name.handler function handler="lambda_EFS.handler", # Points to directory of lambda function code=_lambda.Code.from_asset("cdk_lambda_efs/lambda_EFS"), # Lambda needs to be in same VPC as EFS vpc=self.vpc, filesystem=_lambda.FileSystem.from_efs_access_point( ap=self.access_point, mount_path="/mnt/filesystem" ) if self.access_point else None, )
Lambda function
I will deploy a lambda function without any additional dependencies. If you need dependencies, you will need to use different CDK
constructs to do it. Here is an example of using aws_lambda_python_alpha and here is an example of building using Docker.
This lambda function opens a file on the EFS
filesystem, writes a string to it, then opens it again and returns the result.
cdk_lambda_efs/lambda_EFS/lambda_EFS.py
from pathlib import Path def handler(event, context): # Writing to a file on the EFS filesystem path = Path("/mnt/filesystem/test.txt") with path.open("w") as f: f.write("Test123") # Now open the file, read the text, return with path.open("r") as f: text = f.read() return f"Hello Lambda! {text}"
Test the lambda function with attached filesystem
Navigate to the Lambda console on AWS. First notice the filesystem has been successfully attached to your lambda function
Now go ahead and test it using any kind of event.
I hope this article has helped you to solve your problem of lambda not persisting data. EFS is an easy to use and versatile solution to memory problems.
Make sure to cdk destroy
when you're done to avoid any charges.
Top comments (0)