-
Notifications
You must be signed in to change notification settings - Fork 4k
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
[pipelines] Docker logins for assets #10999
Comments
How would you expect this to work on the desktop? I.e. if you do |
(What I'm saying is this might have implications for the asset manifest and CLI as well) |
TBH I had no expectations of a particular behaviour when deploying locally. I only started using docker image assets after having set up a Pipeline. That said my understanding of |
The requirement of having done docker login was also never explicit when developing locally, since I was already logged in. Only when moving the docker build to CodeBuild did this become apparent. |
Here's the hack I added to my pipeline stack (after the pipeline was created) to get past this: private static addECRLogin (pipeline: CdkPipeline, sourceECRs: string[]) {
for (const action of pipeline.stage('Assets')?.actions) {
const actionProperties = action.actionProperties;
if (actionProperties.actionName.startsWith('Docker')) {
// workaround for https://github.com/aws/aws-cdk/issues/10999
const publishAction = action as PublishAssetsAction;
const commands: string[] = (publishAction as any).commands;
for (const sourceECR of sourceECRs) {
// NOTE: this makes the simplifying assumption that the sourceECR is in the same region as the pipeline
const command = `aws ecr get-login-password --region ${Stack.of(pipeline).region} | docker login --username AWS --password-stdin ${sourceECR}`;
if (!commands.includes(command)) {
// login needs to happen before the asset publication (that's where docker images are built)
commands.unshift(command);
}
}
new Policy(pipeline, 'AllowECRLoginAndPull', {
statements: [
new PolicyStatement({
actions: [
'ecr:GetAuthorizationToken',
'ecr:GetDownloadUrlForLayer',
'ecr:BatchGetImage',
],
resources: ['*'],
sid: 'AllowECRLoginAndPull',
}),
],
}).attachToRole(actionProperties.role!);
}
}
} |
@tobli What do you pass in as sourceECRs for this? |
@nsquires413 It's the full ECR repo name, e.g. |
@tobli @pgarbe One more question if you don't mind. I'm trying to translate this method into C#. Looking at the 'PublishAssetsAction' source code it looks like the it has a private member 'commands'. It seems like you were still able to access this field by casting the action as 'any'? Is that right? Does anyone know if this is possible in C#? |
Correct, it's accessing private field via the cast. That's of course risky, but Typescript lets you do that. If C# does I have no clue I'm afraid. |
When we get to implementing this, see Quip doc with reference See also #11774 |
I had same problem, but I just put docker login as a pre-build command on the codebuild project. https://github.com/quincycs/aws-cdk-q-starter/blob/master/cdk-app/src/PipelineStack.ts#L102 This was an easy fix for me, so maybe I don't understand the issue. |
@quincycs this issue arises when using aws-ecr-assets to build a Docker image as part of the pipeline. Cdk Assets will create a new Assets build pipeline step as an implementation detail. It's for that the login step is needed. |
In python, we don't have access to the publishAssetAction.commands. I ended up writing a script to access the pipeline.template.json using aws_cdk.cx_api and update the buildspec phases for all docker asset. This script was executed as part of synth_command in the pipeline after we run cdk synth. Example:
Output Asset Buildspec.yml
|
I needed to login to a dockerhub paid account, so I worked around like this. The auth token is stored in function maybeAddDockerLogin(scope: cdk.Construct, pipeline: pipelines.CdkPipeline) {
let assetStage: codepipeline.IStage;
try {
assetStage = pipeline.stage('Assets');
} catch {
// If a stage with a given name cannot be found, CDK throws an exception
return;
}
const dockerAssetActions = assetStage.actions.filter((action) => {
const actionProperties = action.actionProperties;
return actionProperties.actionName.startsWith('Docker');
});
if (dockerAssetActions.length === 0) {
return;
}
// Replace the last parameter with the name of your secret.
// This secret is the access token for a paid dockerhub user
// https://docs.docker.com/docker-hub/access-tokens/
const dockerHubSecret = secrets.Secret.fromSecretNameV2(scope, 'SharedSecretImport', 'shared/dockerhub-access-token');
const secretAccessPolicy = new iam.Policy(scope, 'SecretAccessPolicy', {
statements: [
new iam.PolicyStatement({
sid: 'AllowFetchingDockerHubSecret',
actions: ['secretsmanager:GetSecretValue'],
resources: [`${dockerHubSecret.secretArn}-??????`],
}),
],
});
dockerAssetActions.forEach((action) => {
const publishAction = action as any;
const codeBuildProject = publishAction.node.defaultChild.node.defaultChild;
codeBuildProject.environment.environmentVariables = codeBuildProject.environment.environmentVariables ?? [];
codeBuildProject.environment.environmentVariables.push({
name: 'DOCKER_AUTH_TOKEN',
type: 'SECRETS_MANAGER',
value: dockerHubSecret.secretName,
});
secretAccessPolicy.attachToRole(action.actionProperties.role!);
const commands: string[] = publishAction.commands;
const command = 'echo ${DOCKER_AUTH_TOKEN} | docker login --username gingereng --password-stdin';
if (!commands.includes(command)) {
// login needs to happen before the asset publication (that's where docker images are built)
commands.unshift(command);
}
});
} (credit to @tobli's comment above for the majority of this) |
hi @tobli - do you know when the 'Assets' stage is created? I tried using your hack in python, but the command |
@rix0rrr , could we implement a boolean flag in CDKPipeline construct which is defaults FALSE. If enabled, we could add a blanket ECR login command in pre-build step of PublishAssetAction if the assetType === "Docker". The ECR should be in same account/region as the pipeline? |
+1 Push, we need this.... CDK Docker Assets are not usable without it for our team.
to fast... CDK V.1.109.0 Python It seems i cannot access the Assets Stage with
Neither could i access the commands:
Thanks a lot! |
Currently, `cdk-assets` does a single `docker login` with credentials fetched from ECR's `getAuthorizationToken` API. This enables access to (typically) the assets in the environment's ECR repo (`*--container-assets-*`). A pain point for users today is throttling when using images from other sources, especially from DockerHub when using unauthenticated calls. This change introduces a new configuration file at a well-known location (and overridable via the CDK_DOCKER_CREDS_FILE environment variable), which allows specifying per-domain login credentials via either the default ECR auth tokens or via a secret in SecretsManager. If the credentials file is present, a Docker credential helper (docker-credential-cdk-assets) will be set up for each of the configured domains, and used for the `docker build` commands to enable fetching images from both DockerHub or configured ECR repos. Then the "normal" credentials will be assumed for the final publishing step. For backwards compatibility, if no credentials file is present, the existing `docker login` will be done prior to the build step as usual. This PR will be shortly followed by a corresponding PR for the cdk pipelines library to enable users to specify registries and credentials to be fed into this credentials file during various stages of the pipeline (e.g., build/synth, self-update, and asset publishing). related #10999 related #11774
Currently, `cdk-assets` does a single `docker login` with credentials fetched from ECR's `getAuthorizationToken` API. This enables access to (typically) the assets in the environment's ECR repo (`*--container-assets-*`). A pain point for users today is throttling when using images from other sources, especially from DockerHub when using unauthenticated calls. This change introduces a new configuration file at a well-known location (and overridable via the CDK_DOCKER_CREDS_FILE environment variable), which allows specifying per-domain login credentials via either the default ECR auth tokens or via a secret in SecretsManager. If the credentials file is present, a Docker credential helper (docker-credential-cdk-assets) will be set up for each of the configured domains, and used for the `docker build` commands to enable fetching images from both DockerHub or configured ECR repos. Then the "normal" credentials will be assumed for the final publishing step. For backwards compatibility, if no credentials file is present, the existing `docker login` will be done prior to the build step as usual. This PR will be shortly followed by a corresponding PR for the cdk pipelines library to enable users to specify registries and credentials to be fed into this credentials file during various stages of the pipeline (e.g., build/synth, self-update, and asset publishing). related #10999 related #11774
Currently, `cdk-assets` does a single `docker login` with credentials fetched from ECR's `getAuthorizationToken` API. This enables access to (typically) the assets in the environment's ECR repo (`*--container-assets-*`). A pain point for users today is throttling when using images from other sources, especially from DockerHub when using unauthenticated calls. This change introduces a new configuration file at a well-known location (and overridable via the CDK_DOCKER_CREDS_FILE environment variable), which allows specifying per-domain login credentials via either the default ECR auth tokens or via a secret in SecretsManager. If the credentials file is present, a Docker credential helper (docker-credential-cdk-assets) will be set up for each of the configured domains, and used for the `docker build` commands to enable fetching images from both DockerHub or configured ECR repos. Then the "normal" credentials will be assumed for the final publishing step. For backwards compatibility, if no credentials file is present, the existing `docker login` will be done prior to the build step as usual. This PR will be shortly followed by a corresponding PR for the cdk pipelines library to enable users to specify registries and credentials to be fed into this credentials file during various stages of the pipeline (e.g., build/synth, self-update, and asset publishing). related #10999 related #11774
Currently, `cdk-assets` does a single `docker login` with credentials fetched from ECR's `getAuthorizationToken` API. This enables access to (typically) the assets in the environment's ECR repo (`*--container-assets-*`). A pain point for users today is throttling when using images from other sources, especially from DockerHub when using unauthenticated calls. This change introduces a new configuration file at a well-known location (and overridable via the CDK_DOCKER_CREDS_FILE environment variable), which allows specifying per-domain login credentials via either the default ECR auth tokens or via a secret in SecretsManager. If the credentials file is present, a Docker credential helper (docker-credential-cdk-assets) will be set up for each of the configured domains, and used for the `docker build` commands to enable fetching images from both DockerHub or configured ECR repos. Then the "normal" credentials will be assumed for the final publishing step. For backwards compatibility, if no credentials file is present, the existing `docker login` will be done prior to the build step as usual. This PR will be shortly followed by a corresponding PR for the cdk pipelines library to enable users to specify registries and credentials to be fed into this credentials file during various stages of the pipeline (e.g., build/synth, self-update, and asset publishing). Two refactorings here: - Moved obtainEcrCredentials from docker.ts to docker-credentials-ts. - Moved DefaultAwsClient from bin/publish.ts to lib/aws.ts related #10999 related #11774 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Introduce a new set of properties to the pipeline constructs to enable users to specify Docker registries -- and associated credentials for each -- to be used during the pipeline build/synth, self-mutate, and asset publishing stages. These APIs enable the user to specify a Docker registry (e.g., DockerHub, ECR) and either secrets or use role credentials to authenticate to each registry, as well as specify which step(s) of the pipeline need these credentials. DRAFT -- Posting just the basic API for feedback while I finish up tests and final implementation. Any and all feedback welcome! fixes #10999 fixes #11774
Introduce a new set of properties to the pipeline constructs to enable users to specify Docker registries -- and associated credentials for each -- to be used during the pipeline build/synth, self-mutate, and asset publishing stages. These APIs enable the user to specify a Docker registry (e.g., DockerHub, ECR) and either secrets or use role credentials to authenticate to each registry, as well as specify which step(s) of the pipeline need these credentials. fixes #10999 fixes #11774
Introduce a new set of properties to the pipeline constructs to enable users to specify Docker registries -- and associated credentials for each -- to be used during the pipeline build/synth, self-mutate, and asset publishing stages. These APIs enable the user to specify a Docker registry (e.g., DockerHub, ECR) and either secrets or use role credentials to authenticate to each registry, as well as specify which step(s) of the pipeline need these credentials. fixes #10999 fixes #11774 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
|
@jabrennem The stage is created when you add an application stage which actually contains assets to be published. |
Introduce a new set of properties to the pipeline constructs to enable users to specify Docker registries -- and associated credentials for each -- to be used during the pipeline build/synth, self-mutate, and asset publishing stages. These APIs enable the user to specify a Docker registry (e.g., DockerHub, ECR) and either secrets or use role credentials to authenticate to each registry, as well as specify which step(s) of the pipeline need these credentials. fixes aws#10999 fixes aws#11774 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Currently, `cdk-assets` does a single `docker login` with credentials fetched from ECR's `getAuthorizationToken` API. This enables access to (typically) the assets in the environment's ECR repo (`*--container-assets-*`). A pain point for users today is throttling when using images from other sources, especially from DockerHub when using unauthenticated calls. This change introduces a new configuration file at a well-known location (and overridable via the CDK_DOCKER_CREDS_FILE environment variable), which allows specifying per-domain login credentials via either the default ECR auth tokens or via a secret in SecretsManager. If the credentials file is present, a Docker credential helper (docker-credential-cdk-assets) will be set up for each of the configured domains, and used for the `docker build` commands to enable fetching images from both DockerHub or configured ECR repos. Then the "normal" credentials will be assumed for the final publishing step. For backwards compatibility, if no credentials file is present, the existing `docker login` will be done prior to the build step as usual. This PR will be shortly followed by a corresponding PR for the cdk pipelines library to enable users to specify registries and credentials to be fed into this credentials file during various stages of the pipeline (e.g., build/synth, self-update, and asset publishing). Two refactorings here: - Moved obtainEcrCredentials from docker.ts to docker-credentials-ts. - Moved DefaultAwsClient from bin/publish.ts to lib/aws.ts related aws#10999 related aws#11774 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Introduce a new set of properties to the pipeline constructs to enable users to specify Docker registries -- and associated credentials for each -- to be used during the pipeline build/synth, self-mutate, and asset publishing stages. These APIs enable the user to specify a Docker registry (e.g., DockerHub, ECR) and either secrets or use role credentials to authenticate to each registry, as well as specify which step(s) of the pipeline need these credentials. fixes aws#10999 fixes aws#11774 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
For anybody looking at this, #15364 added dockerCredentials in CodePipeline to use:
For some reason publishAssetsInParallel must be set true though (default). Otherwiese got "This BuildSpec contains CloudFormation references and is supported by publishInParallel=false" and the build failed. |
Just banged my head on this for 4 hours today... -_- This has to be a bug right? |
When using CDK Pipelines the autogenerated Assets action will build Docker images, and publish to the cdk-provided ECR. However if included Dockerfiles build on images in a non-public repository (e.g. an ECR in a different account), those builds will fail since the Assets action has no way of specifying sources to
docker login
in to.Use Case
Prior to using Pipelines we've used a shared ECR in a dedicated account to both store our internal base images, as well as images built on top of those. A single
docker login
would cover both pull and push from that repo.However when switching to Pipelines, the destination repo changes. Pipelines transparently handles login to to that, but provides no configuration option for docker registries that need to be logged in to prior to asset building.
Proposed Solution
Other
The error message from the Assets/DockerAsset1 CodeBuild project was:
This is a 🚀 Feature Request
The text was updated successfully, but these errors were encountered: