Use Cases

Claude Code × AWS CodePipeline/CodeBuild Complete Guide | Automate CI/CD Pipeline Build

Automatically build CI/CD with AWS CodePipeline & CodeBuild using Claude Code. Real code examples for pipeline design, buildspec.yml generation, test automation, and CDK infrastructure.

“Why bother with AWS CodePipeline when GitHub Actions works fine?”—a question I hear all the time.

The answer lies in deep integration with AWS resources. Pushing to ECR, deploying to ECS, updating CloudFormation stacks—when you want all of this to work natively within AWS, CodePipeline + CodeBuild is the most seamless combination.

I manage pipelines that combine multiple AWS services at work, and ever since Claude Code started generating buildspec.yml, CDK code, and IAM policies all at once just from describing my pipeline requirements, the time to build new pipelines has dropped to one-quarter of what it used to be.


Basic Structure of CodePipeline / CodeBuild

CodePipeline (Orchestrator)
    │
    ├─ Source Stage:  Fetch code from GitHub / CodeCommit
    ├─ Build Stage:   Build, test, create Docker images with CodeBuild
    ├─ Test Stage:    Integration tests, security scans (optional)
    └─ Deploy Stage:  Deploy to ECS / Elastic Beanstalk / S3

CodeBuild executes commands written in buildspec.yml. Think of it as the equivalent of steps: in GitHub Actions.


Step 1: Auto-Generate buildspec.yml

claude -p "
Generate a buildspec.yml for CodeBuild with the following requirements.

[Build Contents]
- Node.js 20 environment
- Install with npm ci
- TypeScript build (npm run build)
- Run unit tests (npm test)
- Build Docker image and push to ECR
- Image tag: CODEBUILD_RESOLVED_SOURCE_VERSION (Git SHA)
- Also attach latest tag simultaneously

[Security Scan]
- Run Trivy scan after ECR image push
- Fail build if HIGH/CRITICAL vulnerabilities found

[Artifacts]
- Output imagedefinitions.json (for ECS deploy)
"

Generated buildspec.yml:

version: 0.2

env:
  variables:
    AWS_DEFAULT_REGION: us-east-1
    ECR_REPO_NAME: myapp
  parameter-store:
    ECR_REGISTRY: /myapp/ecr-registry

phases:
  install:
    runtime-versions:
      nodejs: 20
    commands:
      - echo "Installing dependencies..."
      - npm ci

  pre_build:
    commands:
      - echo "Running tests..."
      - npm test
      - echo "Logging in to 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 "Building TypeScript..."
      - npm run build
      - echo "Building Docker image..."
      - docker build -t $IMAGE_URI -t $ECR_REGISTRY/$ECR_REPO_NAME:latest .

  post_build:
    commands:
      - echo "Pushing image to ECR..."
      - docker push $IMAGE_URI
      - docker push $ECR_REGISTRY/$ECR_REPO_NAME:latest
      - echo "Scanning image for vulnerabilities..."
      - |
        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 "Creating 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

Step 2: Build the Entire Pipeline with CDK

claude -p "
Implement the following CodePipeline in CDK TypeScript in lib/pipeline-stack.ts.

[Pipeline Configuration]
- Source: GitHub (main branch of owner/repo)
- Build: CodeBuild (using buildspec.yml above)
- Deploy: Blue/Green deployment to ECS service

[Notifications]
- Notify Slack via SNS on pipeline failure
- Also notify Slack on successful deployment

