Courseiva
DOP-C02Chapter 9 of 18Objective 1.2

Continuous Integration with AWS CodeBuild

Continuous Integration with AWS CodeBuild is the automated process of merging code changes from multiple developers into a shared repository several times a day, then automatically building and testing every change. For the DOP-C02 exam, understanding this service is critical because it is the engine that powers the 'build' stage of almost every DevOps pipeline, and the exam will test how to configure, secure, and troubleshoot it in combination with other AWS services like CodePipeline and CodeCommit.

12 min read
Intermediate
Updated Jul 23, 2026
Reviewed by Johnson Ajibi· Senior Network & Security Engineer · MSc IT Security

A simple way to picture Continuous Integration with AWS CodeBuild

The Master Baker’s Kitchen Analogy

You are a master baker running a high-end patisserie. Every morning, you receive a dozen new cake recipes from different clients. Your kitchen is spotless, your tools are prepped, and you have a single, strictly followed procedure: you taste every single ingredient before it goes into the mixing bowl. You test each egg for freshness, you verify the flour hasn’t gone stale, and you check that the sugar is perfectly granulated. Then, after mixing, you bake a single, tiny sample cake to taste the final result before you commit to making the full, elaborate multi-tiered celebration cake. This tasting step happens after every single recipe change — no exceptions.

Now imagine you are not just one baker, but a whole team of bakers in a massive bakery. Every time any baker tweaks a recipe, the same strict testing procedure must be run automatically. This is what a Continuous Integration (CI) system does for software. The recipe is your source code, the ingredient tasting is running automated tests, and the sample cake is a build — a temporary, compiled version of your software. The system is called AWS CodeBuild. It is a fully managed service that takes your source code, automatically runs a set of instructions (a build specification), compiles the code, runs tests, and then produces a packaged, ready-to-deploy version of your software. It does all of this without you having to set up or manage any servers or kitchen equipment. Every time a developer “commits” (saves and pushes) a change to the central code repository, AWS CodeBuild springs into action, guaranteeing that the new recipe hasn’t ruined the cake before it ever reaches a customer.

How It Actually Works

Continuous Integration (CI) is a software development practice where developers frequently merge their code changes into a central repository, and every merge triggers an automated build and a set of automated tests. Before CI, developers would work in isolation for days or weeks on a feature, and when they tried to merge their changes with everyone else's, everything would break in a chaotic conflict called 'integration hell'. CI solves this by integrating and testing early and often.

AWS CodeBuild is a fully managed build service. 'Fully managed' means AWS takes care of the underlying servers, operating system patches, and scaling — you do not have to maintain any build server infrastructure. CodeBuild compiles your source code, runs tests, and produces software packages that are ready to deploy. It works with many programming languages (like Java, Python, Ruby, Node.js, and Go) and can produce outputs like a JAR file for Java or a ZIP archive.

Here is how it works step by step:

First, a developer writes code and pushes (uploads) it to a source repository. CodeBuild supports popular source providers including AWS CodeCommit (a private Git repository on AWS), GitHub, GitHub Enterprise, Bitbucket, and Amazon S3 (a storage service).

Second, you define a 'build project' in CodeBuild. This project contains all the configuration for your build. The core of this configuration is a YAML file called the 'buildspec.yml' file. YAML is a human-readable data format (like a configuration recipe). The buildspec.yml file lives in the root of your source code repository and tells CodeBuild exactly what to do. It has four main phases:

'install': installs any dependencies your build needs, like a specific version of Node.js or a testing library.

'pre_build': runs commands that must happen before the main build, such as signing in to a container registry or checking for secrets.

'build': the main compilation and testing commands. For example, for a Java project, this might be 'mvn compile' or 'mvn test'.

'post_build': runs after the main build, typically used to package your build output (e.g., create a ZIP file) or push the result to a repository like Amazon ECR (Elastic Container Registry) or Amazon S3.

Third, you trigger the build. A trigger can be manual (you click 'Start build' in the AWS Management Console) or automatic (a webhook from your source repository any time code is pushed). Most CI pipelines use automatic triggers.

Fourth, CodeBuild launches a fresh, temporary build environment. Think of this as a clean, empty kitchen for every single build. The environment is a Docker container. Docker is a technology that packages software with everything it needs to run, like a lightweight, portable virtual machine. You can choose from pre-built environments (like Ubuntu Linux with Java 11 or Node.js 14) or provide your own custom Docker image. No build environment is ever reused — every build starts from scratch, guaranteeing consistency and preventing 'it works on my machine' problems.

