AWS's native CI/CD toolchain breaks software delivery into three connected services: CodePipeline orchestrates the overall workflow, CodeBuild compiles and tests your code, and CodeDeploy pushes the finished artifact to servers, containers, or serverless targets. Together they let you automate the path from a code commit to a live production release without leaving the AWS ecosystem. They're commonly paired with CodeCommit or GitHub for source control and CloudFormation or CDK for infrastructure.
Teams new to AWS often assume CodePipeline, CodeBuild, and CodeDeploy are one bundled "DevOps service" you switch on and configure once. In practice they're three distinct managed services, each solving a narrow problem, that you wire together to form a working delivery pipeline. Understanding where one tool's job ends and the next begins is the difference between a pipeline that makes sense and one that feels like a black box. This article walks through what each service actually does, how they hand work off to each other, and where they fit alongside broader CI/CD pipeline concepts.
CodePipeline is the orchestrator. It doesn't build or deploy anything itself — it defines the sequence of stages a change moves through and calls out to other services to do the actual work.
CodeBuild is the compile-and-test engine. It spins up a temporary container, runs whatever commands you give it, and produces an artifact — a zipped bundle of your compiled application, container image, or packaged code.
CodeDeploy is the release mechanism. It takes an artifact and pushes it onto real infrastructure, whether that's a fleet of EC2 instances, an ECS service, or a Lambda function.
Treat them as three separate tools with a shared vocabulary, not one monolithic product. You can use CodeBuild without CodePipeline. You can use CodeDeploy with artifacts that came from somewhere else entirely. They're designed to be composable, which is both their strength and the source of most beginner confusion.
A pipeline in CodePipeline is built from stages, and each stage contains one or more actions. A typical pipeline has a source stage, a build stage, a test stage, and one or more deploy stages, each running in order.
Transitions between stages happen automatically once every action in a stage succeeds. If a build fails, the pipeline halts right there and nothing downstream executes — you don't accidentally deploy broken code because a later stage never gets triggered.
Pipelines are typically triggered by a source change: a git push to a repository, a new object landing in S3, or a tag being applied. From that trigger, CodePipeline pulls the latest source and hands it to the next stage.
You can also insert manual approval actions between stages. This is how teams gate production releases — a pipeline can deploy automatically to a staging environment, then sit and wait until a human clicks approve before touching production.
Not sure which path fits? Get a free 1:1 consultation with our team.
CodeBuild reads instructions from a file called buildspec.yml, which sits in your repository alongside your code. This file defines phases — install, pre_build, build, post_build — and the exact shell commands to run in each one.
Every build runs in a fresh, ephemeral container that's destroyed the moment the build finishes. There's no lingering state between builds, which eliminates the "works on this build server but not that one" problem that plagues self-managed CI boxes.
You're not limited to AWS's prebuilt images either. You can point CodeBuild at a custom Docker image stored in a registry, which matters if your build needs a specific toolchain, language runtime version, or set of system libraries that the standard images don't include. This is also where familiarity with container orchestration tools pays off, since the same image-based thinking carries over to deployment targets later in the pipeline.
During the build phase, CodeBuild commonly runs your test suite — unit tests, linters, sometimes integration tests against mocked services. Teams running browser-based or end-to-end checks often invoke automated testing tools directly from the buildspec, failing the build if any test fails.
Whatever CodeBuild produces at the end — a jar file, a zipped Lambda package, a built container image — becomes a versioned artifact, stored in S3 or pushed to a container registry. That artifact is what gets handed to CodeDeploy next.
CodeDeploy's job is narrower than people expect: it takes a specific artifact and installs it onto a specific set of targets, following a specific set of instructions. Those instructions live in an appspec.yml file, which tells CodeDeploy what to copy where and which lifecycle hooks to run before and after.
CodeDeploy supports three categories of deployment target:
A deployment group defines which instances, tags, or Auto Scaling groups a given deployment targets, along with the deployment configuration — how fast to roll out and what counts as a failure threshold.
For riskier releases, CodeDeploy supports blue-green deployments: it stands up a new environment alongside the old one, shifts traffic over gradually or all at once, and keeps the old environment around briefly in case you need to roll back. If health checks fail partway through, CodeDeploy can automatically roll back to the last known-good version without anyone paging an on-call engineer at 2 a.m.
CodePipeline is not a CI tool and CodeDeploy is not a build tool — the most common AWS DevOps mistake is expecting any single one of these three services to do another's job, when the entire design is that none of them are supposed to.
Picture a team shipping a Java web service running on ECS. Here's what a real pipeline run looks like, start to finish.
Notice how cleanly the responsibilities split: CodePipeline never touches code, CodeBuild never touches live infrastructure, and CodeDeploy never runs a test suite. Each tool does one job and trusts the others to do theirs.
The honest answer is that it depends on what you're already invested in. AWS-native tools shine in a few specific ways.
Third-party tools like Jenkins or GitHub Actions win on different grounds: a much larger plugin ecosystem, easier multi-cloud or hybrid pipelines, and often a gentler learning curve if your team already lives in GitHub. If your organization runs workloads across major cloud platforms rather than AWS exclusively, a cloud-agnostic CI tool may genuinely serve you better than locking your pipeline logic into one provider's console.
There's no universally correct choice here — it's a tradeoff between tight integration and portability, and the right answer depends on your existing infrastructure and team skillset.
Getting a basic pipeline running involves a handful of concrete steps, most of which are permissions work rather than application code.
On cost, think in two buckets. CodeBuild bills by compute time consumed during builds, so a lean buildspec that avoids unnecessary steps keeps costs down. CodePipeline charges per active pipeline, which matters if you're running many small pipelines versus consolidating into fewer, more comprehensive ones.
CodeDeploy itself has no separate charge for EC2 and on-premises deployments; you mainly pay for the underlying compute and any Lambda or ECS costs already in play. A common pattern among small teams is one pipeline per service, with shared IAM roles reused across pipelines to cut down on setup overhead. Teams building this out for the first time often benefit from structured, hands-on practice — something covered in depth in the AWS DevOps Course programme, which walks through configuring these services against real workloads rather than toy examples.
A handful of myths circulate about these services, usually from people who've read the names without reading the docs.
Most of these misconceptions trace back to treating the three services as one product instead of three cooperating ones. Once you separate orchestration, building, and deploying in your head, the actual AWS console stops feeling mysterious.
Understanding the concept is the start. Being able to apply it is a separate skill, and it follows a fairly consistent path — this is the arc a structured programme takes you through.
*{position:relative;z-index:1} .ci-header{display:flex;align-items:flex-start;justify-cont · Introduction to DevOps on AWS · Infrastructure as Code with CloudFormation · AWS Developer Toolkits · Continuous Integration with CodeCommit and CodeBuild · Continuous Delivery with CodeDeploy and CodePipeline · Microservices and Containers · Serverless DevOps
Want a structured, instructor-led path through all of this — with hands-on projects and real feedback? → AWS DevOps Course
No. You can use CodeBuild standalone to run tests, or CodeDeploy standalone to push releases without CodePipeline tying them together. Most production setups do combine all three, since CodePipeline provides the orchestration and visibility that makes the other two useful as part of a repeatable process.
Yes. CodePipeline supports GitHub, GitHub Enterprise, Bitbucket, and S3 as source providers in addition to CodeCommit, which AWS has deprecated for new customers. Most teams today wire CodePipeline directly to a GitHub repository.
buildspec.yml is CodeBuild's config file; it defines install, pre-build, build, and post-build commands plus what artifacts to output. appspec.yml is CodeDeploy's config file; it defines how to install the artifact on a target (file locations, lifecycle hooks like ApplicationStart) and doesn't run tests or compile anything.
Yes. CodeDeploy supports EC2/on-premises instances, ECS services, and Lambda functions, each with its own deployment configuration (in-place, blue-green, or canary/linear traffic shifting for Lambda and ECS).
CodePipeline charges a flat monthly fee per active pipeline (with a free tier), CodeBuild charges per build minute based on compute size, and CodeDeploy is free for EC2/Lambda deployments (you pay only for the underlying compute). Costs scale with build frequency and pipeline count, not team size.
They can be, but the real decision point is ecosystem lock-in versus integration depth. AWS-native tools give you tighter IAM integration and less infrastructure to manage, while Jenkins and GitLab CI offer broader plugin ecosystems and easier multi-cloud portability.
Browse our upcoming batches — live, instructor-led, delivered on Orbit.