Skip to content

(ecr): Code.from_ecr_image tag_or_digest using CFNParameter #20213

@bhsp

Description

@bhsp

Describe the bug

When creating a Lambda utilizing code from ECR, the tag_or_digest works great if the value is literally the tag or sha256: digest. This falls down when providing a CFNParameter as it's value but only when the user input is a digest, works fine with a tag still.

For example. tag_or_digest='sha256:a5ecdfb1bd870e9aa68d3921768cd2d4866be34bac3e41503f2c3c0b6db5a167' generates the following YML - which of course works and is use the @ correctly.

lambdafunction841552AF:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ImageUri:
          Fn::Join:
            - ""
            - - 111111111111.dkr.ecr..
              - Ref: AWS::URLSuffix
              - /test/test@sha256:a5ecdfb1bd870e9aa68d3921768cd2d4866be34bac3e41503f2c3c0b6db5a167

Using a tag, also works great! tag_or_digest='latest'

  lambdafunction841552AF:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ImageUri:
          Fn::Join:
            - ""
            - - 111111111111.dkr.ecr..
              - Ref: AWS::URLSuffix
              - /test/test:latest

If/when we use a CfnParameter and during deploy pass a sha256: the Intrinsic join uses a ":" instead of the "@".

Parameters:
  version:
    Type: String
    AllowedPattern: ^([a-zA-Z0-9_][a-zA-Z0-9_.-]{1,127}|sha256:[0-9a-f]{64})$
    ConstraintDescription: Must match pattern ^([a-zA-Z0-9_][a-zA-Z0-9_.-]{1,127}|sha256:[0-9a-f]{64})$
    Description: Image tag e.g., 'latest' or a digest beginning with sha256:, please verify the digest exists in the repository.
    MaxLength: 127
    MinLength: 1
    NoEcho: false

  lambdafunction841552AF:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ImageUri:
          Fn::Join:
            - ""
            - - 111111111111.dkr.ecr..
              - Ref: AWS::URLSuffix
              - "/test/test:"
              - Ref: version

Expected Behavior

URL is joined using an @ when a digest is provided through a CfnParameter

Current Behavior

The ECR URI is joined by a colon instead of an @ when a digest is provided.

Reproduction Steps

#!/usr/bin/env python3
from constructs import Construct
from aws_cdk import App, Environment, Stack, Duration, CfnParameter
from aws_cdk import (aws_lambda as lambda_, aws_ecr as ecr)


class LambdaStack(Stack):

    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        pattern = '^([a-zA-Z0-9_][a-zA-Z0-9_.-]{1,127}|sha256:[0-9a-f]{64})$'

        lambda_.Function(
            self,
            "lambda-function",
            function_name='lambda-ecr-image',
            runtime=lambda_.Runtime.FROM_IMAGE,
            architecture=lambda_.Architecture.X86_64,
            handler=lambda_.Handler.FROM_IMAGE,
            # Maximum is 15 minutes
            timeout=Duration.minutes(14),
            retry_attempts=1,
            code=lambda_.Code.from_ecr_image(
                repository=ecr.Repository.from_repository_arn(
                    self,
                    id="private-repo",
                    repository_arn="arn:aws:ecr::111111111111:repository/test/test"
                ),

                # Works with the digest as a value
                # Works with the tag as a value
                # Does not work with digest through CfnParameter
                tag_or_digest=CfnParameter(
                    self,
                    id="version",
                    description=f"Image tag e.g., 'latest' or a digest beginning with sha256:, "
                                f"please verify the digest exists in the repository.",
                    allowed_pattern=pattern,
                    constraint_description='Must match pattern ' + pattern,
                    max_length=127,
                    min_length=1,
                    no_echo=False,
                    type="String"
                ).value_as_string
            )
        )


env = Environment(account="111111111111", region='us-east-1')
app = App()

lambda_stack = LambdaStack(app, "lambda-stack", env=env)

app.synth()

Possible Solution

Intrinsic conditional join

Additional Information/Context

No response

CDK CLI Version

2.22.0 (build 1db4b16)

Framework Version

No response

Node.js Version

14.19.1

OS

Windows

Language

Python

Language Version

3.8

Other information

No response

Metadata

Metadata

Assignees

Labels

@aws-cdk/aws-ecrRelated to Amazon Elastic Container RegistrybugThis issue is a bug.closed-for-stalenessThis issue was automatically closed because it hadn't received any attention in a while.effort/smallSmall work item – less than a day of effortgood first issueRelated to contributions. See CONTRIBUTING.mdp2response-requestedWaiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions