January 26th, 2022

Problem: you’re running a multibuild docker build in your cdk asset publishing step and it needs to pull down artifacts from codeartifact.

Here how I got this working for a gradle build.

codeartifact repository

Make sure your repository has a policy that gives GetRepositoryEndpoint and ReadFromRepository permisions to the codebuild role that is assumed by the asset publishing build step.

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "AWS": "arn:aws:iam::<your account id goes here>:root"
    },
    "Action": [
      "codeartifact:List*",
      "codeartifact:Describe*",
      "codeartifact:Get*",
      "codeartifact:Read*"
    ],
    "Resource": "*"
  }]
}

Dockerfile

Add a build argument to pass in the codeartifact token

…
ARG CODEARTIFACT_TOKEN
RUN mkdir -p ~/.gradle
RUN echo codeartifactToken=${CODEARTIFACT_TOKEN} > ~/.gradle/gradle.properties
…

cdk pipeline stack

Add synthCodeBuildDefaults to give the synth step permission to get a token with the correct permissions to read from the repository.

synthCodeBuildDefaults: {
  rolePolicy: [
    new iam.PolicyStatement({
      actions: [
        'codeartifact:GetAuthorizationToken'
      ],
      resources: [`${codeartifactDomainArn}`],
    }),
    new iam.PolicyStatement({
      actions: [
        'codeartifact:GetRepositoryEndpoint',
        'codeartifact:ReadFromRepository'
      ],
      resources: [`${codeartifactRepositoryArn}`],
    }),
    new iam.PolicyStatement({
      actions: ['sts:GetServiceBearerToken'],
      resources: ['*'],
      conditions: {
        "StringEquals": {
          "sts:AWSServiceName": "codeartifact.amazonaws.com"
        }
      }
    })
  ],
}

 cdk application stack

Look up the token and pass as a buildarg

import { execSync } from 'child_process';

const codeartifactToken = execSync(
  'aws codeartifact get-authorization-token --domain megabus --domain-owner 669431401787 --query authorizationToken --output text --region us-east-1',
  { encoding: 'utf8' },
).trim();

ecs.ContainerImage.fromAsset(
  pathToDockerfileDir,
  {
    buildArgs: { CODEARTIFACT_TOKEN: codeartifactToken }
  })