AWS CodeBuild
Core concept: CodeBuild is a fully managed continuous integration service β no Jenkins servers to maintain.
buildspec.yml Reference
version: 0.2
run-as: root
env:
variables: # Plaintext env vars (visible in console)
JAVA_HOME: "/usr/lib/jvm/java-17"
parameter-store: # Fetched from SSM at build start
DB_URL: "/prod/myapp/db-url"
secrets-manager: # Fetched from Secrets Manager at build start
DB_PASSWORD: "prod/myapp/db:password"
API_KEY: "prod/myapp/api-key:key"
exported-variables: # Available to downstream CodePipeline stages
- IMAGE_TAG
phases:
install:
runtime-versions:
java: corretto17
commands:
- echo "Installing tools..."
pre_build:
commands:
- echo "Logging in to ECR..."
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login ...
- export IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
build:
commands:
- echo "Build started on `date`"
- mvn clean verify # Compile + test + package
- docker build -t my-app:$IMAGE_TAG .
post_build:
on-failure: ABORT # ABORT or CONTINUE
commands:
- echo "Pushing image..."
- docker push $ECR_REPO:$IMAGE_TAG
- printf '[{"name":"app","imageUri":"%s"}]' $ECR_REPO:$IMAGE_TAG > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
- appspec.yaml
- taskdef.json
name: BuildOutput
secondary-artifacts:
TestReports:
files:
- target/surefire-reports/**/*.xml
discard-paths: no
reports:
SurefireReports:
files:
- "target/surefire-reports/**/*.xml"
file-format: JUNITXML
discard-paths: no
cache:
paths:
- '/root/.m2/**/*' # Maven local repo
- '/root/.gradle/**/*' # Gradle cache
Built-in Environment Variables
| Variable | Value |
|---|---|
AWS_DEFAULT_REGION | Region of the build |
AWS_ACCOUNT_ID | Account ID |
CODEBUILD_BUILD_ID | Unique build ID |
CODEBUILD_RESOLVED_SOURCE_VERSION | Git commit SHA |
CODEBUILD_SOURCE_REPO_URL | Source repository URL |
Caching
| Cache Type | Location | Best For |
|---|---|---|
| Local | Build host (cleared between hosts) | Fast single-host builds |
| S3 | Persisted across builds | Maven/Gradle dependencies |
cache:
type: S3
location: my-bucket/codebuild-cache
paths:
- '/root/.m2/**/*'
VPC Support
For builds that need to access private resources (RDS, ElastiCache, internal APIs):
# CloudFormation
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
VpcConfig:
VpcId: !Ref VPC
Subnets: [!Ref PrivateSubnet1, !Ref PrivateSubnet2]
SecurityGroupIds: [!Ref BuildSecurityGroup]
Builds in a VPC cannot reach the internet (for pulling Docker images, downloading Maven artifacts) unless a NAT Gateway is configured in the VPC.
Test Reports
reports:
MyTestReports:
files:
- "**/*.xml"
base-directory: target/surefire-reports
file-format: JUNITXML # Or CUCUMBERJSON, TESTNGXML, VISUALSTUDIOTRX
Reports appear in the CodeBuild console with pass/fail trends.
DVA-C02 Exam Tips
- VPC and Internet Access: If a CodeBuild project is connected to a VPC (to access private DBs), it loses internet access by default. You MUST add a NAT Gateway to the VPC for it to reach external APIs or pull public docker images.
- buildspec.yml location: By default, it must be in the root of the source directory, but you can override the filename and path in the project configuration.
- Caching: Always cache Maven (
/root/.m2/**/*) or Docker layers to S3 to reduce build times. - Artifacts: CodeBuild can upload artifacts to S3 or CodePipeline. Use
imagedefinitions.jsonfor ECS deployments. - Environment Variables: Use
parameter-storeorsecrets-managerfor sensitive values instead of plaintextvariables.
Practice Questions
Q1. A CodeBuild project needs to access a private RDS instance during integration tests. What configuration is required?
A) Use RDS public endpoint
B) Configure VPC settings (VPC, Subnets, Security Groups) on the CodeBuild project
C) Allow 0.0.0.0/0 in the RDS security group
D) Use RDS IAM Authentication
β Answer & Explanation
B β Configure VPC, subnets, and security groups on the CodeBuild project. The build environment runs inside your VPC and can access private resources. Add a NAT Gateway if the build also needs internet access.
Q2. A developer wants to speed up Maven builds by reusing downloaded dependencies between builds. What should they configure?
A) Increase CodeBuild compute size
B) Use a custom Docker image with pre-installed dependencies
C) Configure S3 cache for /root/.m2/**/*
D) Use buildspec install phase to pre-download
β Answer & Explanation
C β S3 caching persists the Maven local repository between builds. CodeBuild uploads the cache to S3 after each build and downloads it at the start, dramatically reducing dependency download time.
Resources
Interview Questions
- How do you optimize CodeBuild cost and throughput for large monorepos with mixed Java and container builds?
- When a build runs in private subnets, what networking design avoids flaky internet dependency failures?
- Which secrets strategy do you use in buildspec to balance security, auditability, and developer velocity?
- How would you harden build reproducibility so two builds from the same commit produce equivalent artifacts?
Short answer guide:
- Use targeted build matrices, caching, and right-sized compute classes.
- Provide NAT or VPC endpoints for required services and deterministic dependency mirrors.
- Prefer SSM/Secrets Manager references, avoid plaintext env variables.
- Pin toolchain versions and isolate mutable external inputs.
