Use Cases

Claude Code × AWS CodePipeline/CodeBuild 完全指南 | 自动构建CI/CD流水线

使用Claude Code通过AWS CodePipeline和CodeBuild自动构建CI/CD。包含流水线设计、buildspec.yml生成、测试自动化、CDK基础设施定义的实战代码解说。

“GitHub Actions不就够了,为什么要用AWS CodePipeline?“——这是我经常被问到的问题。

答案在于与AWS资源的深度集成。推送到ECR、部署到ECS、更新CloudFormation栈——当这些都需要在AWS内部原生完成时,CodePipeline + CodeBuild的组合是最无缝的选择。

我在工作中管理着结合多个AWS服务的流水线,自从只需向Claude Code描述流水线需求,它就能一次性生成buildspec.yml、CDK代码和IAM策略之后,构建新流水线的时间缩短为原来的四分之一。


CodePipeline / CodeBuild 基本结构

CodePipeline(编排器)
    │
    ├─ Source阶段:  从GitHub / CodeCommit获取代码
    ├─ Build阶段:   使用CodeBuild进行构建、测试、创建Docker镜像
    ├─ Test阶段:    集成测试、安全扫描(可选)
    └─ Deploy阶段:  部署到ECS / Elastic Beanstalk / S3

CodeBuild执行buildspec.yml中描述的命令。可以把它理解为GitHub Actions中steps:的对应物。


第1步:自动生成buildspec.yml

claude -p "
按以下条件生成CodeBuild的buildspec.yml。

【构建内容】
- Node.js 20环境
- 使用npm ci安装
- TypeScript构建(npm run build)
- 运行单元测试(npm test)
- 构建Docker镜像并推送到ECR
- 镜像标签:CODEBUILD_RESOLVED_SOURCE_VERSION(Git SHA)
- 同时添加latest标签

【安全扫描】
- ECR镜像推送后用Trivy进行扫描
- 发现HIGH/CRITICAL漏洞则构建失败

【制品】
- 输出imagedefinitions.json(用于ECS部署)
"

生成的buildspec.yml:

version: 0.2

env:
  variables:
    AWS_DEFAULT_REGION: ap-northeast-1
    ECR_REPO_NAME: myapp
  parameter-store:
    ECR_REGISTRY: /myapp/ecr-registry

phases:
  install:
    runtime-versions:
      nodejs: 20
    commands:
      - echo "安装依赖..."
      - npm ci

  pre_build:
    commands:
      - echo "运行测试..."
      - npm test
      - echo "登录Amazon ECR..."
      - aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY
      - IMAGE_TAG=$CODEBUILD_RESOLVED_SOURCE_VERSION
      - IMAGE_URI=$ECR_REGISTRY/$ECR_REPO_NAME:$IMAGE_TAG

  build:
    commands:
      - echo "构建TypeScript..."
      - npm run build
      - echo "构建Docker镜像..."
      - docker build -t $IMAGE_URI -t $ECR_REGISTRY/$ECR_REPO_NAME:latest .

  post_build:
    commands:
      - echo "推送镜像到ECR..."
      - docker push $IMAGE_URI
      - docker push $ECR_REGISTRY/$ECR_REPO_NAME:latest
      - echo "扫描镜像漏洞..."
      - |
        docker run --rm \
          -v /var/run/docker.sock:/var/run/docker.sock \
          aquasec/trivy:latest image \
          --exit-code 1 \
          --severity HIGH,CRITICAL \
          $IMAGE_URI
      - echo "创建imagedefinitions.json..."
      - printf '[{"name":"app","imageUri":"%s"}]' $IMAGE_URI > imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json

reports:
  test-reports:
    files:
      - "coverage/junit.xml"
    file-format: JUNITXML

第2步:用CDK构建完整流水线

claude -p "
在lib/pipeline-stack.ts中用CDK TypeScript实现以下CodePipeline。

【流水线配置】
- Source:GitHub(owner/repo的main分支)
- Build:CodeBuild(使用上面的buildspec.yml)
- Deploy:ECS服务的蓝绿部署

【通知】
- 流水线失败时通过SNS → Slack通知
- 部署成功时也通知Slack

【制品存储】
- S3存储桶(启用加密和版本控制)
"
// lib/pipeline-stack.ts
import * as cdk from "aws-cdk-lib";
import * as codepipeline from "aws-cdk-lib/aws-codepipeline";
import * as codepipeline_actions from "aws-cdk-lib/aws-codepipeline-actions";
import * as codebuild from "aws-cdk-lib/aws-codebuild";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as iam from "aws-cdk-lib/aws-iam";
import * as sns from "aws-cdk-lib/aws-sns";