Fifth, CodeBuild runs the commands in your buildspec.yml file inside this temporary container. It streams all the output logs to AWS CloudWatch Logs (a monitoring service) in real time, so you can watch the build happen and debug failures.

Sixth, when the build succeeds, CodeBuild packages the output artifacts (the compiled files) and stores them where you specify, typically in an Amazon S3 bucket. If the build fails, CodeBuild stops and reports the error. It can also send a notification via Amazon SNS (Simple Notification Service) to alert the team.

Why does this matter for DevOps? CI is one of the core practices of DevOps because it catches integration bugs early, reduces manual effort, and gives rapid feedback to developers. Without CI, a team of ten developers might wait two weeks to discover that their changes are incompatible. With CI, they know within minutes.

For the DOP-C02 exam, you must also understand CodeBuild's integration with other services. It is commonly the 'build' stage in an AWS CodePipeline, which is a CI/CD (Continuous Integration / Continuous Delivery) orchestration service that automates the entire release process from source to deployment. CodeBuild can also be triggered by AWS CodeCommit push events, Amazon S3 bucket events, or scheduled cron jobs. You must know how to give CodeBuild permissions to access other AWS services using an IAM service role. An IAM role is like a temporary identity card that allows CodeBuild to perform actions like reading source code from CodeCommit, storing artifacts in S3, or pulling a custom Docker image from Amazon ECR.

This diagram shows the end-to-end flow of a CI build triggered by a code push, through CodeBuild's stages, to artifact storage and notification.

Walk-Through

1

Code Push to Repository

A developer commits and pushes code changes to a source repository like AWS CodeCommit. This act triggers a webhook that notifies CodeBuild of the new code. The webhook ensures the build starts automatically without human intervention, which is the essence of continuous integration.

2

Build Project Configuration

CodeBuild reads the build project settings you have pre-configured, including the source repository location, the build environment (e.g., 'aws/codebuild/standard:5.0'), the service IAM role, and the output artifact location (an S3 bucket). The build project also defines timeout, VPC configuration, and environment variables. Without this configuration, CodeBuild would not know what type of environment to launch or where to send the results.

3

Read buildspec.yml

CodeBuild locates the 'buildspec.yml' file from the root of the source code. This YAML file contains the exact commands for the four build phases and defines environment variables (like database connection strings) and artifact output paths. This file is version-controlled alongside the code, so build instructions change with the code, ensuring consistency.

4

Environment Launch and Dependency Installation

CodeBuild launches a fresh Docker container using the specified environment image. It then executes the 'install' phase commands (e.g., 'pip install -r requirements.txt' for Python, or 'npm install' for Node.js). This installs all external libraries or tools the build needs. Running this in a clean container prevents conflicts with previously installed packages.

5

Code Compilation and Testing

CodeBuild executes the 'build' phase commands (e.g., 'mvn compile' for Java or 'make' for C++), which compile the source code into executable binaries or libraries. Then it runs the defined tests. If a test fails, CodeBuild reports the failure immediately and stops, preventing broken code from proceeding further in the pipeline.

6

Artifact Packaging and Storage

After successful testing, CodeBuild runs the 'post_build' phase commands, which typically package the built files into a deployable artifact (e.g., a ZIP file or Docker image). It then uploads this artifact to the designated S3 bucket or pushes the Docker image to Amazon ECR. This artifact is now ready for deployment in the next stage of the pipeline.

7

Logging and Notification

CodeBuild streams all build output, including errors, to Amazon CloudWatch Logs for real-time and historical inspection. It also sends a notification (via Amazon SNS) about the build result (success or failure) to configured endpoints like email, Slack, or an AWS Lambda function. This feedback loop lets developers react immediately to build failures.

What This Looks Like on the Job

An IT professional working as a DevOps engineer at a mid-sized e-commerce company is responsible for building and deploying a microservices-based application. The application consists of 15 separate services (like user authentication, product catalogue, payment processing, and order management), each owned by a different team. The teams work in different programming languages: one in Python, one in Java, one in Node.js. Before adopting AWS CodeBuild, the teams manually built each service on individual developer laptops. This caused chaos: builds were inconsistent, the 'it works on my machine' problem was rampant, and deploying to production took three days because someone had to manually compile, test, and package each service.

Step 1: The DevOps engineer creates separate CodeBuild projects for each of the 15 services. For the Python service, they configure a build environment using the 'aws/codebuild/amazonlinux2-x86_64-standard:3.0' image. For the Java service, they use the 'aws/codebuild/standard:5.0' image which includes Java 11 and Maven. For the Node.js service, they use the 'aws/codebuild/standard:5.0' image with Node.js 16.

Step 2: For each service, they write a tailored buildspec.yml file. The buildspec for the Java service includes:

In the 'install' phase: no additional steps because Maven is already in the environment.

In the 'pre_build' phase: log in to Amazon ECR using the AWS CLI command 'aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com'.

In the 'build' phase: run 'mvn clean package' and then 'docker build -t payment-service .' to create a Docker image.

In the 'post_build' phase: push the Docker image to Amazon ECR using 'docker push <ecr-repo-uri>:latest'.

Step 3: They configure an AWS CodePipeline that triggers automatically whenever a developer pushes code to the 'main' branch of the CodeCommit repository. The pipeline has three stages: Source (pull code from CodeCommit), Build (invoke the correct CodeBuild project), and Deploy (deploy the new container to Amazon ECS using CodeDeploy).

Step 4: A developer on the payment team pushes a bug fix. Within 30 seconds, CodePipeline detects the new commit and triggers the Build stage. CodeBuild launches a fresh container, checks out the latest code, logs in to ECR, compiles the Java code, runs 200 unit tests, builds a Docker image, and pushes it to the ECR repository. The build logs are streamed to CloudWatch Logs. The developer receives an automated email from Amazon SNS saying the build succeeded. The pipeline then automatically deploys the new container to a staging environment.

Step 5: If a build fails, the pipeline pauses and sends a failure notification. The developer can click a link to inspect the build logs in CloudWatch Logs to see the exact line of code that caused the failure, for example a Python syntax error on line 42 of app.py, and fix it immediately.

What the IT professional actually does:

Writes and maintains the buildspec.yml files for each service.

Configures IAM roles for CodeBuild to access CodeCommit, S3, ECR, and CloudWatch Logs.

Monitors build metrics like build duration, success rate, and queued builds using CloudWatch dashboards.

Integrates CodeBuild with AWS Secrets Manager to retrieve database passwords and API keys needed during the build, instead of hardcoding them in the buildspec file.

Sets up build timeouts (e.g., 30 minutes) to prevent runaway builds from incurring unnecessary cost.

Creates separate CodeBuild projects for different environments (development, staging, production) with different artifact locations and different IAM permissions.

How DOP-C02 Actually Tests This

The DOP-C02 exam tests AWS CodeBuild in depth, primarily as part of questions about building CI/CD pipelines. Expect multiple-choice scenario questions where you must choose the correct configuration for a given situation. The exam loves to present three similar-looking answers and one correct one.

Key concepts the exam tests:

buildspec.yml syntax: You must know the correct YAML structure for the phases (install, pre_build, build, post_build), how to specify environment variables (env.variables), where to define artifacts (artifacts.files), and how to set cache (cache.paths). The exam will ask you to identify the correct buildspec.yml snippet from a list.

Environment types: CodeBuild offers 'LINUX_CONTAINER', 'WINDOWS_SERVER_2019_CONTAINER', 'LINUX_GPU_CONTAINER', and 'ARM_CONTAINER'. You must know which environment type to choose based on the application. For example, for .NET applications on Windows, you need a Windows container. For machine learning training on GPUs, you need a GPU container. For most modern applications, a Linux container is the default.

VPC configuration: CodeBuild by default runs in a VPC that AWS manages. But if your build needs to access resources inside your own VPC (like a private Amazon RDS database to run integration tests), you must configure CodeBuild to run in your VPC. The exam will test you on when and how to set the 'vpcConfig' parameter in the build project.

IAM roles and permissions: The exam will test the least privilege principle — creating an IAM service role for CodeBuild with only the permissions it needs (e.g., 'codecommit:GetFile', 's3:PutObject', 'logs:CreateLogGroup'). They will present scenarios where the build fails due to missing permissions, and you must identify which permission is missing.

Artifacts and caching: CodeBuild stores build outputs as artifacts in an S3 bucket. Caching can improve performance by reusing downloaded dependencies (like Maven .m2 folder or npm packages) across builds. You must know how to configure caching and where the cache is stored.

