Open tachyonics opened 4 years ago
Why not grant the role that runs the build these permissions? What’s the value in assuming a different role?
That would also be fine. Is this possible? How would you give permissions to this role and then use the role from within the build?
Currently my Dockerfile partially looks something like-
RUN yum install -y -q git aws-cli
RUN git config --global credential.helper '!aws codecommit credential-helper $@'
RUN git config --global credential.UseHttpPath true
RUN git clone https://git-codecommit.us-west-2.amazonaws.com/v1/repos/MyRepository
which produces the error-
Cloning into 'MyRepository'...
--
101 |
102 | 'NoneType' object has no attribute 'secret_key'
103 | fatal: could not read Username for 'https://git-codecommit.us-west-2.amazonaws.com/v1/repos/MyRepository': No such device or address
Hi, is there any update for this?
Hey,
I too am running into the same issue -- I got around it by creating my own asset publishing step in the CDK pipeline. I ran into two issues:
Is there an update for this issue?
Use Case We need to access CodeArtifact during the asset build process.
Seems like this role you're trying to assume would be asset-specific. Then shouldn't the CLI assume the same role while doing cdk deploy
and bundling the asset there?
How would one go about configuring the CLI to assume the role while doing the cdk deploy
through CDK?
The buildspec.yml
for the asset publication stage is autogenerated; this is what I see for the stage in the console:
{
"version": "0.2",
"phases": {
"install": {
"commands": "npm install -g cdk-assets"
},
"build": {
"commands": [
"cdk-assets --path ...
]
}
}
}
I can make changes to this to assume the required role and re-deploy but those are not captured in the CDK code and it resets to the original buildspec.yml
after every deployment.
For context, I'm doing a build in my DockerFile
which requires a CODEARTIFACT_TOKEN
and I haven't been able to figure out how to get this token during the build of the Docker image asset through CDK. I modified the DockerFile
to install the aws cli, so that I could export the token into an environment variable but was getting the following error: Unable to Locate Credentials...
during the asset build stage. So the workaround I did was to modify the generated buildspec.yml
to export the authorization token into a file and then copy that onto the file system of the container and export it into an environment variable. So even if I were able to assume into the required role how would I go about using those credentials when calling docker build other than exporting them as environment variables in the buildspec?
For now I ended up writing my own stage that builds the image and uploads to the required ECR repository but was hoping to be able to use the DockerImageAsset
because it simplifies deploying across accounts and regions.
How would one go about configuring the CLI to assume the role while doing the
cdk deploy
through CDK?
At this point it's not possible, but that's what I'm trying to get a sense for. Is this an "assets" feature or a "pipelines" feature?
What would you expect to happen if you did cdk deploy
on a development copy of the stack?
And is this purely about CodeArtifact or is there are more general need for IAM credentials inside a Docker build?
My expectation is that the credentials profile used for the cdk deploy
would be sufficient to build the asset and upload it to the required ECR repository for the DockerImageAsset. For the pipeline integration my two cents would be that this would be an assets feature because the asset is responsible for setting up the CodeBuild build project which deploys the asset, and the pipeline just runs it.
Allowing one to have IAM credentials inside of a Docker build would address the issue I'm having as well as @tachyonics (I believe) because I'd be able to use those IAM credentials to get the authorization token through the aws cli or assume a role that is able to.
My current workaround for this to have a custom asset publication step. Each action in this step has the required permissions to assume a role which has the required permissions to build and publish the asset in the appropriate account's ECR repository.
Currently my use case requires credentials for CodeCommit although likely CodeArtifact in the future. My feeling is that if the Docker asset building process is going to be as flexible as using something like CodeBuild to build a Docker image, generalised access to IAM credentials will be required.
From the perspective of least privileges, I would think there should be an option for asset-specific credentials (with the ability for the CLI to assume these credentials).
Is this something that I could contribute to based on my understanding what what would need to be done (ie. adding the ability to pass in and assume a role in cdk-assets[1] with the credentials then passed into the docker build process) or does it require a more robust design from the core CDK team)
I would like to add another use case, possibly this could be a separate ticket, feedback is welcome. So, during our DockerAssetImage build, we need to install a private pip module. While we could use CodeArtifact and auth via IAM (which ofc requires credentials) we went down the easy road first and just installed from github directly. For that we need to have a github api token at hand, which is stored in the secret manager. So we tried to inject it via build args, but the secrets do not get resolved during the asset build step (I think this refers to @tachyonics comment as well). Next thing we tried was to have a multi stage docker build and first pull the secret via aws cli and then copy it over to the actual build container, which also fails because of missing credentials. My next step would have been to try and pull the artifact from CodeArtifact, but after reading this thread, it does not make sense to try and rather go for the last resort and build the image manually, i guess.
We pull artifacts from CodeArtifact as a part of our build process and need an authorization token for it. What we ended up doing is that in the Build
stage of our CodePipeline we export the CodeArtifact authorization token as an environment variable and then copy it into the DockerFile in our code using sed
. The output of the Build
stage is all the files so our modified DockerFile gets sent as input to the Assets
which builds the actual Docker image and publishes it to the appropriate ECR repository. This workaround allowed us to get rid of separate publishing steps in our pipeline and allowed us to rely on the DockerImageAsset.
Pulling from CodeCommit or CodeArtifact during multi-stage Docker build is only natural. Yet, AWS CDK does not really support this well, as is evident by #10193, #9942 and #10298.
My recent struggle was that I coudn't use AWS SDK to get CodeArtifact token, because AWS CDK does not support async/await code. The workaround I used for CodeArtifact and node.js
is:
This must be synchronous because AWS CDK does not support async code
import { execSync } from 'child_process';
export const CodeArtifactToken = execSync(
'aws codeartifact get-authorization-token --domain my-domain --query authorizationToken --output text --profile my-profile',
{
encoding: 'utf8',
},
).trim();
ecs.ContainerImage.fromAsset(
path.join(__dirname, 'runtime'),
{
buildArgs: {
CODEARTIFACT_TOKEN: CodeArtifactToken,
},
// TODO: add hashBuildArgs - https://github.com/aws/aws-cdk/issues/15936
},
),
.npmrc
file next to Dockerfile
@mycompany:registry=https://project-112233445566.d.codeartifact.region.amazonaws.com/npm/project/
//project-112233445566.d.codeartifact.region.amazonaws.com/npm/project/:always-auth=true
//project-112233445566.d.codeartifact.region.amazonaws.com/npm/project/:_authToken=${CODEARTIFACT_TOKEN}
ARG
in Dockerfile
ARG CODEARTIFACT_TOKEN
ENV CODEARTIFACT_TOKEN=${CODEARTIFACT_TOKEN}
COPY ["package.json", "package-lock.json*", ".npmrc", "./"]
RUN npm install
Hi, is there any update on when this feature will be available?
I am running into this issue as well while trying to pip install
dependencies from CodeArtifact during a Docker image asset build.
The workaround described by @paya-cz works pretty well, but it leads to very slow builds, since the Docker layer cache is invalidated every time we generate a new CodeArtifact token.
Inspired by @paya-cz, I had to solve this for the combination of Typescript CDK and PIP Packages.
--domain-owner
is necessary if you do this command cross-account--duration-seconds
it's recommended to limit the token time-to-live for security reasons --profile
is necessary if you initially provision the CDK Pipeline (if you use it to provision your Stack) and needs to be removed afterward.import { execSync } from 'child_process';
export const CodeArtifactToken = execSync(
'aws codeartifact get-authorization-token --domain my-domain --query authorizationToken --domain-owner 111111111111 --output text --duration-seconds 900 --profile my-profile',
{
encoding: 'utf8',
},
).trim();
The token will be passed as a Build Argument to the Docker Build Process
this.exampleLambda = new DockerImageFunction(this, `exampleLambda`, {
code: DockerImageCode.fromImageAsset(path.join(__dirname, '..', 'assets'), {
buildArgs: {
CODEARTIFACT_TOKEN: CodeArtifactToken,
},
cmd: ["example.lambda_handler"],
}),
vpc: vpc,
vpcSubnets: subnets,
securityGroups: [securityGroup],
memorySize: 512,
timeout: Duration.minutes(1),
retryAttempts: 0,
environment: {
ENVIRONMENT: props.stage,
}
});
The best way to make sure everything is set up correctly, you can generate the PIP Global Config on the fly:
ARG CODEARTIFACT_TOKEN
RUN echo "[global]" > /etc/pip.conf && \
echo "index-url = https://aws:${CODEARTIFACT_TOKEN}@MYDOMAIN-ACCOUNTID.d.codeartifact.eu-central-1.amazonaws.com/pypi/REPONAME/simple/" >> /etc/pip.conf
Important IAM Policy You would need to add this IAM policy to your CodePipeline to be able to access the CodeArtifact Repository:
new PolicyStatement({
actions: [
"codeartifact:GetAuthorizationToken",
"codeartifact:GetRepositoryEndpoint",
"codeartifact:ReadFromRepository",
"sts:GetServiceBearerToken"
],
resources: ["*"]
}),
More complex Docker-based build processes may need authentication to other AWS resources as part of building the asset. This is possible with a CodeBuild project and seems like a restriction of the current asset build process.
Use Case
Our asset build process requires pulling from CodeCommit repositories for dependencies and potentially CodeArtifact in the future.
This is a :rocket: Feature Request