aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.71k stars 3.94k forks source link

(ecr-deployment): new aws-ecr-deployment module #12597

Closed jabrennem closed 1 year ago

jabrennem commented 3 years ago

🚀🚀🚀 The CDK team is picking up this feature request! Check below for more details!

We understand this is a highly desirable feature. Until we are able to integrate it into the CDK, we recommend considering the cdk-ecr-deployment library.

Let us know what you think! ❤️


Allow users to publish docker image assets to arbitrary ECR repositories. Similar to how s3-deployment works for S3:

const image = new DockerImageAsset(...);
const myRepo = new ecr.Repository(...);

new RepositoryDeployment(this, 'MyDeployment', {
  from: image,
  to: myRepo
});

I've been trying to identify if this is already supported. I am adding as a feature request. Let me know otherwise.

For this code snippet, is there a way to specify an image and tag that I want my local docker image to deploy to? I am posting the code in javascript since the example in the API reference is in JS, but my team uses python.

import { DockerImageAsset } from '@aws-cdk/aws-ecr-assets';

const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});

Use Case

I would like to use this feature to completely deploy my local image source code to ECR for me using an ECR repo that I have previously created in my CDK app or more importantly outside the app using an arn. The biggest problem is that the image cannot be completely abstracted into the assets repo because of auditing and semantic versioning.

Proposed Solution

Here is my proposed solution.

import { DockerImageAsset } from '@aws-cdk/aws-ecr-assets';

const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
  repo_name: 'company/my-image',
  tag: '1.2.0'
});

Other


This is a :rocket: Feature Request

eladb commented 3 years ago

Repurposed this issue as "ecr-deployment".

CDK assets (s3/ECR) are designed to be referenced from within CDK apps and not as a tool to publish docker images for external consumption. There are multiple places in the CDK and CDK pipelines which rely on the idea that all docker assets are published to the same repository.

I can see a use case for something like "s3-deployment" for docker images (which will replicate a docker image asset to a specific ECR repository), but this is currently not something we have. Happy to accept contributions.

jabrennem commented 3 years ago

I see. Thanks for the response. It does seem better to refocus this issue towards an "ecr-deployment" module rather than change how assets are handled.

MHacker9404 commented 3 years ago

I'm not sure that I agree with that. For example - I want a standardized image to support the lambda functions my company produces. It sounds to me like there would be a separate repository then for each lambda/image. How would we reference the image repository if CDK munges the name, because we can't set it?

SoManyHs commented 3 years ago

This is something we will not likely support. CDK assets (s3/ECR) are designed to be referenced from within CDK apps and not as a tool to publish docker images for external consumption. There are multiple places in the CDK and CDK pipelines which rely on the idea that all docker assets are published to the same repository.

@elad Did we decide that we will try to support this approach after all, given your https://github.com/aws/aws-cdk/issues/2663#issuecomment-789537323 in #2663?

eladb commented 3 years ago

@SoManyHs yes, it was a comment on the issue before it was repurposed. Edited.

eladb commented 3 years ago

People on this thread, make sure to +1 so that we are able to prioritize this.

wchaws commented 3 years ago

@eladb @jabrennem I wrote a cdk-ecr-deployment https://github.com/wchaws/cdk-ecr-deployment. See if this can help you. With this you can replicate your ECR to another location

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`),
});
TRANTANKHOA commented 3 years ago

@eladb @jabrennem I wrote a cdk-ecr-deployment https://github.com/wchaws/cdk-ecr-deployment. See if this can help you. With this you can replicate your ECR to another location

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`),
});

Hi, can you help approve this PR there? https://github.com/wchaws/cdk-ecr-deployment/pull/31

eladb commented 3 years ago

@wchaws https://github.com/aws/aws-cdk/pull/14488 calls out your awesome library as a way to deploy to ECR.

wchaws commented 3 years ago

@wchaws #14488 calls out your awesome library as a way to deploy to ECR.

Thank you @eladb

chrisbirster commented 3 years ago

What happened to this project? https://github.com/wchaws/cdk-ecr-deployment. It doesn't exist now.

wchaws commented 3 years ago

What happened to this project? https://github.com/wchaws/cdk-ecr-deployment. It doesn't exist now.

This project is going to move into official cdklabs org. Some process is on going. Stay tuned.


2021/06/03 Updated

https://github.com/wchaws/cdk-ecr-deployment has been moved to cdklabs.

pseudo-su commented 3 years ago

This project is going to move into official cdklabs org. Some process is on going. Stay tuned.

Does that affect whether or not there would still be a possibility for having a more "official" solution?

