Claude
Skills
Sign in
Back

aws-codepipeline-codebuild

Included with Lifetime
$97 forever

Authors and debugs AWS CodePipeline + CodeBuild workflows — pipeline v1 vs v2 (triggers, variables), source providers via CodeStar Connections, artifact handoff, buildspec.yml authoring, IAM service roles, ECR pull permissions, VPC build environments, S3/local caching strategies, Lambda invoke action callback pattern, and manual approval setup. Use when working with AWS CodePipeline, AWS CodeBuild, buildspec.yml, CodeStar Connections, pipeline service roles, build VPC config, or "CodeBuild can't pull image" / "Lambda action hangs" debugging.

Image & Video

What this skill does


# AWS CodePipeline + CodeBuild

These two services are tightly coupled in practice: CodePipeline orchestrates stages, CodeBuild does the build action. Most friction lives at the boundary (artifact handoff, IAM roles, source authentication).

## When to invoke

**Symptoms:**

- CodeBuild fails immediately with `CannotPullContainerError: pull access denied` for an ECR image.
- A Lambda invoke action in CodePipeline hangs for 30+ minutes even though the function returns quickly.
- `npm ci` / `pip install` / Maven dependency resolution dominates build time and the configured cache isn't helping.
- The source action shows OAuth-style GitHub auth and we want to migrate to the modern GitHub App.
- Cross-account deploy stage fails with assume-role errors.
- Build succeeds but the next stage receives empty / missing artifacts.
- A `buildspec.yml` referenced in CodeBuild silently runs without env vars from Parameter Store / Secrets Manager.
- Pipeline service role attached an AWS-managed policy and we want to scope it down.

## Cross-cutting rules

1. **Always set `imagePullCredentialsType` explicitly when using ECR base images.** Default (`CODEBUILD`) requires an ECR repository policy trusting `codebuild.amazonaws.com`. Setting `SERVICE_ROLE` pulls under the project's IAM role — usually what you want. See [ECR base images](#ecr-base-images).
2. **Lambda actions are async from CodePipeline's perspective.** The Lambda MUST call `PutJobSuccessResult` / `PutJobFailureResult` before returning. Returning is not signaling. See [Lambda invoke action](#lambda-invoke-action).
3. **Never edit `buildspec.yml` and the source CodeBuild project's `buildspec` field at the same time** — one shadows the other. The inline `buildspec` field on the project (when set) overrides the file in source. Pick one; document which.
4. **Pipeline service role and CodeBuild service role are different roles.** Pipeline's role does NOT confer permissions on the build. Each build action has its own service role, set on the CodeBuild project (NOT the pipeline action).
5. **Artifact bucket is encrypted by default.** Cross-account artifact reads require the destination account's role to have decrypt access on the source account's KMS key — and the key policy must grant cross-account use. Symptom of missing this: `AccessDenied` on artifact download even when bucket policy looks correct.

## CodePipeline v1 vs v2

Two pipeline types coexist. `pipelineType: V1` is the original; `V2` adds capabilities that often warrant upgrading.

| Feature | V1 | V2 |
|---|---|---|
| Pipeline triggers with filters (branch, tag, file path) | No — runs on every source change | Yes — `triggers` block with `gitConfiguration` filters |
| Pipeline-level variables (resolved at start, passed to actions) | No | Yes — `variables` block |
| Parallel actions in same stage | Yes (in both) | Yes |
| Queued execution mode | No (replaces in-flight) | Yes (`executionMode: QUEUED`) |
| Action types | All | All |
| Pricing | Per active pipeline-month | Per action-execution-minute (often cheaper for low-traffic, more for high) |

**Upgrade path:** there is no in-place V1 → V2 conversion. Create a new pipeline with `pipelineType: V2`, point at the same source, retire the V1 once parallel-run validates. Existing V1 pipelines continue to work.

