AWS CodeBuild
Managed build service — compiles code, runs tests, produces artifacts/Docker images. The build stage of the AWS-native CI/CD trio (CodePipeline orchestrates, CodeBuild builds, CodeDeploy deploys). Tier 3 for most backend roles — GitHub Actions / GitLab CI dominate the broader market — but relevant in AWS-native shops.
What it is
A fully managed build environment. You define the build steps in a buildspec.yml; CodeBuild spins up a container, runs the phases, and produces artifacts. No build servers to maintain.
# buildspec.yml
version: 0.2
phases:
install:
runtime-versions:
python: 3.12
commands:
- pip install -r requirements.txt
pre_build:
commands:
- pip install pytest ruff
- ruff check .
build:
commands:
- pytest --cov=app
- docker build -t $ECR_REPO:$CODEBUILD_RESOLVED_SOURCE_VERSION .
post_build:
commands:
- aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY
- docker push $ECR_REPO:$CODEBUILD_RESOLVED_SOURCE_VERSION
artifacts:
files:
- appspec.yml
- taskdef.json
Phases run in order: install → pre_build → build → post_build. A non-zero exit in any phase fails the build.
Build environment
- Runs in a Docker container — AWS-managed images (with common runtimes) or your own custom image from ECR.
- You pick compute size (CPU/memory); larger = faster builds = more cost per minute.
- Building Docker images needs privileged mode enabled on the project.
- Billed per build-minute — no idle cost (unlike a self-hosted Jenkins box).
IAM — the service role
CodeBuild assumes a service role for everything it does in your account: pull source, push to ECR, write logs to CloudWatch, read secrets. A common failure is a build that fails at docker push or secret retrieval because the service role is missing ecr:* or secretsmanager:GetSecretValue / kms:Decrypt.
Secrets in a build come from Secrets Manager / SSM Parameter Store referenced in the buildspec env section — never hardcoded.
Caching
Builds re-download dependencies every time unless you configure caching:
- S3 cache — cache
pip/npmdirectories or Docker layers to S3 between builds. - Local cache — cache on the build host (faster, but only helps if the same host is reused).
Without caching, every build re-runs pip install from scratch — slow and wasteful.
Where it fits — the AWS CI/CD trio
CodePipeline orchestrates the stages (source → build → deploy)
│
├─ Source: CodeCommit / GitHub / S3 — triggers the pipeline on commit
├─ Build: CodeBuild — buildspec.yml: test, lint, build image, push to ECR
└─ Deploy: CodeDeploy — rolls out to ECS / Lambda / EC2 (rolling, blue/green, canary)
- CodePipeline — the orchestrator; defines the stage graph.
- CodeBuild — the build/test stage.
- CodeDeploy — the deployment stage; handles deployment strategies and rollback.
CodeBuild vs GitHub Actions
| CodeBuild | GitHub Actions | |
|---|---|---|
| Hosting | AWS-managed | GitHub-managed (or self-hosted runners) |
| Config | buildspec.yml |
.github/workflows/*.yml |
| AWS credentials | service role (native) | GitHub OIDC → assume an IAM role |
| Ecosystem | AWS-centric | huge marketplace of actions |
| Best for | AWS-native shops, builds that need to live in the VPC | most teams — broader ecosystem, integrated with the repo |
For most teams, GitHub Actions (with OIDC federation to AWS — see ../../Security_Identity_and_Compliance/02_AWS_Identity_and_Access_Management/02_advanced_role_patterns.md) is the default. CodeBuild earns its place when builds need to run inside your VPC (access private resources during the build) or when you’re committed to the AWS-native pipeline.
Common gotchas
- Service role missing permissions — build fails at
docker push(noecr:*) or at secret retrieval (nosecretsmanager/kms:Decrypt). - No caching — every build re-downloads all dependencies; slow and costs build-minutes.
- Privileged mode not enabled —
docker buildfails inside the build container. - Secrets hardcoded in buildspec — reference Secrets Manager / SSM instead.
- Wrong phase for a command — a test in
installruns before dependencies are ready; understand the phase order.
Interview angle
- “What’s the AWS CI/CD trio?” — CodePipeline orchestrates stages, CodeBuild runs the build/test stage (
buildspec.yml), CodeDeploy handles deployment (rolling/blue-green/canary to ECS/Lambda/EC2). - “How does CodeBuild get permissions to push to ECR?” — its service role. The role needs
ecr:*(or scoped push permissions) plus CloudWatch Logs and any Secrets Manager / KMS access the build uses. Missing service-role permissions is the most common build failure. - “CodeBuild vs GitHub Actions?” — CodeBuild is AWS-managed, configured with
buildspec.yml, uses a service role natively, and can run inside your VPC. GitHub Actions has a much larger ecosystem and is integrated with the repo; with OIDC federation it gets AWS credentials without long-lived keys. Most teams use GitHub Actions; CodeBuild fits AWS-native shops or VPC-bound builds. - “How do you speed up a slow CodeBuild build?” — enable caching (S3 cache for
pip/npmdirs and Docker layers), use a larger compute size, and split independent steps. Without caching every build re-downloads all dependencies.