Integrations: The exam frequently asks how CodeBuild integrates with CodePipeline, CodeCommit, CloudWatch Events (now called Amazon EventBridge), and AWS CloudTrail for auditing. You must know that CodePipeline can pass variables (like a build ID) from one stage to the next.

Security: Topics include validating the source code with signed commits, using AWS KMS to encrypt artifacts, and scanning for secrets in the build process. The exam may ask about using Amazon CodeGuru Reviewer or integration with security scanning tools.

Build timeouts: The default timeout is 8 hours, but the exam will test you on setting a shorter timeout (e.g., 20 minutes) to save costs and prevent orphaned builds.

Common traps the exam sets:

Confusing 'computeType' sizes: build.general1.small, build.general1.medium, build.general1.large. The exam might ask which to use for a memory-intensive build. The general rule: small for simple builds, medium for most builds, large for builds that need more than 8GB of RAM.

Forgetting that CodeBuild supports custom Docker images: The exam might present a scenario where the pre-built environment does not have a required tool (like a specific version of Terraform). The correct answer is to create a custom Docker image stored in Amazon ECR and reference it in the build environment.

Misunderstanding build specifications inheritance: The buildspec.yml file can have a version (currently 0.2). The exam may test that the version is required and that the file must be in YAML format.

Not knowing that CodeBuild can run shell scripts: If you need complex logic, you can reference a shell script file in the buildspec.yml instead of inline commands, using the 'commands' field under each phase.

Assuming CodeBuild can only build code: The exam may present a scenario where you want to run a database migration script as part of a build. This is valid — you can run any command in the build environment.

To memorise: The buildspec.yml phases are 'install', 'pre_build', 'build', 'post_build' in that exact order. Know the default compute type ('build.general1.small') and the default environment image for Linux ('aws/codebuild/standard:5.0'). Remember that CodeBuild uses a 'service role' not a 'user role', and that role must trust the 'codebuild.amazonaws.com' service principal.

Key Takeaways

AWS CodeBuild is a fully managed continuous integration service that compiles source code, runs tests, and produces deployable artifacts without you having to manage any servers.

Every build runs in a fresh, isolated Docker container, guaranteeing that each build is identical and eliminating the 'it works on my machine' problem.

The buildspec.yml file, written in YAML, is the core configuration that defines the build phases: install, pre_build, build, and post_build, in that exact order.

CodeBuild integrates natively with AWS CodePipeline, CodeCommit, S3, and CloudWatch Logs, making it the natural build engine for DevOps pipelines on AWS.

To access private resources (like an RDS database) during a build, you must configure CodeBuild to run inside your own VPC using the vpcConfig parameter.

CodeBuild stores build output artifacts in an Amazon S3 bucket, and you can cache files (like Maven dependencies) across builds to significantly reduce build time.

CodeBuild does not perform deployments; it only produces artifacts. Deployment is the responsibility of other services like CodeDeploy, ECS, or Lambda, typically orchestrated by CodePipeline.

You must grant CodeBuild an IAM service role with least-privilege permissions to read source code, write artifacts, and access any other AWS resources needed during the build.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

AWS CodeBuild

Runs the actual build commands (compile, test, package) inside a temporary container

Focused on the 'build' phase of the CI/CD lifecycle

Output is an artifact (e.g., ZIP file or Docker image) stored in S3 or ECR

AWS CodePipeline

Orchestrates the entire release workflow from source to deployment

Coordinates multiple stages: source, build, test, deploy, each handled by different services

Output is a deployed application; it does not run build commands itself

AWS CodeBuild

Purpose: compile code and run tests

Runs in a temporary, disposable container per build

Produces build artifacts stored in S3 or ECR

AWS CodeDeploy

Purpose: deploy application updates to compute services like EC2, Lambda, or ECS

Runs on target servers or as a service

Consumes build artifacts and deploys them to running environments

CodeBuild Build Environment (Linux Container)

Supports most open-source languages like Java, Python, Node.js, Ruby

Typically faster startup and lower cost per build

Cannot compile .NET Framework applications that depend on Windows-only features

CodeBuild Build Environment (Windows Container)

Supports .NET Framework, classic ASP, and other Windows-only technologies

Slower startup and higher cost per build

Cannot run Linux-native toolchains like gcc or make

Watch Out for These

Mistake

CodeBuild runs builds on the same server every time, so you can rely on files from a previous build being present.

Correct

CodeBuild creates a fresh, temporary build environment for every build. No data persists between builds unless you explicitly use caching or store artifacts externally.

This mirrors the idea of virtual machines or containers being disposable. Beginners often assume a persistent server environment because traditional build servers like Jenkins often have a persistent file system.

Mistake

You do not need to write a buildspec.yml file because CodeBuild can guess how to build your code from the programming language.

Correct

CodeBuild requires a buildspec.yml file in the root of your source code to define the build commands. There is no automatic build detection. You must explicitly write the instructions.

Many AWS services offer automatic detection (like CodeGuru for code review), so beginners assume CodeBuild works the same way. CodeBuild is a blank canvas — you tell it exactly what to do.

Mistake

CodeBuild can deploy your application directly to EC2 or Lambda after the build.

Correct

CodeBuild only compiles code, runs tests, and produces artifacts. It does not deploy. Deployment is handled by other services like AWS CodeDeploy, Amazon ECS, or AWS Lambda, usually orchestrated by AWS CodePipeline.

The line between CI (continuous integration) and CD (continuous delivery) is blurry for beginners. CodeBuild is strictly the CI part; it integrates with other services for CD.

Mistake

If my build fails, I must manually log into the build container to fix it.

Correct

You cannot log into a failed build container. The environment is destroyed after the build ends. You must fix the code and push a new commit, which triggers a new build with a fresh environment.

Beginners often think of build servers as persistent machines they can SSH into. CodeBuild's stateless, ephemeral nature is a deliberate design to ensure consistency, but it feels unintuitive at first.

Mistake

CodeBuild can only build code stored in AWS CodeCommit.

Correct

CodeBuild supports source code from AWS CodeCommit, GitHub, GitHub Enterprise, Bitbucket, and S3. It also supports third-party source providers through webhooks.

Because the exam often presents scenarios with CodeCommit and CodePipeline together, beginners assume CodeBuild is locked into the AWS ecosystem. It is actually source-agnostic.

Mistake

You must use Docker containers for every CodeBuild build.

Correct

CodeBuild always runs builds inside a Docker container — that is how it provides isolated, consistent environments. But you do not need to know Docker to use CodeBuild; you simply choose from a list of pre-built environments.

The term 'container' intimidates beginners. They think they need to learn Docker before using CodeBuild, but CodeBuild abstracts all container management away. You just pick an environment image.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

Do I need to provision an EC2 instance to use AWS CodeBuild?

No, CodeBuild is a fully managed service. AWS automatically provisions and manages the underlying compute resources for each build. You do not need to create, configure, or maintain any EC2 instances.

Can AWS CodeBuild run tests that require a database?

Yes, but the database must be accessible from the CodeBuild build environment. If the database is in your private VPC, you must configure CodeBuild to run in that same VPC using the VPC configuration option. Otherwise, CodeBuild runs in an AWS-managed VPC with no access to your private resources.

How is CodeBuild different from Jenkins?

Jenkins is an open-source build server that you must install, configure, and maintain on your own infrastructure (EC2 or on-premises). CodeBuild is a managed service — you only define the build project and AWS handles the servers, scaling, and patching. CodeBuild also integrates more tightly with other AWS services like CodePipeline and IAM.

What happens if my build takes longer than the timeout I set?

CodeBuild will stop the build and mark it as failed. You set the timeout when creating the build project (default is 8 hours). If you expect a longer build, you can increase the timeout, or you can optimise your build to finish sooner.

Can I use CodeBuild with source code hosted on GitHub or Bitbucket?

Yes, CodeBuild supports source providers including GitHub, GitHub Enterprise, Bitbucket, and AWS CodeCommit. You connect CodeBuild to your repository using OAuth tokens or webhooks. The build is triggered automatically on push events if configured.

How does CodeBuild handle environment variables like API keys?

You can specify environment variables directly in the build project configuration or in the buildspec.yml file. For sensitive values like API keys, you should use AWS Secrets Manager or Systems Manager Parameter Store and reference them in the buildspec.yml using the 'parameter-store' or 'secrets-manager' type.

Terms Worth Knowing

Keep going

You've finished Continuous Integration with AWS CodeBuild. Continue through the DOP-C02 study guide to build a complete picture of the exam.

Done with this chapter?