I'd love a cdk ecr-deployment module that also supported "OCI Articacts" as described here

https://aws.amazon.com/blogs/containers/oci-artifact-support-in-amazon-ecr/

wchaws commented 3 years ago

This project is going to move into official cdklabs org. Some process is on going. Stay tuned.

Does that affect whether or not there would still be a possibility for having a more "official" solution?

I'd love a cdk ecr-deployment module that also supported "OCI Articacts" as described here

https://aws.amazon.com/blogs/containers/oci-artifact-support-in-amazon-ecr/

I believe cdk-ecr-deployment does support OCI image because it's based on https://github.com/containers/skopeo

pseudo-su commented 3 years ago

Admittedly I haven't had a chance to look into it exhaustively yet but there is an open feature request on the skopeo repo to support OCI Artifacts https://github.com/containers/skopeo/issues/931

wchaws commented 3 years ago

Admittedly I haven't had a chance to look into it exhaustively yet but there is an open feature request on the skopeo repo to support OCI Artifacts containers/skopeo#931

But from https://github.com/containers/skopeo project README. It says it supports OCI image. (I'm confused)

pseudo-su commented 3 years ago

My understanding is the OCI Image spec is distinct from the OCI Artifact spec

EG from here https://github.com/opencontainers/distribution-spec/blob/main/spec.md#introduction

While OCI Image is the most prominent, the specification is designed to be agnostic of content types. Concepts such as "manifests" and "digests", are currently defined in the Open Container Initiative Image Format Specification (a.k.a. "OCI Image Spec").

To support other artifact types, please see the Open Container Initiative Artifact Authors Guide (a.k.a. "OCI Artifacts").

automartin5000 commented 3 years ago

If the idea here is that everything is self-contained in CDK, what's the recommended way to move artifacts (S3/ECR Images) between accounts? Surely the recommendation is not to rebuild an artifact after we've already tested it in a lower environment :)

ahammond commented 3 years ago

Use case: bootstrapping an ECR repo.

Say I want to have a stack which contains both an ECR repository and the ECS Cluster that uses it. Currently I'm stuck doing stupid tricks like having a bootstrap mode. If I can stuff a HelloWorld container in there, I have a viable starting point.

TrentonAdams commented 3 years ago

The CDK should not even send assets to a central repo. So it might have to do a v2 of DockerImageAsset, as right now it sends it to aws-cdk/assets, which is just icky.

TrentonAdams commented 3 years ago

Actually, wouldn't this be better?

        const asset = new DockerImageAsset(this, 'DockerImage', {
            directory: path.join(__dirname, './my-image'),
            repoName: 'my-app-repo',
            imageName: 'my-image:1.0.0'
        });

Then the ECR repo url is determined by the AWS account you're using. If repoName/imageName are given, the new functionality is used, otherwise it goes to aws-cdk/assets repo.

elhedran commented 2 years ago

A use case I haven't seen mentioned here is the one I'm looking into.

If using CDK for a service catalogue (@aws-cdk/aws-servicecatalog-alpha) the assets need to exist separately from the stack deployed into the service catalogue. While we could just give permission to the CDK bootstrap stack for this, it would make more sense to have a separate assets stack to sit along side the stack representing the catalogue item, so that life-cycle etc could be managed expliciltly

TrentonAdams commented 2 years ago

@elhedran The assets needed by the stack are a dependency of the stack deployment. In terms of software, that which changes together stays together. A core aspect of the Single Responsibility Principle is...

Gather together the things that change for the same reasons. Separate those things that change for different reasons.

Since the asset is a dependency of that stack, it should be integrated with that stack, because the need for it will change with the need for the stack. I would see separating them as a software development anti-pattern. I might abstract them if there were a lot of them, but generally speaking still keep them together.

elhedran commented 2 years ago

@TrentonAdams - While I'd normally agree that the assets stay with the stack, when attempting to that with (https://docs.aws.amazon.com/cdk/api/v1/docs/aws-servicecatalog-readme.html) the service catalog product construct pretty much the first error you will hit is that you can't have the assets in the stack.

To be exact on the error that will be encountered: https://github.com/aws/aws-cdk/blob/be909bc90822db947ec0a932621709d0cb07e50e/packages/%40aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts#L22

I assume this is because what is published to the service catalog is just the synthesized cloud formation template, and not assets.

However if you can show working code where something using the service catalog Product construct includes assets directly I'd be very happy to change my approach.

Trust me, in all the stacks that are not trying to publish under service catalog, the assets are indeed integrated with the stack.

ahammond commented 2 years ago

This is still a problem. cdk-ecr-deployment would solve my problem, except it's brutally slow. https://github.com/cdklabs/cdk-ecr-deployment/issues/194 and I literally can't sell that developer experience to my devs. As far as I can see, re-writing the lambda in TypeScript (or python) would immediately solve this problem. And... I can't see any reason for it to be in golang.

scanlonp commented 2 years ago

Great news! The CDK team will be picking this up and designing a package in the aws-cdk repository called aws-ecr-deployment. It will have similar functionality to cdklabs/cdk-ecr-deployment, but will be maintained by the CDK team. We will keep you updated as this develops!

TrentonAdams commented 2 years ago

We will keep you updated as this develops!

Will there be an issue you can link to for feedback from the community?

One additional thing I just considered, is that perhaps this new package should create an "asset" stack, named the same as the stack using it. That way, the "asset" stack is created prior to the stack in question, and then it just uses it.

scanlonp commented 2 years ago

Hi @TrentonAdams

Will there be an issue you can link to for feedback from the community?

We're always happy to hear feedback. Generally, this issue is the right place to provide feedback. Were you thinking of something different?

As for your suggestion, the aws-ecr-deployment module would be entirely separate from the asset mechanism you're talking about. We don't want to expand the use cases for assets and would rather support this use case (publishing a docker image asset to an arbitrary ECR repository) as a separate module.

scanlonp commented 2 years ago

Check out cdk-docker-image-deployment, a new library that gives you control of the tags and organization of your Docker image assets.

Right now, it lives in cdklabs and will be maintained by the cdk team, but depending on its popularity we may add it to the core aws-cdk-lib library as well. We are excited to get your feedback and hear what features you would like to see added!

fjinkis commented 2 years ago

@scanlonp First of all, thank you so much for all your effort! I just replaced my code with this library and I was surprised by the number of extra resources created by the stack. From my point of view, it is a bit intrusive to create 7 new roles with their policies in order to run CodeBuild using 4 lambdas and 1 state machine function. To be honest I was tempted to give it a try because I was trying to upload the image cleaner than cdk-ecr-deployment library. In my opinion, it would be much better if we could reuse all those resources for any image that we'd like to upload to any ECR repo (perhaps as a dependency stack, does that make sense?). Do you know if there is a way to do that? And if not, is there a way to specify which role the custom resource should use? I didn't find anything in the repo, but maybe you are working on something similar. I think it would not only help to reduce the number of resources, but also allow us to continue to divide the responsibilities between implementation and permissions.

scanlonp commented 2 years ago

@fjinkis thanks for the suggestion! I agree that the construct does create a fair number of resources, although for good reason. The construct does not support it currently, but sharing resources is definitely desirable in the future. I opened up this feature request https://github.com/cdklabs/cdk-docker-image-deployment/issues/29 if you would like to discuss further.

TheRealAmazonKendra commented 1 year ago

Closing this issue as the work has been completed. Any further issues should be opened in the cdk-docker-image-deployment repo.

github-actions[bot] commented 1 year ago

⚠️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.

fabiozig commented 1 year ago

I'm not sure if this issue should be closed. The proposed solution was to have an option to set your own ecr repository without relying on the cdk/assets repository... The new library still uses the cdk/asset repository, so if i want to delete any of my images I would have to manually create a lifecycle rule for each one of my services based on their tag?

I can definitely do that maybe with aws-sdk but I still believe being able to bypass the cdk/assets repository would be a better way to go.

SamStephens commented 1 year ago

@TheRealAmazonKendra cdk-docker-image-deployment does not appear to work for non-Javascript languages, and in addition has seen no sign of activity for months.

saste commented 10 months ago

This issue is linked from this page: https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_ecr_assets/README.html

⚠️ Please note that this is a 3rd-party construct library and is not officially supported by AWS. You are welcome to +1 this GitHub issue if you would like to see native support for this use-case in the AWS CDK.

This adds to the confusion, because on one side it is suggesting this might be natively integrated in the aws-cdk, but on this issue it is suggesting that this is supposed to be maintained as a third-party repository (while we see it is not really maintained).

LeuisKen commented 4 months ago

@TheRealAmazonKendra cdk-docker-image-deployment does not appear to work for non-Javascript languages, and in addition has seen no sign of activity for months.

Now we can say for years.

bschulz87 commented 1 month ago

Having to deal with broken and unmaintained unofficial libraries for deploying container images is beyond frustrating. Especially with multi-platform builds. Please consider reopening this issue.