aws-cdk icon indicating copy to clipboard operation
aws-cdk copied to clipboard

aws-s3-deployments, but for ECR: copy asset Docker image to well-defined repository

Open farzad-xgen opened this issue 5 years ago • 11 comments

We are using DockerImageAsset to push a dummy image to the ECR and to use it to create an ECS service. To do that, we use repositoryName to address the target repo. It seems that there's a hint in https://github.com/aws/aws-cdk/blob/4baf26e82503ec256d2ac792f87c4a1975375104/packages/%40aws-cdk/core/lib/assets.ts#L155 indicating that the use of repositoryName is deprecated. My question is what is the safe alternative way to push an image to an ECR repository?

farzad-xgen avatar Jun 16 '20 01:06 farzad-xgen

Related to #8483

rrrix avatar Jun 16 '20 01:06 rrrix

Please describe your use case in more detail. Is it the following?

You want to create an ECR repository and fill it with a dummy image, so that you can immediately start an ECS service off of it. After that has happened, you will use a completely different mechanism, for example a CodePipeline, to push new images into that ECR repository which will automatically trigger an update of your ECS service?

(Using cdk deploy as a means to create and fill a target ECR repository was never a use case we were supporting)

rix0rrr avatar Jun 16 '20 09:06 rix0rrr

Yes, this is exactly my use case. And I can’t set the desired tasks to 0 at any point because it will break my service. So I need to create the ECS service with a dummy task to provide the minimum health check functionality to make it stable, and then I create the Codepipeline and it automatically puts the right image in the ECR and updates the service, and from that point forward we continue just like that, merging the updates to our Github repo to update the image.

farzad-xgen avatar Jun 16 '20 09:06 farzad-xgen

That's an interesting use case, but not really what the asset system is intended for. In that system, we manage the repositories and the images, and you're not supposed to care where they live or how they get there.

The intended pattern is very similar to what aws-s3-deployments does, but for Docker Images instead of files.

This is a Custom Resource that takes data from the "you're not supposed to care about it" asset location, and copies it into a location that you do care about and explicitly provision.

I'd recommend you write something similar for ECR.

Leaving this open as a feature request, and I can see the use for it in core CDK, but not likely something we'll invest in.

rix0rrr avatar Jun 17 '20 13:06 rix0rrr

For context, this is a problem we're facing as well. If you want to create a CodePipeline which builds an image and deploys an ECS service, you don't have a ton of options if you don't have a pre-built image handy (i.e. you're deploying infrastructure from scratch into a new AWS account). We're using YAML files instead of the CDK, but I wanted to mention it regardless.

dentonmwood avatar Sep 08 '20 14:09 dentonmwood

We are looking for something very similar so I found myself digging through the code.

I don't think this is particular complicated or far away to achieve - either as part of cdk or a separate/custom package. However two of the recent (and older) design decisions in cdk-assets make this impossibly hard at the moment:

  • cdk-assets is perfectly happy to build and push a well-named docker image if referenced in assets.json

  • It cannot however be forced to rebuild if the name already exists

  • There also isn't an easy way to create multiple tags, but that's still achievable by duplicating the config

  • There's no interface on the new stack synthesizer anymore to add a DockerImageAsset with a custom repositoryName

  • Also one would have to know that sourceHash is implemented as image tag


I'm not quite convinced that pulling, re-tagging and pushing an image inside of a custom resource is the better approach, but remain open to that option.

I'm also wondering why the cloud-assembly-schema for the assets manifests is defined so openly, when on cdk code end it's than locked then again.


As far as use case go, it is very common in our company to publish images under well-known and human-friendly addresses that can be used within the business. Essentially the definition of what Docker Hub is but privately and internally. Would be great if I could deploy all of this using only cdk (or at least as a wrapper around docker) and not having to write the docker build steps in my ci/cd pipeline language.

mrgrain avatar Sep 15 '20 17:09 mrgrain

Just ran in to same issue.

okonon avatar Dec 21 '20 23:12 okonon

Hi @farzad-xgen @rrrix , I wrote a cdk-ecr-deployment https://github.com/wchaws/cdk-ecr-deployment. See if this can help you. With this you can do it in this way

const image = new DockerImageAsset(this, 'CDKDockerImage', {
  directory: path.join(__dirname, 'docker'),
});

new ecrDeploy.ECRDeployment(this, 'DeployDockerImage', {
  src: new ecrDeploy.DockerImageName(image.imageUri),
  dest: new ecrDeploy.DockerImageName(`${cdk.Aws.ACCOUNT_ID}.dkr.ecr.us-west-2.amazonaws.com/test:nginx`),
});

wchaws avatar Apr 18 '21 14:04 wchaws

This issue has not received any attention in 1 year. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

github-actions[bot] avatar Jun 03 '22 16:06 github-actions[bot]

Keep open please!

mrgrain avatar Jun 06 '22 04:06 mrgrain

I would like to use DockerImageAsset to define a base image that is used in multiple projects. Ideally there would be a specific tag we could give the DockerImageAsset construct that could be referenced in the other projects. This seems to be very similar to this discussion.

Currently I export the image URL and then pull the exported value with SDK calls in the other CDK apps.

rupe120 avatar May 15 '23 13:05 rupe120