Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[aws-ecr-assets] DockerImageAsset: Specify image tag #2663

Closed
nason opened this issue May 29, 2019 · 20 comments
Closed

[aws-ecr-assets] DockerImageAsset: Specify image tag #2663

nason opened this issue May 29, 2019 · 20 comments
Labels
@aws-cdk/assets Related to the @aws-cdk/assets package @aws-cdk/aws-ecr-assets Related to AWS CDK Docker Image Assets @aws-cdk/aws-ecs Related to Amazon Elastic Container effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p1

Comments

@nason
Copy link
Contributor

nason commented May 29, 2019

We are using a DockerImageAsset with an ECS ContainerDefinition, and would like to build, tag, and deploy an image from a build-specific tag (ie not latest).

I see that #2334 made deploy-time context hashes from the image available recently. Is there a way to accomplish this with these? I'm getting stuck trying, and can't seem to specify an image sha in the container definition, only a tag.

Would it make sense to tag+push DockerImageAsset with these hashes and/or user provided tags? https://github.com/awslabs/aws-cdk/blob/master/packages/aws-cdk/lib/docker.ts#L64

I'd be happy to open a PR if this is a welcome feature! Also, thank you for this great tooling, its been a pleasure to work with on my projects recently 💯

@nason nason added the feature-request A feature should be added or improved. label May 29, 2019
@jeshan
Copy link

jeshan commented Aug 29, 2019

I'd like this too. I saw the imageUri property on DockerImageAsset which suggested that it is settable, but apparently the setter doesn't work; only getter works (not from Python anyway).

