-1

I'm building AWS CodePipelines for my project using TypeScript and cdk. I also have a CodeBuild project that I've created in one of the pipelines (Pipeline A) and I'd like to reuse it in a different pipeline (Pipeline B).

In Pipeline B I'm creating a link to this project as

const project = PipelineProject.fromProjectName(this, "SharedId", "SharedName");

Both pipelines were created successfully. When I'm running this in Pipeline A everything works. The problem is - when I'm running this project in Pipeline B, it fails with a message:

[Container] 2022/10/07 10:34:57 Waiting for DOWNLOAD_SOURCE
AccessDenied: Access Denied
    status code: 403, request id: QHRTGW90SXRHBRAD, host id: nTnocqc+T3RL6naDcEdDH+WOQ4RJfFekFGopZCPFvbcZEkXE8OxCS9slBjrnJl/k+w68ChuBoei1KtcGT1xWZA== for primary source and source version arn:aws:s3:::mypipeline-ia1llzrl9at8/SharedId/deployment/65uygTY

I've tried to add to the shared CodeBuild project's role permissions to s3, but no luck. In this case it fails with the message:

[Container] 2022/10/07 12:20:13 Waiting for DOWNLOAD_SOURCE
AccessDenied: The ciphertext refers to a customer master key that does not exist, does not exist in this region, or you are not allowed to access.
    status code: 403, request id: XQS9V45BHRGK3SBG, host id: //Jrj4Tb6aV1GMCwOE9mzA18Hc0En7299hcd4DgxoFD7l7O/QaDsgln8UMtqwfIV5o/RDKR+Aqc= for primary source and source version arn:aws:s3:::mypipeline-ia1llzrl9at8/SharedId/deployment/65uygTY

UPD: Then I've tried to add to the shared CodeBuild project's role permissions to kms key of the artifact from Pipeline B, but again no luck. I received the same error as above. The project's role is updated like this:

        testProject.role!.addToPrincipalPolicy(
            new PolicyStatement({
                effect: Effect.ALLOW,
                actions: [
                    "s3:GetObject*",
                    "s3:GetBucket*",
                    "s3:List*",
                ],
                resources: ["arn:aws:s3:::teststack*"],
            }),
        );
        testProject.role!.addToPrincipalPolicy(
            new PolicyStatement({
                effect: Effect.ALLOW,
                actions: [
                    "kms:Decrypt",
                    "kms:DescribeKey",
                    "kms:Encrypt",
                    "kms:ReEncrypt*",
                    "kms:GenerateDataKey*"
                ],
                resources: ["arn:aws:kms:us-east-1:413000313257:key/110e4489-3424-46e0-8783-09479cba82b5"]
            }),
        );

So my question is - how to properly setup permissions for this CodeBuild project so it could access input artifacts from both pipelines?

Gwen
  • 354
  • 1
  • 2
  • 10

1 Answers1

0

Ok. So finally I've figured out how to do this in general and what was the problem in my case.

When you create a pipeline's project using cdk it creates a bucket on S3 where an input artifact for this project is uploaded. The artifact is encrypted with a KMS key. The project's service role has permissions "kms:Decrypt" and "kms:DescribeKey" for this key and the key has permissions to allow these actions to the project's service role. It goes out of the box behind the hood of cdk.

Now you'd like to reuse the project in another pipeline. This new pipeline creates a different bucket on S3 with an input artifact. So you have to allow access to this bucket to the project. You can do this in cdk like

testProject.role!.addToPrincipalPolicy(
            new PolicyStatement({
                effect: Effect.ALLOW,
                actions: [
                    "s3:GetObject*",
                    "s3:GetBucket*",
                    "s3:List*",
                ],
                resources: ["arn:aws:s3:::teststack*"],
            }),
        );

The bucket is also encrypted with a KMS key (created by the new pipeline). So you have to grant permissions for this key to your project like

testProject.role!.addToPrincipalPolicy(
            new PolicyStatement({
                effect: Effect.ALLOW,
                actions: [
                    "kms:Decrypt",
                    "kms:DescribeKey"
                ],
                resources: ["arn:aws:kms:us-east-1:413000313257:key/<kms key from Pipeline B>"]
            }),
        );

And the very last step is to update the permissions of this new KMS key to allow project's service role (created in Pipeline A) to "kms:Decrypt" and "kms:DescribeKey" it. This last step I did manually and then everything started to work.

        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::413000313257:role/PipelineA-reusedProject-id"
            },
            "Action": [
                "kms:Decrypt",
                "kms:DescribeKey"
            ],
            "Resource": "*"
        },

Unfortunately I haven't found how it can be done using CDK as this key is created automatically and it seems there is no option to use some custom key to encrypt pipeline's artifacts.

Note During the investigation of this topic I made sure that it has no sense to reuse codebuild projects in pipelines. It's easier and with no harm to create as many projects for different pipelines as you want.

Gwen
  • 354
  • 1
  • 2
  • 10