question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Skip Docker Lambda image builds when ImageUri is a valid ECR location

See original GitHub issue

Describe your idea/feature/enhancement

When configuring a lambda / serverless function of which the PackageType is Zip, SAM preemptively checks whether the resource CodeUri is a S3 location or not.

  # This function is already packaged and will to be ignored by SAM
  Function:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Zip
      CodeUri: s3://bucket/function.zip
      ...

If so, SAM will not attempt to build said lambda, and will show a warning to the user:

% sam build
The resource AWS::Serverless::Function 'Function' has specified S3 location for CodeUri. It will not be built and SAM CLI does not support invoking it locally.

I would expect SAM to do the same when attempting to build a PackageType: Image lambda function; checking whether or not the resource property ImageUri is a valid ECR URL before attempting to build said images locally, yet this feature is not supported by SAM today:

  # SAM should not attempt to build this Lambda
  Function:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      ImageUri: 123456789012.dkr.ecr.eu-west-1.amazonaws.com/function:latest

Instead, attempting to do so will most likely output the following exception (as the DockerContext resource metadata, required for building Docker Images using SAM, will most likely be unset, error traced here):

% sam build
Building image for Function function
Traceback (most recent call last):
  File "/usr/local/bin/sam", line 8, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/click/decorators.py", line 73, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/samcli/lib/telemetry/metric.py", line 153, in wrapped
    raise exception  # pylint: disable=raising-bad-type
  File "/usr/local/lib/python3.8/site-packages/samcli/lib/telemetry/metric.py", line 122, in wrapped
    return_value = func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/samcli/lib/utils/version_checker.py", line 42, in wrapped
    actual_result = func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/samcli/cli/main.py", line 90, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/samcli/commands/build/command.py", line 210, in cli
    do_cli(
  File "/usr/local/lib/python3.8/site-packages/samcli/commands/build/command.py", line 315, in do_cli
    artifacts = builder.build()
  File "/usr/local/lib/python3.8/site-packages/samcli/lib/build/app_builder.py", line 169, in build
    return build_strategy.build()
  File "/usr/local/lib/python3.8/site-packages/samcli/lib/build/build_strategy.py", line 41, in build
    result.update(self._build_functions(self._build_graph))
  File "/usr/local/lib/python3.8/site-packages/samcli/lib/build/build_strategy.py", line 52, in _build_functions
    function_build_results.update(self.build_single_function_definition(build_definition))
  File "/usr/local/lib/python3.8/site-packages/samcli/lib/build/build_strategy.py", line 118, in build_single_function_definition
    result = self._build_function(
  File "/usr/local/lib/python3.8/site-packages/samcli/lib/build/app_builder.py", line 500, in _build_function
    return self._build_lambda_image(function_name=function_name, metadata=metadata)  # type: ignore
  File "/usr/local/lib/python3.8/site-packages/samcli/lib/build/app_builder.py", line 322, in _build_lambda_image
    docker_context_dir = pathlib.Path(self._base_dir, docker_context).resolve()
  File "/usr/local/Cellar/python@3.8/3.8.10/Frameworks/Python.framework/Versions/3.8/lib/python3.8/pathlib.py", line 1042, in __new__
    self = cls._from_parts(args, init=False)
  File "/usr/local/Cellar/python@3.8/3.8.10/Frameworks/Python.framework/Versions/3.8/lib/python3.8/pathlib.py", line 683, in _from_parts
    drv, root, parts = self._parse_args(args)
  File "/usr/local/Cellar/python@3.8/3.8.10/Frameworks/Python.framework/Versions/3.8/lib/python3.8/pathlib.py", line 667, in _parse_args
    a = os.fspath(a)

As a result, it is currently not possible to deploy Docker-packed Lambda functions, without building the underlying image using SAM, which is, in my opinion, very limiting (e.g., inability to share ECR registries & images among an Organization, inability to use Docker images that require a specific build workflow -passing secrets using buildkit, environment specific args-…)

I did find a workaround, tricking SAM into skipping the build of a PackageType: Image Lambda, by setting the Code.S3Bucket property to an empty value, but I believe this to be very hack-y:

  # A working hack to skip the build of a Image Lambda function
  Function:
    Type: AWS::Lambda::Function
    Properties:
      PackageType: Image
      Code:
        S3Bucket: !Ref AWS::NoValue
        ImageUri: 123456789012.dkr.ecr.eu-west-1.amazonaws.com/function:latest

Proposal

  • Similarly to Zip packaged lambdas, check whether or not the ImageUri property of a AWS::Serverless::Function, or Code.ImageUri property of a AWS::Lambda::Function is a valid ECR URL before attempting to locally build said function. This could be done by reusing a function in the package.ecr_utils module here.
  • Show the user a proper warning when skipping the build of Docker lambda images.

Things to consider:

  1. Will this require any updates to the SAM Spec

Additional Details

A PR should follow soon with a workaround proposal.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:8
  • Comments:12 (4 by maintainers)

github_iconTop GitHub Comments

4reactions
ccmoosecommented, Sep 10, 2021

Hi,

I haven’t contributed to SAM before, but is there any way I can help move this along? I’m happy to help with any work that needs to be done.

This has been an issue at my company. We have lambda function container images that host machine learning models that can be used in multiple SAM stacks. When I bumped into this issue a couple of months ago I came here with the intent of opening a feature request but found this one had just been opened. I’ve been silently watching its progress but my impatience got the better of me. (That and my current workaround is a private fork with a very similar solution… not ideal.)

Anyway, my apologies if these things simply take time but do let me know if I can contribute/test/whatever to help.

Thanks, Mike “Moose” Moustakas

1reaction
matlikcommented, Apr 22, 2022

I’m not convinced this issue is fully resolved. In fact, the solution implemented in #2935 has introduced a regression for us.

This issue requests that the following isn’t built:

  Function:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      ImageUri: 123456789012.dkr.ecr.eu-west-1.amazonaws.com/function:latest

However, why would this preclude SAM from being able to invoke the lambda locally if the docker image already exists in the local image cache?

We are using SAM to integration test lambdas that are built from multiple projects. There is no build or deploy being performed, just a local test of the lambda functions and the step function state machine that wires it all together. But now we are getting the following error when things used to work fine: The resource AWS::Serverless::Function 'SetupFunction' has specified ECR registry image for ImageUri. It will not be built and SAM CLI does not support invoking it locally.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using container image support for AWS Lambda with AWS SAM
This new feature allows developers to package and deploy Lambda functions as container images of up to 10 GB in size. With this...
Read more >
Getting Started with Lambda Container Images
But first, let's get one thing out of the way: Lambda Container Images are not a way to run arbitrary Docker images within...
Read more >
Deploying sam template of a lambda with docker image
When using the ImageUri , can't have the Handler , Runtime , or Layers in the template. Remove these two from your template...
Read more >
AWS Lambda function using a container image - Cloud Tutorials
You can then upload the image to your container registry hosted on Amazon Elastic Container Registry (Amazon ECR) and deploy it to AWS...
Read more >
aws-sam-cli Changelog - pyup.io
chore: bump AWS Lambda Builders version by aws-sam-cli-bot in ... fix: Skip build of Docker image if ImageUri is a valid ECR URL...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found