aws-sam-cli icon indicating copy to clipboard operation
aws-sam-cli copied to clipboard

Add mount option on sam local invoke/start-api

Open dacgray opened this issue 4 years ago • 10 comments

Describe your idea/feature/enhancement

Related to:

  • https://github.com/aws/aws-sam-cli/pull/1486/files
  • https://github.com/aws/aws-sam-cli/issues/1896
  • https://github.com/aws/aws-sam-cli/issues/1485

We use custom lambda container images. We run code in /var/task/ or mount from EFS and run in /mnt/*.

We can't emulate the /mnt mount with SAM, or make changes to code mounted in /var/task without a rebuild. This complicates dev - and makes dev impossible for builds with a big codebase.

The lambda runtime emulator works but is very limited.

Is there a workaround?

Proposal

It would be great to emulate the behaviour of docker --mount, with an extra function param:

From the example below:

sam local start-api --mount func=MyFunc,source="$(pwd)"/code,target=/mnt/shop

Additional Details

Example

- code/
-- foo.php
- bootstrap
- Dockerfile
- template.yaml

foo.php

<?php

echo json_encode(
    [
        'isBase64Encoded'=> false,
        'statusCode' => 200,
        'body' => '{"abc":123}'
    ]
);

bootstrap

#!/bin/bash

set -euo pipefail

while true
do

    HEADERS="$(mktemp)"

    EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
    REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)

    RESPONSE="$(mktemp)"

    export EVENT_DATA
    php /mnt/shop/foo.php >> "${RESPONSE}"

    curl -sS -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/${REQUEST_ID}/response" -d @${RESPONSE}

done

Dockerfile

FROM amazon/aws-lambda-provided:al2 as base

RUN yum install -y amazon-linux-extras
RUN amazon-linux-extras install epel -y

RUN rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm

RUN yum --enablerepo=remi-php74 install -y \
    php-cli-7.4.14

COPY bootstrap /var/runtime
RUN chmod 755 /var/runtime/bootstrap

CMD [ "handler.php" ]

template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:

  FileSystem:
    Type: AWS::EFS::FileSystem
    Properties: []

  MountTarget:
    Type: AWS::EFS::MountTarget
    Properties: []

  AccessPoint:
    Type: AWS::EFS::AccessPoint
    Properties: []

  MyFunc:
    Type: AWS::Serverless::Function
    Metadata:
      DockerContext: .
      Dockerfile: Dockerfile
    Properties:
      PackageType: Image
      FileSystemConfigs:
        - Arn: !GetAtt AccessPoint.Arn
          LocalMountPath: /mnt/shop
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /path
            Method: get

dacgray avatar Feb 05 '21 09:02 dacgray

For reference - this is how we get around this issue:

https://github.com/dacgray/sam-local-start-api-container-image-volume-mount

dacgray avatar Mar 09 '21 02:03 dacgray

Thanks for creating the feature request. I am tagging this for PM review and will update once we have discussed in team.

c2tarun avatar Jan 06 '22 18:01 c2tarun

@c2tarun Any updates on this? This is currently a pretty significant drawback when using custom runtime container images, since any changes made to function code need a full rebuild of the runtime container. When using the built-in runtimes SAM detects changes to the function code and rebuilds the containers automatically.

BenVosper avatar Mar 09 '22 14:03 BenVosper

/tmp would also be a good choice for a mounted volume.

Sparticuz avatar May 24 '22 13:05 Sparticuz

Agree with @BenVosper , this is a much needed feature.

dschiavu avatar Feb 25 '23 00:02 dschiavu

Any progress regarding this request?

Lucas1983 avatar Apr 06 '23 12:04 Lucas1983

This is needed when using DevContainers. Or else it doesn't work.

ffMathy avatar Apr 12 '23 13:04 ffMathy

Any update on this issue?

CC @hnnasit @mndeveci because you seem to be active. Looks like this issue might have gotten buried! Thanks for your help.

BenVosper avatar Oct 26 '23 10:10 BenVosper

@c2tarun is there an update on the PM review? Is there a chance this feature will be implemented? Would be really good to have the possibility to mount volumes to, for example, emulate local EFS mounting.

I am interested in this feature because in the project I am working on there is a need to share files between lambdas executed as a part of one StepFunctions environment. When executed on AWS we use EFS for that.

But when testing functionality locally - there is no way (at least I'm not aware of it) to have a dir shared between different lambdas started by sam local start-lambda

VladyslavXXI avatar Apr 11 '24 14:04 VladyslavXXI

For those running in devcontainer this solution worked for me

# get the host workspace path
host_workspace_path=$(docker inspect -f '{{ range .Mounts }}{{ if eq .Destination "/workspaces" }}{{ .Source }}{{ end }}{{ end }}' NAME_OR_ID)

# get the volume basedir
volume_basedir=$host_workspace_path/path-to-cdk-out

# now start sam local
sam local start-api --container-host host.docker.internal --docker-network NETWORK_NAME --docker-volume-basedir $volume_basedir 

wyliang avatar Aug 18 '24 22:08 wyliang