aws / aws-sam-cli

CLI tool to build, test, debug, and deploy Serverless applications using AWS SAM
https://aws.amazon.com/serverless/sam/
Apache License 2.0
6.49k stars 1.17k forks source link

Feature request: Provide option to customize the generated docker image tag format / prefix #4078

Open weipingxia opened 2 years ago

weipingxia commented 2 years ago

Describe your idea/feature/enhancement

I wish SAM CLI would generate image tag in the format of <FuncLabel>-<DockerTag>-<RandomSuffix> rather than the current format - <FuncLabel>-<RandomInfix>-<DockerTag>. That way I can leverage the ECR image lifecycle to clean up obsolete images by specifying particular tagPrefixList. The current format doesn't apply tagPrefixList option.

E.g. Given the following metadata of the lambda function:

HelloWorldFunction:
  Type: 'AWS::Lambda::Function'
  Properties:
    ...
  Metadata:
    DockerContext: X/sam/test/hello_world
    DockerTag: python3.9-v1
    Dockerfile: Dockerfile

Generate docker tag as - helloworldfunction-python3.9-v1-ffffff111111

Proposal

Option-1: Change the default format to <FuncLabel>-<DockerTag>-<RandomSuffix> Option-2: Provide additional configuration to specify the tag prefix in metadata. E.g. DockerTagPrefix: xxx E.g.

HelloWorldFunction:
  Type: 'AWS::Lambda::Function'
  Properties:
    ...
  Metadata:
    DockerContext: X/sam/test/hello_world
    Dockerfile: Dockerfile
    DockerTagPrefix: myimageprefix

The above would generate docker tag as - myimageprefix-ffffff111111, disregard the DockerTag option. (DockerTag and DockerTagPrefix can be mutual-exclusive).

Additional Details

Discussion chain in Premium Support CASE 10376090461

qingchm commented 2 years ago

Thanks for providing your feedback on this specific behaviour! Marking this as a feature request

sriram-mv commented 2 years ago

This is a reasonable request, the important thing for us to consider is to enable this kind of behavior as a non breaking change so that users on previous versions who are upgrading don't see a change in their tags especially if they are relying on such behavior.

weipingxia commented 2 years ago

Then option-2 could help to keep the current behavior as default, and alter the tag only if the new config - DockerTagPrefix appears.

Actually I feel the current DockerTag does not exactly function as its name, since it's more like a suffix appended to another combined prefix. I would suggest to rename it as DockerTagSuffix to reflect its real behavior. Or if you still want the DockerTag config to behave the same, I would suggest to highlight this nuance in documenation to avoid confusion.

moelasmar commented 2 years ago

@weipingxia .. you are correct about the real meaning of DockerTag property, but we could not change this behaviour now. We can do as we suggested to accept new metadata property to add extra suffix to the image tag before pushing it to ECR. I will ask our PM to check this feature request, and to include it to our priorities.

dzienki commented 1 year ago

Any updates of that?

recog-arch commented 1 year ago

We are also interested in this feature. Any news?

madhavpujara-at commented 8 months ago

any updates on this feature

fethiozdol commented 1 month ago

I've been waiting for this SAM CLI feature and also this ECR feature request for a while now and I gave up on waiting.

Here is a workaround which performs retagging the docker image with a prepended tag prefix.

If the computed tag is <FuncLabel>-<RandomInfix>-<DockerTag> ; the new tag will be alpha-<FuncLabel>-<RandomInfix>-<DockerTag>.

However, this workaround works if you do not use sam deploy. In my case, I always use sam package in my build pipelines and then create CloudFormation changesets using the packaged template during deployments.

Also, I wanted to parse YAML files in a similar fashion to parsing JSON files using jq, I used yq but feel free to use another parser.

# sam package pushes the image to ECR and the packaged-template contains computed ImageUris
sam package --output-template-file packaged-template.yaml

# this is the tag prefix that we will prepend to the existing tag
# "alpha" if develop branch, "beta" if release branch and so on...
DOCKER_TAG_PREFIX="alpha"

# get the unique set of image uris found in the packaged template
CURRENT_IMAGE_URIS=$(yq '.Resources.* | select(.Type == "AWS::Serverless::Function") | .Properties.ImageUri' "packaged-template.yaml" | sort -u)

# there may be multiple image uris in the template, hence loop through each one
for CURRENT_IMAGE_URI in $CURRENT_IMAGE_URIS; do
  # extract the tag from the image uri
  CURRENT_TAG=$(echo $CURRENT_IMAGE_URI | cut -d':' -f2)
  # the rest is based on https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-retag.html
  MANIFEST=$(aws ecr batch-get-image --repository-name my-repo --image-ids imageTag="$CURRENT_TAG" --output text --query 'images[].imageManifest')
  aws ecr put-image --repository-name my-repo --image-tag "$DOCKER_TAG_PREFIX-$CURRENT_TAG" --image-manifest "$MANIFEST"
done