[Artifact Store]
- S3 bucket (encryption and versioning enabled)
"
// 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);

    // Artifact store S3 bucket
    const artifactBucket = new s3.Bucket(this, "ArtifactBucket", {
      versioned: true,
      encryption: s3.BucketEncryption.S3_MANAGED,
      removalPolicy: cdk.RemovalPolicy.RETAIN,
    });

    // Artifact definitions
    const sourceOutput = new codepipeline.Artifact("SourceOutput");
    const buildOutput = new codepipeline.Artifact("BuildOutput");

    // CodeBuild project
    const buildProject = new codebuild.PipelineProject(this, "BuildProject", {
      buildSpec: codebuild.BuildSpec.fromSourceFilename("buildspec.yml"),
      environment: {
        buildImage: codebuild.LinuxBuildImage.STANDARD_7_0,
        privileged: true,  // Required for Docker builds
      },
      environmentVariables: {
        AWS_ACCOUNT_ID: { value: this.account },
      },
    });

    // Grant ECR access permissions
    buildProject.addToRolePolicy(new iam.PolicyStatement({
      actions: [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:PutImage",
        "ecr:InitiateLayerUpload",
        "ecr:UploadLayerPart",
        "ecr:CompleteLayerUpload",
      ],
      resources: ["*"],
    }));

    // Pipeline
    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,
            }),
          ],
        },
      ],
    });

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

Step 3: Configure Test Result Reports

claude -p "
I want to send test results to CodeBuild Reports in CodeBuild
so I can check quality reports per PR.

- Test framework: Vitest
- Coverage report: Istanbul (lcov format)
- Add reports section to buildspec.yml
- Also define report group with CDK
"
# buildspec.yml reports section
reports:
  UnitTestResults:
    files:
      - "test-results/junit.xml"
    file-format: JUNITXML
  CodeCoverage:
    files:
      - "coverage/lcov.info"
    file-format: CLOVERXML

Step 4: Multi-Environment Pipeline Design

claude -p "
Design a CDK staged deployment pipeline for 3 environments: dev → staging → prod.

- dev: auto-deploy on push to main branch
- staging: deploy after dev succeeds, with manual approval
- prod: deploy after staging succeeds, with manual approval
- Notify Slack when each environment deployment completes
"
// Add manual approval gates for staging → prod
{
  stageName: "Approve_Staging",
  actions: [
    new codepipeline_actions.ManualApprovalAction({
      actionName: "Approve_Deploy_to_Staging",
      notificationTopic: alertTopic,
      additionalInformation: "Do you approve deployment to Staging?",
    }),
  ],
},
{
  stageName: "Deploy_Staging",
  actions: [
    new codepipeline_actions.EcsDeployAction({
      actionName: "Deploy_to_Staging",
      service: stagingService,
      input: buildOutput,
    }),
  ],
},

4 Common Pitfalls

1. Forgetting privileged: true in CodeBuild

Building Docker images requires privileged: true. Without it, you’ll get Cannot connect to the Docker daemon errors.

2. Insufficient GitHub OAuth Token Permissions

The GitHub source requires the repo scope. Using only public_repo won’t work for private repositories.

3. S3 Artifact Bucket Region

The pipeline and the artifact S3 bucket must be in the same region. Cross-region pipelines require additional configuration.

4. imagedefinitions.json Format for ECS Deploy Action

ECS deployment requires the exact format:

[{"name": "container-name", "imageUri": "image-uri"}]

The container name must exactly match the container name in the task definition.


Summary

TaskClaude Code’s Contribution
buildspec.yml generationGenerated with build, test, Docker, and security scan included
CDK PipelineAuto-generates all stages from Source→Build→Deploy
Multi-environment designDesigns staged deployment with manual approval gates
Test reportsAutomates CodeBuild Reports configuration

CodePipeline configuration may look complex, but just tell Claude Code “I want this kind of pipeline” and it will produce both buildspec.yml and CDK code in one shot. Start by trying it with buildspec.yml first.

References

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

Level up your Claude Code workflow

50 battle-tested prompt templates you can copy-paste into Claude Code right now.

Free

Free PDF: Claude Code Cheatsheet in 5 Minutes

Just enter your email and we'll send you the single-page A4 cheatsheet right away.

We handle your data with care and never send spam.

Masa

About the Author

Masa

Engineer obsessed with Claude Code. Runs claudecode-lab.com, a 10-language tech media with 2,000+ pages.