**When V2 is worth it:**
- You're triggering one pipeline from many branches and want per-branch filtering — V2 triggers eliminate the "one pipeline per branch" anti-pattern.
- You want to pass a commit SHA or PR number through multiple stages as a variable.
- You want PR-specific pipelines (V2's pull request triggers).

**When V1 is fine:** simple "build on main push, deploy to prod" pipelines with no per-branch logic.

## Source providers

| Provider | Use | Notes |
|---|---|---|
| **CodeConnections** (GitHub, Bitbucket, GitLab) | Default for third-party Git | GitHub App, modern. Action type: `CodeStarSourceConnection` (action name retained the original branding). |
| GitHub via OAuth token | Legacy | Deprecated. New pipelines should not use it. |
| S3 | Drop-zip-into-bucket triggers | `pollForSourceChanges: false` + S3 event notifications via CloudWatch. |
| CodeCommit | Internal AWS Git | **Deprecated for new accounts as of 2024-07.** Existing customers keep access; do not adopt for greenfield. |
| ECR (image push triggers pipeline) | Container-as-source | `pipelineType: V2` recommended for image tag filters. |

### CodeConnections setup

> Naming: AWS renamed CodeStar Connections → CodeConnections in late 2023. The CLI (`aws codestar-connections ...`), ARN namespace (`arn:aws:codestar-connections:...`), IAM action (`codestar-connections:UseConnection`), and pipeline action provider (`CodeStarSourceConnection`) all kept their original names for backward compatibility. New `aws codeconnections` CLI commands also work. Either form is valid.

Connection is a separate account-level resource (Console → Developer Tools → Settings → Connections, or `aws codestar-connections create-connection`). The first-time flow requires browser-based authorization by a GitHub org admin — there's no purely API path.

Once created, the connection ARN is reused across pipelines. In the source action:

```yaml
# (CloudFormation snippet)
- Name: Source
  ActionTypeId:
    Category: Source
    Owner: AWS
    Provider: CodeStarSourceConnection
    Version: '1'
  Configuration:
    ConnectionArn: arn:aws:codestar-connections:us-east-1:1234:connection/abc-def
    FullRepositoryId: my-org/my-repo
    BranchName: main
    DetectChanges: 'true'
  OutputArtifacts:
    - Name: SourceArtifact
```

Pipeline service role needs `codestar-connections:UseConnection` on the connection ARN.

## Artifact handoff

Every action declares `InputArtifacts` and/or `OutputArtifacts` by name. The pipeline ships artifacts via a versioned S3 bucket (set at the pipeline level: `artifactStore.location` and `artifactStore.encryptionKey`).

**The primary-artifact rule:**

A build action emits ONE primary output artifact. The buildspec's `artifacts` block defines what's in it:

```yaml
# buildspec.yml
artifacts:
  files:
    - '**/*'
  base-directory: dist
  discard-paths: no
```

For multi-artifact builds, use `secondary-artifacts`:

```yaml
artifacts:
  secondary-artifacts:
    app:
      files: ['**/*']
      base-directory: dist
    config:
      files: ['*.yml']
      base-directory: config
```

In the CodePipeline build action, map each secondary artifact name to a named output:

```yaml
OutputArtifacts:
  - Name: AppArtifact     # maps to 'app' from buildspec
  - Name: ConfigArtifact  # maps to 'config'
```

Without `secondary-artifacts`, the entire `artifacts.files` set goes to the primary output artifact. Common trap: `files: ['**/*']` with no `base-directory` includes `node_modules` — huge artifact, slow handoff.

**Cross-account artifact reads:**

When stage N is in account A and stage N+1 is in account B (cross-account deploy pattern), B must have:

1. IAM role in B that trusts A's pipeline role.
2. KMS key permissions on A's encryption key — A's key policy must allow B's role to `kms:Decrypt`.
3. Bucket policy on A's artifact bucket allowing B's role to read.

Forgetting (2) is the most common cause of `AccessDenied` errors that look like bucket-policy issues.

## buildspec.yml essentials

Current version is `0.2`. The shape:

```yaml
version: 0.2

env:
  variables:
    NODE_ENV: production
  parameter-store:
    DB_PASSWORD: /prod/db/password         # Parameter Store name
  secrets-manager:
    API_KEY: prod/api:apikey               # SecretId:JSONKey
  exported-variables:
    - GIT_SHA                              # exposed to downstream pipeline actions

phases:
  install:
    runtime-versions:
      nodejs: 20
      python: 3.11
    commands:
      - npm ci
  pre_build:
    on-failure: ABORT                      # ABORT (default) | CONTINUE
    commands:
      - export GIT_SHA=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | head -c 8)

Related in Image & Video