SAM deploy does not deploy Layer dependencies to S3

1

In my SAM template I've got 2 Lambda functions that share dependencies via a Layer. Here's my directory structure. As you can see, individual functions have no requirements.txt file, but it's shared within deps/ directory:

├── deps
│   └── requirements.txt
├── src
│   ├── function1
│   │       └── getArticlesById.py 
│   └── function2
│           └── getArticlesById.py
└── my-sam-template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Sample SAM Template for testing API Gateway, Lambda, DynamoDB integration

Globals:
  Api:
    OpenApiVersion: 3.0.1
  Function:
    Timeout: 5

Parameters:
    Environment:
      Type: String
      Default: dev

Resources:
  DepsLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      Description: !Sub Dependencies for ${AWS::StackId}-${Environment}
      ContentUri: deps/
      CompatibleRuntimes:
        - python3.9
      RetentionPolicy: Retain
    Metadata:
      BuildMethod: python3.9

  GetRecommendationsByIdFunctionDynamo:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/function1
      Handler: getArticlesById.lambda_handler
      Runtime: python3.9
      MemorySize: 3008
      Tracing: Active
      Policies:
        - AWSLambdaVPCAccessExecutionRole
        - DynamoDBReadPolicy:
            TableName:
              !Ref MyDatabase
      Layers:
        - !Ref DepsLayer
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /getArticlesByIdDynamo
            Method: get
            RestApiId: !Ref API
      Environment:
        Variables:
          STAGE: !Sub ${Environment}

  GetRecommendationsByIdFunctionS3:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/function2
      Handler: getArticlesById.lambda_handler
      Runtime: python3.9
      MemorySize: 3008
      Tracing: Active
      Policies:
        - AWSLambdaVPCAccessExecutionRole
        - S3ReadPolicy:
            BucketName:
              !Ref MyBucket
      Layers:
        - !Ref DepsLayer
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /getArticlesByIdS3
            Method: get
            RestApiId: !Ref API
      Environment:
        Variables:
          STAGE: !Sub ${Environment}

sam build --template-file my-sam-template.yml fetches all dependencies and puts them into .aws-sam/build/DepsLayer/python:

.aws-sam
├── build
│   ├── DepsLayer
│   │   └── python
│   ├── GetRecommendationsByIdFunctionDynamo
│   │   └── getArticlesById.py
│   ├── GetRecommendationsByIdFunctionS3
│   │   └── getArticlesById.py
│   └── template.yaml
└── build.toml

However when I run sam deploy --template-file my-sam-template.yml, DepsLayer dependencies are not copied over to S3, and Lambda functions fail at runtime, since they can't find these dependencies.

$ aws --version
aws-cli/2.3.2 Python/3.9.7 Darwin/20.6.0 source/x86_64 prompt/off

$ sam --version
SAM CLI, version 1.36.0
maslick
asked a year ago211 views
1 Answer
1

It turns out sam has a bug. When I execute:

sam build
sam deploy

Everything works as expected. The Layer with Python dependencies is pushed to S3.

But when I use a yml with a non-standard name (other than template.yml or template.yaml):

sam build --template-file my-sam-template.yml
sam deploy --template-file my-sam-template.yml

then the Layer is generated locally (dependencies are fetched from Pypi), but are not pushed to S3.

maslick
answered 10 months ago
  • Nice find .. thanks a lot -- have been poundering my head on this for hours

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions