aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.47k stars 3.83k forks source link

pipelines: can't add additional policies for the CodePipelineActionRole with provided artifactBucket and kms key #30360

Open pahud opened 3 months ago

pahud commented 3 months ago

Describe the bug

when an existing artifactBucket is provided with existing kms key for the pipeline, CDK would not add correct policy for the role to generate the data key and is having the error:

[GitHub] Upload to S3 failed with the following error: User: arn:aws:sts::XXXXXXXXXXXX:assumed-role/PipelineStack-PipelineSource/XXXXXXXXX is not authorized to perform: kms:GenerateDataKey on resource: arn:aws:kms:eu-west-2:XXXXXXXXXXXX:key/20dd7b78-20f8-4723-a9ea-be8f8e54e339 because no identity-based policy allows the kms:GenerateDataKey action.

Consider this sample:

export class MyDummyPipeline extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const connection = pipelines.CodePipelineSource.connection('pahud/empty', 'main', {
      connectionArn,
    });

    const importedKey = kms.Alias.fromAliasName(this, "CdkPipelineKey", "alias/cdk-pipeline-key");

    const artifactBucket = s3.Bucket.fromBucketAttributes(this, "CdkPipelineArtifactBucket", {
      bucketName: 'my-bucket',
      encryptionKey: importedKey,
    },
  )

    const mypipeline = new pipelines.CodePipeline(this, 'MyPipeline', {
        artifactBucket,
        synth: new pipelines.CodeBuildStep("Synth", {
          input: connection,
          commands: ['ls'],
        }),
    });

  }

We got this in the synthesized iam policy

    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - s3:Abort*
              - s3:DeleteObject*
              - s3:GetBucket*
              - s3:GetObject*
              - s3:List*
              - s3:PutObject
              - s3:PutObjectLegalHold
              - s3:PutObjectRetention
              - s3:PutObjectTagging
              - s3:PutObjectVersionTagging
            Effect: Allow
            Resource:
              - arn:aws:s3:::my-bucket
              - arn:aws:s3:::my-bucket/*
          - Action: sts:AssumeRole
            Effect: Allow
            Resource:
              - Fn::GetAtt:
                  - MyPipelineCodeBuildActionRole1AA6A14D
                  - Arn
              - Fn::GetAtt:
                  - MyPipelineSourcepahudemptyCodePipelineActionRole4F9E74DC
                  - Arn

A temp workaround is to use Aspect:

class MyAspect implements IAspect {
    public visit(node: IConstruct): void {
        if (node.node.id === 'CodePipelineActionRole') {
            const roleArn = (node as iam.Role).roleArn;
            const stack = Stack.of(node);
            const importedKey = kms.Alias.fromAliasName(stack, "MyCdkPipelineKey", "alias/cdk-pipeline-key");
            new iam.Policy(stack, 'CustomPolicy', {
                roles: [ iam.Role.fromRoleArn(stack, 'role', roleArn )],
                statements: [
                    new iam.PolicyStatement({
                        actions: ['kms:GenerateDataKey'],
                        resources: [importedKey.keyArn],
                    })
                ]
            })
        }
    }
}

Expected Behavior

CDK should render correct policies or allow users to add additional policies for it.

Current Behavior

missing required policies

Reproduction Steps

see description

Possible Solution

using Aspect

Additional Information/Context

No response

CDK CLI Version

all

Framework Version

No response

Node.js Version

all

OS

all

Language

TypeScript

Language Version

No response

Other information

No response

pahud commented 3 months ago

internal tracking: V1395397915