export class PipelineStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 制品存储S3存储桶
    const artifactBucket = new s3.Bucket(this, "ArtifactBucket", {
      versioned: true,
      encryption: s3.BucketEncryption.S3_MANAGED,
      removalPolicy: cdk.RemovalPolicy.RETAIN,
    });

    // 制品定义
    const sourceOutput = new codepipeline.Artifact("SourceOutput");
    const buildOutput = new codepipeline.Artifact("BuildOutput");

    // CodeBuild项目
    const buildProject = new codebuild.PipelineProject(this, "BuildProject", {
      buildSpec: codebuild.BuildSpec.fromSourceFilename("buildspec.yml"),
      environment: {
        buildImage: codebuild.LinuxBuildImage.STANDARD_7_0,
        privileged: true,  // Docker构建所必需
      },
      environmentVariables: {
        AWS_ACCOUNT_ID: { value: this.account },
      },
    });

    // 授予ECR访问权限
    buildProject.addToRolePolicy(new iam.PolicyStatement({
      actions: [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:PutImage",
        "ecr:InitiateLayerUpload",
        "ecr:UploadLayerPart",
        "ecr:CompleteLayerUpload",
      ],
      resources: ["*"],
    }));

    // 流水线
    const pipeline = new codepipeline.Pipeline(this, "Pipeline", {
      pipelineName: "myapp-pipeline",
      artifactBucket,
      stages: [
        {
          stageName: "Source",
          actions: [
            new codepipeline_actions.GitHubSourceAction({
              actionName: "GitHub_Source",
              owner: "your-org",
              repo: "your-repo",
              branch: "main",
              oauthToken: cdk.SecretValue.secretsManager("github-token"),
              output: sourceOutput,
            }),
          ],
        },
        {
          stageName: "Build",
          actions: [
            new codepipeline_actions.CodeBuildAction({
              actionName: "Build_and_Test",
              project: buildProject,
              input: sourceOutput,
              outputs: [buildOutput],
            }),
          ],
        },
        {
          stageName: "Deploy",
          actions: [
            new codepipeline_actions.EcsDeployAction({
              actionName: "Deploy_to_ECS",
              service: ecs.FargateService.fromFargateServiceAttributes(
                this, "EcsService", {
                  cluster: ecs.Cluster.fromClusterArn(
                    this, "Cluster",
                    `arn:aws:ecs:${this.region}:${this.account}:cluster/myapp-cluster`
                  ),
                  serviceName: "myapp-service",
                }
              ),
              input: buildOutput,
            }),
          ],
        },
      ],
    });

    // 失败通知
    const alertTopic = new sns.Topic(this, "AlertTopic");
    pipeline.notifyOnAnyStageStateChange("PipelineNotification", alertTopic, {
      events: [
        codepipeline.PipelineNotificationEvents.PIPELINE_EXECUTION_FAILED,
        codepipeline.PipelineNotificationEvents.PIPELINE_EXECUTION_SUCCEEDED,
      ],
    });
  }
}

第3步:配置测试结果报告

claude -p "
想在CodeBuild中将测试结果发送到CodeBuild Reports,
以便为每个PR查看质量报告。

- 测试框架:Vitest
- 覆盖率报告:Istanbul(lcov格式)
- 在buildspec.yml中添加reports部分
- 也用CDK定义报告组
"
# buildspec.yml的reports部分
reports:
  UnitTestResults:
    files:
      - "test-results/junit.xml"
    file-format: JUNITXML
  CodeCoverage:
    files:
      - "coverage/lcov.info"
    file-format: CLOVERXML

第4步:多环境流水线设计

claude -p "
用CDK设计3个环境的分阶段部署流水线:dev → staging → prod。

- dev:向main分支push时自动部署
- staging:dev部署成功后,经手动审批后部署
- prod:staging部署成功后,经手动审批后部署
- 各环境部署完成时通知Slack
"
// 为staging → prod添加手动审批门控
{
  stageName: "Approve_Staging",
  actions: [
    new codepipeline_actions.ManualApprovalAction({
      actionName: "Approve_Deploy_to_Staging",
      notificationTopic: alertTopic,
      additionalInformation: "批准部署到Staging吗?",
    }),
  ],
},
{
  stageName: "Deploy_Staging",
  actions: [
    new codepipeline_actions.EcsDeployAction({
      actionName: "Deploy_to_Staging",
      service: stagingService,
      input: buildOutput,
    }),
  ],
},

4个常见陷阱

1. 忘记CodeBuild中的privileged: true

构建Docker镜像需要privileged: true。没有这个设置会出现Cannot connect to the Docker daemon错误。

2. GitHub OAuth令牌权限不足

GitHub源需要repo权限范围。仅有public_repo不能用于私有仓库。

3. S3制品存储桶的区域

流水线和制品S3存储桶必须在同一区域。跨区域流水线需要额外配置。

4. ECS部署操作的imagedefinitions.json格式

ECS部署需要精确的格式:

[{"name": "容器名", "imageUri": "镜像URI"}]

容器名必须与任务定义中的容器名完全一致。


总结

任务Claude Code的贡献
buildspec.yml生成包含构建、测试、Docker和安全扫描一体生成
CDK流水线自动生成Source→Build→Deploy的全部阶段
多环境设计设计带手动审批门控的分阶段部署
测试报告自动化CodeBuild Reports配置

CodePipeline的配置看起来很复杂,但只需告诉Claude Code”我想要这样的流水线”,它就会一次性生成buildspec.yml和CDK代码。建议先从buildspec.yml开始尝试。

相关文章

参考资料

#claude-code #aws #codepipeline #codebuild #cicd #devops

让你的 Claude Code 工作流更上一层楼

50 个经过实战检验的提示词模板,现在就能复制粘贴到 Claude Code 中使用。

免费

免费 PDF:5 分钟看懂 Claude Code 速查表

只需留下邮箱,我们就会立即把这份 A4 一页速查表 PDF 发送给你。

我们会严格保护你的个人信息,绝不发送垃圾邮件。

Masa

本文作者

Masa

深度使用 Claude Code 的工程师。运营 claudecode-lab.com——一个涵盖 10 种语言、超过 2,000 页内容的科技媒体。