amazon-web-services - 以跨账户 CodeCommit 存储库作为源的 AWS 管道

标签 amazon-web-services aws-cloudformation aws-codepipeline aws-cdk aws-codecommit

我需要使用 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

我怎样才能创建它?

最佳答案

如果有人遇到同样的问题,我设法使用 CDK 来解决此问题 this example 。它已经过时了,但我应用了相同的逻辑。由于最近的变化,这个答案中提到的一些步骤可能是不必要的。我找到了一个更新的例子here ,但我还没有尝试过。

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

让我们通过 CodeCommit 存储库调用 ID_ACC_WITH_REPO 到 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
    }
});
  • 在 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);
    
  • 导入存储库。
  • const repo = codecommit.Repository.fromRepositoryArn(
      repoAccStack,
      'AppRepository',
      `arn:aws:codecommit:${REPO_REGION}:${ID_ACC_WITH_REPO}:${REPO_NAME}`
    );
    

    ACC_WITH_PIPELINE

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

    实际上,我在尝试创建 key 时遇到 kms.model.MalformedPolicyDocumentException 错误,因此我从 AWS 控制台手动执行此操作,然后使用 kms.Key.fromKeyArn< 导入它。我的帐户可能出了问题(在使用此解决方案之前我遇到了很多错误),但如果您遇到相同的错误,这是一个解决方法。只需确保为管道角色分配使用权限即可。

  • 使用之前创建的 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));
    
  • 创建管道并添加第 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:*', 'codecommit:*', 'kms:*');
    pipeline.addToRolePolicy(policy);
    
  • 使用第 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
        })
      ]
    });
    
  • 最后添加构建阶段
  • // 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 部署here对此进行了解释。 。但是,如果您尝试 cdk 部署“*”,则会出现另一个错误:需要对账户 ACCOUNT_ID 执行 AWS 调用,但当前凭证适用于 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"
    

    关于amazon-web-services - 以跨账户 CodeCommit 存储库作为源的 AWS 管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63602642/

    相关文章:

    java - AWS S3 Java SDK 不将文件复制到文件夹

    java - 将 AWS SageMaker 机器学习模型转换为 Java 库

    javascript - 延迟 AWS 代码管道 :

    amazon-s3 - 使用 CICD 管道的 cloudform 导入现有资源时 S3 访问被拒绝

    amazon-web-services - 仅当 lambda 发生任何更改时才使用 AWS Code Pipeline 执行云形成

    javascript - 在桌面应用程序上调用 AWS Lambda

    amazon-web-services - 来自不同 AWS 账户的 EC2 之间的区域数据传输费用

    amazon-web-services - 使用 CloudFormation 将证书附加到 ALB

    json - AWS Cloudformation-如何在 json/yaml 模板中处理字符串大写或小写

    amazon-web-services - 如何从 CF 中的另一个模板检索 secret 管理员名称?