export class DockerImageAsset extends cdk.Construct implements assets.IAsset {
/**
* The full URI of the image (including a tag). Use this reference to pull
* the asset.
*/
public imageUri: string;

@SomayaB SomayaB added the @aws-cdk/aws-ecs Related to Amazon Elastic Container label Oct 15, 2019
@SomayaB SomayaB added the needs-triage This issue or PR still needs to be triaged. label Oct 15, 2019
@NGL321 NGL321 removed the needs-triage This issue or PR still needs to be triaged. label Oct 16, 2019
@dandu1008
Copy link

Any Updates on this request..?

@MrArnoldPalmer MrArnoldPalmer added the effort/medium Medium work item – several days of effort label May 4, 2020
@SomayaB SomayaB assigned MrArnoldPalmer and unassigned SoManyHs and piradeepk Oct 21, 2020
@sdkitono
Copy link

+1

@luxaritas
Copy link
Contributor

Additional point: without lifecycle policies (#6692), and since specifying a repository name is now deprecated in lieu of using a cdk-wide repository, there is currently no way to tell my images apart whatsoever - all I see are commit hashes. I have no viable way of cleaning up unused resources.

@SoManyHs SoManyHs added p1 and removed p2 labels Jan 7, 2021
@SoManyHs SoManyHs added the @aws-cdk/aws-ecr-assets Related to AWS CDK Docker Image Assets label Feb 10, 2021
@SoManyHs SoManyHs changed the title DockerImageAsset: Specify image tag [aws-ecr-assetsDockerImageAsset: Specify image tag Feb 17, 2021
@SoManyHs SoManyHs changed the title [aws-ecr-assetsDockerImageAsset: Specify image tag [aws-ecr-assets] DockerImageAsset: Specify image tag Feb 17, 2021
@github-actions github-actions bot added the @aws-cdk/assets Related to the @aws-cdk/assets package label Feb 17, 2021
@eladb eladb removed their assignment Feb 25, 2021
@SoManyHs SoManyHs self-assigned this Mar 3, 2021
@eladb
Copy link
Contributor

eladb commented Mar 3, 2021

I don't think we will be able to support specifying an image tag for docker assets because all the assets go to the same ECR repository (created by the bootstrap stack) and tagged according to their asset hash.

I believe the solution to this use case is to use something like "ecr-deployment" (see the proposal in #12597) which will allow you to "deploy" a docker image to a user-defined ECR repository and then you can control everything.

@nason can you confirm that #12597 will address your use case and then we can close this as a duplicate?

@SoManyHs SoManyHs removed their assignment Mar 3, 2021
@rix0rrr
Copy link
Contributor

rix0rrr commented Mar 15, 2021

It might be a little late for this thread, but I'd like to collect some use cases in here for this feature.

We are using a DockerImageAsset with an ECS ContainerDefinition, and would like to build, tag, and deploy an image from a build-specific tag (ie not latest).

Not exactly sure what this means. If you say, "build [...] an image from a build-specific tag", is putting the following:

FROM <image>:<tag>

In your Dockerfile not good enough? If not, why not?


If your request is actually about controlling the tags that Docker images get pushed TO: it's true, we don't allow that.

The same way we push ZIPs under generated names to a single S3 bucket (the asset bucket from the bootstrap stack), we do the same for ECR images. The asset mechanism gets files from "your disk" into "a running CDK application", nothing more and nothing less. How we get them there is at our discretion and is an implementation detail you shouldn't rely on. As such, you also shouldn't rely on repositories where images get pushed, nor on the tags they will get them there.

If want to push images to a well-known location for consumption by something else other than your CDK app (again: what is the use case?), the solution would be to set up a CodePipeline that builds and pushes a Docker image to a dedicated ECR repository you control the lifecycle of.

If not that, then an EcrDeployment construct as proposed in #12597 would also do it (although as of this writing that construct hasn't been written yet).


there is currently no way to tell my images apart whatsoever - all I see are commit hashes. I have no viable way of cleaning up unused resources.

That is a fair point, and an unfortunate downside of the method we've chosen.

Our plan for addressing this was going to be a Garbage Collector which would clean unused files and images from the bootstrap resources. Please upvote issue #11071 to help us prioritize this work among everything else that people are asking for.

@rareelement
Copy link

AWS CLI allows specifying more than one image tag, see https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-retag.html. I could add version tag to a Docker image uploaded by CDK to aws-cdk/assets repository.

Is it possible to implement support for optional image tags in DockerImageAsset that will supplement asset hash based auto-generated tag? These tags should be sufficient to enable image cleanup and management.

@eladb
Copy link
Contributor

eladb commented Jul 22, 2021

@rareelement please take a look at cdk-ecr-deployment. It should address your use case.

I am also closing this as a duplicate of #12597

@eladb eladb closed this as completed Jul 22, 2021
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

@rareelement
Copy link

@eladb Is cdk-ecr-deployment officially supported by AWS?

Anyways, it is not going to help with my use case of keeping aws-cdk/assets repository slim, unless the expectation is that aws-cdk/assets repository will be regularly completely cleaned (which is not realistic in most companies with multiple teams/services). This, now closed issue, is different from #12597.

If ECR supports multiple image tags, I don't see why CDK cannot support those as well and why AWS users have to incur additional costs by duplicating docker images.

@eladb
Copy link
Contributor

eladb commented Jul 22, 2021

@rareelement thanks for the additional context.

I'll reopen the issue and we'll discuss solutions.

@eladb eladb reopened this Jul 22, 2021
@phuwin
Copy link

phuwin commented Aug 10, 2021

We got
Resource handler returned message: "Invalid request provided: Create TaskDefinition: Container.image should be 255 characters or less
Part of this is the really long tag that DockerImageAsset generates:
image
How do we solve this?

@eladb
Copy link
Contributor

eladb commented Aug 10, 2021

@phuwin95 wrote:

We got

Resource handler returned message: "Invalid request provided: Create TaskDefinition: Container.image should be 255 characters or less

Part of this is the really long tag that DockerImageAsset generates:

image

How do we solve this?

Seems like a bug. Care to raise a separate issue for it?

@airmonitor
Copy link

Hey.

I'm using image.asset_hash if this help you to not use only latest.

Sample python code below:



# -*- coding: utf-8 -*-
"""The core AWS CloudFormation stack which creates main AWS resources which are
crucial resources."""

from os import path

import aws_cdk.aws_ecr as ecr
import cdk_ecr_deployment as ecrdeploy
from aws_cdk import core as cdk
from aws_cdk.aws_ecr_assets import DockerImageAsset


class CoreStack(cdk.Stack):
    """Create EC2 autoscaling and security group."""

    # pylint: disable=W0613
    def __init__(self, scope: cdk.Construct, construct_id: str, env, props, **kwargs) -> None:
        super().__init__(scope, construct_id, env=env, **kwargs)

        repository = ecr.Repository(
            self,
            id="cvc_container_repository",
            repository_name=f'{props["stage"]}-{props["project"]}',
            removal_policy=cdk.RemovalPolicy.DESTROY,
            image_scan_on_push=True,
            lifecycle_rules=[ecr.LifecycleRule(max_image_count=10)],
        )
        image = DockerImageAsset(
            self, id="cvc_qa_test_docker_image", directory=path.join("sonyhive_cvc_qa_automation/core_stacks", "docker")
        )

        ecrdeploy.ECRDeployment(
            self,
            id="deploy_docker_image_latest",
            src=ecrdeploy.DockerImageName(image.image_uri),
            dest=ecrdeploy.DockerImageName(f"{repository.repository_uri}:latest"),
        )

        ecrdeploy.ECRDeployment(
            self,
            id="deploy_docker_image_asset_hash",
            src=ecrdeploy.DockerImageName(image.image_uri),
            dest=ecrdeploy.DockerImageName(f"{repository.repository_uri}:{image.asset_hash}"),
        )

@neovasili
Copy link
Contributor

neovasili commented Jun 27, 2022

@eladb I found that in CDK v1 you could use image.image_uri to get the DockerImageAsset tag splitting its value since is a string containing the token reference inside:

ACCOUNT_ID.dkr.ecr.REGION.${Token[AWS.URLSuffix.X]}/aws-cdk/assets:ASSET_HASH

so I was able to use something like this:

codebuild_project = codebuild.Project(
    self,
    f"{self.service}-project",
    project_name=f"{self.service}-project",
    build_spec=BuidlSpecHelper.get_buildspec(
        file_location="buildspec.yml",
    ),
    environment=codebuild.BuildEnvironment(
        build_image=codebuild.LinuxBuildImage.from_ecr_repository(image.repository, image.image_uri.split(":")[-1]),
        compute_type=codebuild.ComputeType.SMALL,
    ),
    logging=codebuild.LoggingOptions(
        cloud_watch=codebuild.CloudWatchLoggingOptions(
            log_group=logs.LogGroup(
                self,
                f"{self.service}-codebuild-log-group",
                log_group_name=f"/aws/codebuild/{self.service}",
                retention=logs.RetentionDays.TWO_WEEKS,
            ),
        )
    ),
)

Unfortunately, this no longer work in CDK v2, since image.image_uri is not producing the same output:

${Token[TOKEN.X]}

That also leads into a similar issue to the one @phuwin95 mentioned because the split is not produced, so the image reference is wrong:

...
  "testservicetestserviceprojectXXXXX": {
   "Type": "AWS::CodeBuild::Project",
   "Properties": {
    "Artifacts": {
     "Type": "NO_ARTIFACTS"
    },
    "Environment": {
     "ComputeType": "BUILD_GENERAL1_SMALL",
     "Image": {
      "Fn::Join": [
       "",
       [
        "ACCOUNT_ID.dkr.ecr.us-west-2.",
        {
         "Ref": "AWS::URLSuffix"
        },
        "/cdk-CDK_ID-container-assets-ACCOUNT_ID-REGION:",
        {
         "Fn::Sub": "ACCOUNT_ID.dkr.ecr.REGION.${AWS::URLSuffix}/cdk-CDK_ID-container-assets-ACCOUNT_ID-REGION:ASSET_HASH"
        }
       ]
      ]
     },
...

and need an unexpected refactor in the code when migrating using what you suggested here or something like this:

codebuild_project = codebuild.Project(
    self,
    f"{self.service}-project",
    project_name=f"{self.service}-project",
    build_spec=BuidlSpecHelper.get_buildspec(
        file_location="buildspec.yml",
    ),
    environment=codebuild.BuildEnvironment(
        build_image=codebuild.LinuxBuildImage.from_ecr_repository(image.repository, image.asset_hash),
        compute_type=codebuild.ComputeType.SMALL,
    ),
    logging=codebuild.LoggingOptions(
        cloud_watch=codebuild.CloudWatchLoggingOptions(
            log_group=logs.LogGroup(
                self,
                f"{self.service}-codebuild-log-group",
                log_group_name=f"/aws/codebuild/{self.service}",
                retention=logs.RetentionDays.TWO_WEEKS,
            ),
        )
    ),
)

I already find the issue migrating the stack and have a solution, but not sure if that output was expected or is part of a bug; in any case it maybe should be documented or reported somewhere else, what do you think @eladb?

@MrArnoldPalmer
Copy link
Contributor

So it looks like this has spread out to a couple of different issues. One being managing your own ECR repository which is enabled via #12597 and the ecr-deployment module. The other being keeping the cdk assets ECR repository clean which is being tracked as "garbage collection" here #6692

Closing in favor of those in order to consolidate discussion and tracking.

@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

@DerkSchooltink
Copy link
Contributor

I still think there's a lot of merit in the original proposal. CDK assets are quite powerful, it helped us get rid of our Docker building setup that ran independently of the CDK build. That required a lot of maintenance regarding cleaning up images, setting permissions correctly and extra overhead maintaining the build pipeline for building Docker images.

With that in mind, I would love to keep using CDK assets, specifically Docker assets! It takes care of permissions easily, our pipeline has gotten simpler, and cleaning up images after they are no longer in use is taken care of using this nifty toolkit cleaner.

However, it is really hard to find the assets you're looking for when you need to inspect something. For example, fixing vulnerabilities is a pain in the ass when all I have is a random SHA256 hash from ECR to go on. I have to scour through my build logs to see where it was being built. I sometimes use Docker scout to inspect the image, but that still doesn't give me a reference to the actual time and config that was used when creating the image.

Some use-cases I can imagine will benefit a lot by being able to tag Docker image assets yourself:

  1. Fix vulnerabilities more easily
  2. Tracing a bug in a certain version is a lot easier when you have the corresponding Docker image to reproduce it at runtime
  3. Transparency across multiple repositories (which all will be pushed to the CDK image asset ECR repository) to figure out which image belongs to which component/application you're building

These are all indeed fixable by maintaining your own Docker repository, and using something like the ECR deployment module, but like I said there is a lot of value in keeping those images as part of the CDK assets repository.

Therefor, I would like to propose to reopen this issue and see if we can implement it anyway.

@DerkSchooltink
Copy link
Contributor

@MrArnoldPalmer could you consider my comments above? :) I don't think my post has a lot of visibility because the issue is closed.

@quadrupole
Copy link

I think this is now possible with https://docs.aws.amazon.com/cdk/api/v2/docs/app-staging-synthesizer-alpha-readme.html ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/assets Related to the @aws-cdk/assets package @aws-cdk/aws-ecr-assets Related to AWS CDK Docker Image Assets @aws-cdk/aws-ecs Related to Amazon Elastic Container effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p1
Projects
None yet
Development

No branches or pull requests