question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[codepipeline] Error : Artifact Bucket must have a KMS Key to add cross-account action

See original GitHub issue

Reproduction Steps

Environment

  • **CLI Version :1.67
  • **Framework Version:1.67
  • Node.js Version: 14.4.0
  • **OS :Windows 10
  • Language (Version): TypeScript (4.0.3)

This is 🐛 Bug Report

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
skinny85commented, Oct 16, 2020

Yep, here’s your issue:

        const artifactBucket = Bucket.fromBucketArn(this, 'artifactBucket', pipelineArtifactBucketArn);

You’re importing the Bucket in the other Stack without a Key. Use fromBucketAttributes, passing the Key there, and everything will work.

Thanks, Adam

1reaction
VXConsultingcommented, Oct 15, 2020

Here is the creation script for the bucket and its encryption key in another stack.

    //Name of the bucket that will receive all the code package from XLRelease
    const bucketArtifactName = 'pipeline-artifact-bucket';

    //Encryption key for the BictbucketStore
    const keyName = `${bucketArtifactName}-encryptionkey`
    this.ArtifactBucketEncryptionKey = new Key(this, keyName, {
      description: 'EncryptionKey used by the main pipelines to access the content of the ' + bucketArtifactName,
      alias: keyName,
      trustAccountIdentities: true
    });

    //Bucket creation
    this.ArtifactBucket = new Bucket(this, bucketArtifactName, {
      blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
      encryptionKey: this.ArtifactBucketEncryptionKey,
      encryption: BucketEncryption.KMS,
      bucketName: bucketArtifactName,
      versioned: true,
      removalPolicy: RemovalPolicy.DESTROY
    });

    //Securing the bucket
    this.ArtifactBucket.addToResourcePolicy(new PolicyStatement({
      effect: Effect.DENY,
      principals: [new AnyPrincipal()],
      resources: [this.ArtifactBucket.bucketArn + '/*'],
      actions: ["s3:*"],
      conditions: {
        "Bool": {
          "aws:SecureTransport": false
        }
      }
    }));

    this.ArtifactBucket.addToResourcePolicy(new PolicyStatement({
      effect: Effect.DENY,
      principals: [new AnyPrincipal()],
      resources: [this.ArtifactBucket.bucketArn + '/*'],
      actions: ["s3:PutObject"],
      conditions: {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": "aws:kms"
        }
      }
    }));

    //Add permissions for the roles that will deploy the stack with cross-account mecanism
    //Give the pipeline the capability to deploy in destination accounts
    const integrationAccountId = Accounts.integration;
    const testAccountId = Accounts.test;
    const acceptanceAccountId = Accounts.acceptance;
    const productionAccountId = Accounts.production;

    //Assignement of the roles to deploy in the destination accounts
    const assetPrefix = 'devops';
    const integrationDevopRoleName = `${assetPrefix}-integration-devOpsRole`;
    const integrationChangeSetRoleName = `${assetPrefix}integration-changeSetRole`;
    const integrationDevOpsRole = Role.fromRoleArn(this, integrationDevopRoleName, `arn:aws:iam::${integrationAccountId}:role/DevOpsRole`);
    const integrationChangeSetRole = Role.fromRoleArn(this, integrationChangeSetRoleName, `arn:aws:iam::${integrationAccountId}:role/DevOpsChangeSetExecRole`);

    const testDevopRoleName = `${assetPrefix}-testDevOpsRole`;
    const testChangeSetRoleName = `${assetPrefix}-testChangeSetRole`;
    const testDevOpsRole = Role.fromRoleArn(this, testDevopRoleName, `arn:aws:iam::${testAccountId}:role/DevOpsRole`);
    const testChangeSetRole = Role.fromRoleArn(this, testChangeSetRoleName, `arn:aws:iam::${testAccountId}:role/DevOpsChangeSetExecRole`);

    const devopRoleName = `${assetPrefix}-acceptanceDevOpsRole`;
    const changeSetRoleName = `${assetPrefix}-acceptanceChangeSetRole`;
    const acceptanceDevOpsRole = Role.fromRoleArn(this, devopRoleName, `arn:aws:iam::${acceptanceAccountId}:role/DevOpsRole`);
    const acceptanceChangeSetRole = Role.fromRoleArn(this, changeSetRoleName, `arn:aws:iam::${acceptanceAccountId}:role/DevOpsChangeSetExecRole`);

    const productionDevopRoleName = assetPrefix + '-productionDevOpsRole';
    const productionChangeSetRoleName = assetPrefix + '-productionChangeSetRole';
    const productionDevOpsRole = Role.fromRoleArn(this, productionDevopRoleName, `arn:aws:iam::${productionAccountId}:role/DevOpsRole`);
    const productionChangeSetRole = Role.fromRoleArn(this, productionChangeSetRoleName, `arn:aws:iam::${productionAccountId}:role/DevOpsChangeSetExecRole`);

    this.ArtifactBucket.grantRead(new ArnPrincipal(integrationDevOpsRole.roleArn));
    this.ArtifactBucket.grantRead(new ArnPrincipal(integrationChangeSetRole.roleArn));

    this.ArtifactBucket.grantRead(new ArnPrincipal(testDevOpsRole.roleArn));
    this.ArtifactBucket.grantRead(new ArnPrincipal(testChangeSetRole.roleArn));

    this.ArtifactBucket.grantRead(new ArnPrincipal(acceptanceDevOpsRole.roleArn));
    this.ArtifactBucket.grantRead(new ArnPrincipal(acceptanceChangeSetRole.roleArn));

    this.ArtifactBucket.grantRead(new ArnPrincipal(productionDevOpsRole.roleArn));
    this.ArtifactBucket.grantRead(new ArnPrincipal(productionChangeSetRole.roleArn));

    this.ArtifactBucketEncryptionKey.addToResourcePolicy(new PolicyStatement({
      effect: Effect.ALLOW,
      principals: [
        new ArnPrincipal(integrationDevOpsRole.roleArn),
        new ArnPrincipal(integrationChangeSetRole.roleArn),
        new ArnPrincipal(testDevOpsRole.roleArn),
        new ArnPrincipal(testChangeSetRole.roleArn),
        new ArnPrincipal(acceptanceDevOpsRole.roleArn),
        new ArnPrincipal(acceptanceChangeSetRole.roleArn),
        new ArnPrincipal(productionDevOpsRole.roleArn),
        new ArnPrincipal(productionChangeSetRole.roleArn)],
      resources: ['*'],
      actions: [
        "kms:Decrypt",
        "kms:DescribeKey"
      ]
    }));

    this.ArtifactBucket.addToResourcePolicy(new PolicyStatement({
      effect: Effect.DENY,
      principals: [new AnyPrincipal()],
      resources: [this.ArtifactBucket.bucketArn + '/*'],
      actions: ["s3:*"],
      conditions: {
        "Bool": {
          "aws:SecureTransport": false
        }
      }
    }));

    this.ArtifactBucket.addToResourcePolicy(new PolicyStatement({
      effect: Effect.DENY,
      principals: [new AnyPrincipal()],
      resources: [this.ArtifactBucket.bucketArn + '/*'],
      actions: ["s3:PutObject"],
      conditions: {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": "aws:kms"
        }
      }
    }));

    new CfnOutput(this, `${keyName}Arn`, {
      description: `encryption key Arn artifact files Bucket`,
      exportName: `${keyName}Arn`,
      value: this.ArtifactBucketEncryptionKey.keyArn,
    });

    new CfnOutput(this, `${bucketArtifactName}Arn`, {
      description: `artifact files Bucket Arn`,
      exportName: `${bucketArtifactName}Arn`,
      value: this.ArtifactBucket.bucketArn,
    });
Read more comments on GitHub >

github_iconTop Results From Across the Web

Create a pipeline in CodePipeline that uses resources from ...
Step 1: Set up account policies and roles. After you create the AWS KMS key, you must create and attach policies that will...
Read more >
Why codepipline require the KMS key? - Stack Overflow
Data in CodePipeline is encrypted at rest using AWS KMS keys. Code artifacts are stored in a customer-owned S3 bucket and encrypted with...
Read more >
@aws-cdk/aws-codepipeline - npm
Customer Master Key (CMK) for you to encrypt the artifacts in the artifact bucket, which incurs a cost of $1/month. This default configuration ......
Read more >
Building a cross-account CI/CD pipeline - AWS Workshop Studio
It also configures the S3 bucket to be accessed from a different AWS account, and the AWS Key Management Service (KMS) key to...
Read more >
CDK Pipelines - Go Packages
Pipeline `field:"optional" json:"codePipeline" yaml:"codePipeline"` // Create KMS keys for the artifact buckets, allowing cross-account deployments.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found