Confusing Deprecations: IDeploymentEnvironment / Stack.addDockerImageAsset / DockerImageAsset.repositoryName
See original GitHub issueDockerImageAssetOptions.repositoryName
is deprecated, instructing to override Stack.addDockerImageAsset
.
Interface property DockerImageAssetSource.repositoryName
is also deprecated with a confusing message.
However Stack.addDockerImageAsset()
is also deprecated with a confusing deprecation warning:
I assume IDeploymentEnvironment
is an interface I need to implement. However I cannot find this interface in the CDK source code anywhere and can only find references to it in the JSDoc’s mentioning it in the @aws-cdk/core/lib/stack.ts
file.
I did find one other mention in an (Outdated!) PR: https://github.com/aws/aws-cdk/pull/6366#discussion_r382131917
From reviewing reviewing #6366 it seems that that IDeploymentEnvironment
was renamed to IStackSynthesizer
.
So… that means if I want to change what my docker image repository name is, I have to implement an entire stack synthesizer class? I just want a custom repository name for each image… 😃
Reproduction Steps
import { Repository } from '@aws-cdk/aws-ecr';
import { DockerImageAsset } from '@aws-cdk/aws-ecr-assets';
import { Construct, DockerImageAssetLocation, DockerImageAssetSource, Stack, StackProps } from '@aws-cdk/core';
class MyStack extends Stack {
// deprecated
addDockerImageAsset(asset: DockerImageAssetSource): DockerImageAssetLocation {
return super.addDockerImageAsset(asset);
}
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const repo = new Repository(this, 'repo', {
repositoryName: 'my-repo',
});
new DockerImageAsset(this, 'containerImageAsset', {
directory: './containerImageSrc',
// deprecated
repositoryName: repo.repositoryName,
});
}
}
Error Log
[Warning at /ecr/apiAsset] DockerImageAsset.repositoryName is deprecated. Override "core.Stack.addDockerImageAsset" to control asset locations
Environment
- CLI Version : 1.45.0 (build 0cfab15)
- Framework Version: 1.45.0
- Node.js Version: v14.4.0
- OS : MacOS 10.15.5
- Language (Version): TypeScript (3.9.3)
Other
I need to create multiple ECR repositories, one repo per “application image”, ideally with a custom (human friendly) repository name. I need this for several reasons:
- Security (access control via IAM and Resource Policies)
- User access (
docker pull repo-url/image:tag
) - External (non-CDK) tools access to image URI’s
- Ability to use the
latest
tag for each of my images & repositories (docker pull repo-url/image:latest
) - Managing individual Repository Tags for Billing and IAM Security
We have many different images for various applications, and pushing them all into aws-cdk/assets
makes it impossible to distinguish one application image from another. This also means that I cannot use the latest
tag (since only one image can have a unique tag in a repository).
I need to be able to reference / find my images from outside of my CDK Application / Constructs, so that users and external (non-CDK) tools can easily find and pull these images.
With a single ECR repository, I can no longer effectively manage security on my individual images, since that’s typically done per-repository, not per individual image hash/tag. If all of my images for different containers are in aws-cdk/assets
, that makes granting access all-or-nothing.
Regarding the new Stack Synthesizer changes, why should my Docker Image Repository Name be specified at the environment-level and not at the image level? I think specifying a Container Registry at the environment level makes more sense (but not an image repository.)
Lastly, how do I properly override the repository name at the environment level? There’s no documentation to do this AFAIK, although from reading through @aws-cdk/core/lib/stack-synthesizers/legacy.ts
I think I can set the context key assets-ecr-repository-name
(which defaults to aws-cdk/assets
) to a custom value. I think I could get this to sufficiently solve my use case, with an per-stack context value and one image/repository per stack.
I feel like this whole thing might all be a CDK-specific anti-pattern (even though it’s the norm for most container workflows). Should I avoid using the CDK and exclusively manage my container images completely outside of the CDK for this use case?
This is 🐛 Bug Report and a 📕 documentation issue
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:13 (5 by maintainers)
Top GitHub Comments
If one already has a repository in the stack, wouldn’t it be agreeable to allow that to be passed to the DockerImageAsset? In many cases I just need that asset to land in an already created repository. In my case I have an environment that created its own ECR Repository and I want those images to go there and NOT into a default cdk/asset repository as the Repository that I want those images to land in will have other ways of scanning images and such.
If those images go elsewhere, a project’s resources bleed out into a general location where they really shouldn’t be. Is it at least agreeable to let one pass in the repository where those resources should land? I don’t need CDK to create it, but if I have to later fish the resources out of cdk/assets - that has a bunch of other implications.
could then easily become
and this would be no different than how we pass Vpcs and other resources around today across stacks and such.
At the moment the CDK comes with 2 asset systems:
The legacy one (currently still the default), where you get to specify a repositoryName per asset, and the CLI will create and push to whatever ECR repository you name.
The new one (will become the default in the future), where a single ECR repository will be created by doing
cdk bootstrap
and all images will be pushed into it. The CLI will not create the repository any more, it must already exist. IIRC this was done to limit the permissions required for deployments. @eladb, can you help me remember why we chose to do it this way?If you want to deviate from this pattern then yes, you will have to implement your own subclass of
IStackSynthesizer
and use that.