Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS SAM: Shared files across Lambda functions

I am working with AWS SAM (Serverless Application Model) to build Python 3.6 lambda code in an API Gateway setup. As such, I have a single template.yaml file that creates several Lambda functions. They are organized with the lambda functions each in their own sub-directory within the project. The lambda also share several common files which I keep in a shared folder.

project-home
 -lambda_a_dir
   -lambda_a.py
 -lambda_b_dir
   -lambda_b.py
 -shared_dir
   -shared.py

The problem is that while Pycharm can clearly see the shared.py, SAM cannot and refuses to recognize the shared files, with the following error: Unable to import module 'lambdaA': No module named 'shared' If I move a copy of the shared.py file into each lambda directory, both Pycharm and SAM are happy and I can build/deploy to AWS.
My question: how can I build the SAM template with the shared files living in the shared directory?
So far, I have tried:

  • Symbolic link and MacOS alias.
  • Various combinations of CodeUri alternatives
  • Local package with __init__ and setup.py. (I can't use a public package because the code is private and cannot not be put on a public repository.)

Here is my template file:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  lambdaA:
    Type: AWS::Serverless::Function 
    Properties:
      CodeUri: ./lambda_a_dir/
      Handler: lambda_a.lambda_handler
      Runtime: python3.6
  lambdaB:
    Type: AWS::Serverless::Function 
    Properties:
      CodeUri: ./lambda_b_dir/
      Handler: lambda_b.lambda_handler
      Runtime: python3.6
like image 316
Hephaestus Avatar asked Apr 08 '19 04:04

Hephaestus


People also ask

How do you share data between Lambda functions?

There is no in-built technique for sharing data between Lambda functions. Each function runs independently and there is no shared datastore. You will need to use an external datastore -- that is, something outside of Lambda that can persist the data.

Can AWS Lambda share code between functions?

Before lambda layers, developers used to either duplicate common code in every lambda function or create local npm packages and refer them in lambdas. Now with lambda layers, you can securely share code among your lambda functions in the same AWS account, cross-accounts or in public.

Can Lambda access resources across accounts?

AWS Lambda Permission Policies (aka resource-based policies) can allow functions to be invoked from AWS accounts other than the one it is running in.

Can I store file in Lambda function?

You can now mount EFS volumes in Lambda functions, which makes it simpler to share data across invocations. The file system grows and shrinks as you add or delete data, so you do not need to manage storage limits. The Lambda service mounts EFS file systems when the execution environment is prepared.

How to download AWS SAM file in AWS Lambda?

In the Lambda function window, choose Actions, and then select Export Function. 4. In the Export function window, choose Download AWS SAM file. 5. After the AWS SAM file is downloaded, return to the Export function window and choose Download deployment package to download the deployment package.

How do I migrate a lambda function to another AWS account?

Use the AWS SAM file and AWS CloudFormation to deploy and manage a new Lambda function in another AWS account or Region. For more information, see Deploying a Hello World application. Note: You can also migrate a Lambda function using the Lambda console or the AWS Command Line Interface (AWS CLI). 1.

What can I do with lambda functions on AWS EC2?

Or you can use a Lambda function to process files uploaded by a web application running on EC2. In this way, some use cases are much easier to implement with Lambda functions. For example:

What is the difference between lambda and Amazon EFS?

With Amazon EFS, your function code can access and modify shared resources safely and at high concurrency. Lambda uses your function's permissions to mount file systems.


2 Answers

Following the recommendation from @Dunedan I created a Layers object for each lambda function with the shared code, this effectively added those routines to the PythonPath for those functions. I also added the following to the API template definition with the new Layers properties:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  lambdaA:
    Type: AWS::Serverless::Function 
    Properties:
      CodeUri: ./lambda_a_dir/
      Handler: lambda_a.lambda_handler
      Runtime: python3.6
      Layers: 
        - arn:aws:lambda:us-west-1:012345678:layer:my_shared_zip:1
  lambdaB:
    Type: AWS::Serverless::Function 
    Properties:
      CodeUri: ./lambda_b_dir/
      Handler: lambda_b.lambda_handler
      Runtime: python3.6
      Layers: 
        - arn:aws:lambda:us-west-1:012345678:layer:my_shared_zip:1

Note that the code needs to be zipped before it is uploaded and needs to have a directory structure of the following, with the code inside a directory with the name of the language. In this case since I was using Python, the code needed to be in the python directory, and the python directory was then zipped:

my_shared_zip.zip
 -python
   -shared.py
   -other_shared.py
   -more_shared.py

Last note. While ideally, this shared-python directory should be deployed directly by the sam deploy command into the Layer objects, I have found that support for Layers in the AWS SAM CLI is still so new and so buggy, that at this point its not functional. Hopefully in the coming months it will be fixed. In the meantime, I need to manually install new versions of the shared-zip file myself. Sigh.

like image 87
Hephaestus Avatar answered Sep 27 '22 18:09

Hephaestus


The layers solution looks like a hack. I tried creating symlink to "shared" folder and it worked - the shared folder was successfully packed along with my lambda function.

cd lambda_a_dir
ln -s ../shared
like image 21
MrKsn Avatar answered Sep 27 '22 18:09

MrKsn