跨账户CodeCommit存储库作为源的AWS管道 重要提示:请确保两个帐户中的资源位于同一区域 ACC_WITH_REPO ACC_WITH_PIPELINE

问题描述

我需要使用CDK创建一个管道,该管道将基于CodeCommit存储库中的分支触发CloudFormation中的部署。如果CodeCommit存储库与管道位于同一帐户中,我将使用类似以下内容:

const codecommitRepo = codecommit.Repository.fromRepositoryName(
  this,'AppRepository','REPO_NAME'
);

pipeline.addStage({
  stageName: 'Source',actions: [
    new codepipeline_actions.CodeCommitSourceAction({
      actionName: 'Source',repository: codecommitRepo,branch: 'BRANCH_NAME',output: sourceArtifact,}),],});

但是,如果CodeCommit存储库位于另一个帐户中怎么办?

我要重新创建的架构类似于this article(下图)中所示的架构,但是具有CDK和CloudFormation。

aws-architecture

如何创建它?

解决方法

CodePipeline(CP)都在同一帐户中时,它们会通过 CloudWatch Event规则由CC触发:

CC ---> CW Event rule ---> CP

要在整个帐户中进行此操作,您必须调整CW事件。即,CC帐户中的CW事件规则必须将事件转发到CP帐户中的CW事件:

CP ---> CW Event rule ---> CW Event bus in CP acc ---> CW rule --> CP 

我没有适合您的代码,但这是应该做的。您提供的链接提供了该体系结构的更多详细信息。

我猜想在使用CDK时,您将必须“手动”创建所有CW事件规则,因为通常这不是开箱即用的事情。

,

如果有人遇到相同的问题,我可以通过this example用CDK来解决。它已经过时,但我采用了相同的逻辑。由于最近的更改,此答案中提到的某些步骤可能不是必需的。我找到了最近的示例here,但是我还没有尝试过。

重要提示:请确保两个帐户中的资源位于同一区域。

让我们将ID_ACC_WITH_REPO调用具有CodeCommit存储库的AWS账户ID,并将ID_ACC_WITH_PIPELINE调用具有管道以及我们要在其中部署架构的账户ID。

管道的CDK代码

ACC_WITH_REPO

  1. 在ID_ACC_WITH_REPO中创建堆栈。必须指定区域 ,因为跨帐户渠道需要该区域。
const repoAccStack = new cdk.Stack(app,'RepoAccStack',{
    env: {
        account: ID_ACC_WITH_REPO,region: REPO_REGION
    }
});
  1. 在ACC_WITH_REPO中创建一个跨帐户角色,并附加S3(用于存储工件),CodeCommit和KMS(加密)的完全访问策略。该角色将由ACC_WITH_PIPELINE中的管道以及源阶段中的CodeCommit源操作使用。我想您可以进一步限制它们,以提高安全性。
// Create role
const crossAccRole = new iam.Role(repoAccStack,'OtherAccRole',{
    roleName: 'CrossAccountRole',assumedBy: new iam.AccountPrincipal(pipelineAcc),});

// Attach policies
const policy = new iam.PolicyStatement();
policy.addAllResources();
policy.addActions('s3:*','codecommit:*','kms:*');
crossAccRole.addToPolicy(policy);
  1. 导入存储库。
const repo = codecommit.Repository.fromRepositoryArn(
  repoAccStack,'AppRepository',`arn:aws:codecommit:${REPO_REGION}:${ID_ACC_WITH_REPO}:${REPO_NAME}`
);

ACC_WITH_PIPELINE

  1. 在ID_ACC_WITH_PIPELINE中为管道创建堆栈。
const pipelineAccStack = new cdk.Stack(app,'PipelineAccStack',{
    env: {
        account: ID_ACC_WITH_PIPELINE,region: REGION_WITH_PIPELINE
    }
});
  1. 创建KMS密钥。该示例中使用的方法EncryptionKey已过时,请改用Key
const key = new kms.Key(pipelineAccStack,'CrossAccountKmsKey');

实际上,尝试创建密钥时出现了kms.model.MalformedPolicyDocumentException错误,因此我是从AWS控制台手动完成的,然后使用kms.Key.fromKeyArn进行了导入。我的帐户可能做错了什么(在使用此解决方案之前,我有很多错误),但是如果遇到同样的错误,这是一种解决方法。只需确保将使用权限分配给管道角色即可。

  1. 使用之前创建的KMS在ACC_WITH_PIPELINE中创建S3存储桶。桶名称是必需的。该示例中使用的HackyIdentity是不必要的,该类实现中使用的几种方法现已弃用。
const artifactsBucket = new s3.Bucket(pipelineAccStack,"ArtifactsBucket",{
    bucketName: BUCKET_NAME,encryptionKey: key,encryption: s3.BucketEncryption.KMS
});

artifactsBucket.grantReadWrite(new iam.ArnPrincipal(crossAccRole.roleArn));
  1. 创建管道并添加在第5步中创建的跨帐户角色。
// Create pipeline
const pipeline = new codepipeline.Pipeline(pipelineAccStack,'Pipeline',{
    pipelineName: 'CrossAccountPipeline',artifactBucket: artifactsBucket
});

// Add cross-account role
const policy = new iam.PolicyStatement();
policy.addResources(crossAccRole.roleArn)
policy.addActions('s3:*','kms:*');
pipeline.addToRolePolicy(policy);
  1. 使用在步骤3中导入的CodeCommit存储库将源阶段添加到管道中。
// Create artifact for source code
const sourceArtifact = new codepipeline.Artifact();

// Create source stage with role
pipeline.addStage({
  stageName: 'Source',actions: [
    new codepipeline_actions.CodeCommitSourceAction({
      actionName: 'CodeCommit_Source',repository: repo,output: sourceArtifact,branch: 'dev',role: crossAccRole
    })
  ]
});
  1. 最后添加构建阶段
// Create CodeBuild project
const buildProject = new codebuild.PipelineProject(this,'Build',{
  environment: { buildImage: codebuild.LinuxBuildImage.AMAZON_LINUX_2_2 }
});

// Create artifact for build
const buildArtifact = new codepipeline.Artifact();

// Add build stage
pipeline.addStage({
  stageName: 'Build',actions: [
    new codepipeline_actions.CodeBuildAction({
      actionName: 'Build',project: buildProject,input: sourceArtifact,outputs: [buildArtifact],}),],});

部署

当CDK应用程序包含多个堆栈时,您不仅会cdk deployhere中对此进行了说明。但是,如果您尝试cdk deploy '*',则会出现另一个错误:Need to perform AWS calls for account ACCOUNT_ID,but the current credentials are for ACCOUNT_ID

我设法用cdk deploy -e部署堆栈,并用aws configure切换帐户。 一共有三叠,而不是两叠。 CDK自动生成EventBusPolicy堆栈,以创建事件总线。 CDK在PipelineAccStack和RepoAccStack中添加了其他两个事件(也自动)。 Marcin的答案说明了如何配置跨帐户事件。应该在ACC_WITH_PIPELINE中创建EventBusPolicy堆栈。要获取堆栈的确切名称,请使用cdk list

考虑到所有这些因素,在此示例中,我将部署:

# with aws configure in ACC_WITH_PIPELINE
cdk deploy -e "PipelineAccStack"
cdk deploy -e "EventBusPolicy-$ID_ACC_WITH_REPO-$REGION-$ID_ACC_WITH_PIPELINE"

# switch aws configure to ACC_WITH_REPO
cdk deploy -e "RepoAccStack"

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...