Introduction
Hi, I'm miruky.
If you have ever tried to wire up CI/CD on AWS, you already know the names: CodeCommit, CodeBuild, CodeDeploy, CodePipeline. Individually each one is small. The real question is how to glue them into a flow that actually ships software safely.
Where does the source live? Where does the build run? How do artifacts move? How do you deploy to EC2, ECS, or Lambda? Who approves the production push? What happens when something fails? CI/CD only starts paying back when all of these connect in a single line.
This article walks through that end to end, from the fundamentals of CI/CD to each service, the config files, a complete hands-on pipeline, and day-2 operations.
Status note as of mid-2026
AWS CodeCommit was restricted to existing customers from July 2024, then returned to full general availability on November 24, 2025. Amazon CodeCatalyst and Amazon CodeGuru Reviewer remain restricted for new customers. This article reflects the post-GA state, so CodeCommit is back on the table next to GitHub integration.
Scope
| Area | Contents |
|---|---|
| CI/CD fundamentals | CI, Continuous Delivery, Continuous Deployment, the base flow |
| CodeCommit | Service overview, GA return, migration to GitHub, comparisons |
| GitHub integration | Git setup, SSH keys, CodeConnections, connection checks |
| CodeBuild | How it works, pricing, compute types, project creation |
buildspec.yml |
Phases, environment variables, secrets, cache, Docker, batch, reports, webhooks |
| CodeDeploy for EC2 |
appspec.yml, lifecycle, agent, EC2 deployment, deployment groups |
| Deployment strategies | In-Place, Blue/Green, load balancers, automatic rollback, CloudWatch alarms |
| ECS and Lambda | Blue/Green, Canary, Linear, test hooks, Lambda aliases |
| CodePipeline | Stages, actions, artifacts, V1 vs V2, pricing |
| CodePipeline V2 | Trigger filters, variables, manual approval, SNS, EventBridge, JSON definitions |
| Advanced layouts | Multi-stage, parallel actions, multi-source, CloudFormation, cross-account, cross-region, Lambda Invoke |
| End-to-end hands-on | GitHub to EC2 CI/CD, validation, failure behavior, cleanup |
| Production operations | IAM, secrets, S3/KMS, cost, monitoring, logs, troubleshooting, team practices |
Table of Contents
- CI/CD fundamentals
- The AWS Code family at a glance
- Source control and where CodeCommit stands now
- GitHub and CodeConnections setup
- CodeBuild fundamentals
-
buildspec.ymlin practice - CodeDeploy fundamentals
- Deploying to EC2
- Deployment strategies and rollback
- Canary deployments to ECS and Lambda
- CodePipeline fundamentals
- CodePipeline V2 in practice
- Advanced pipeline design
- Building a CI/CD pipeline from scratch
- Security and IAM design
- Cost, monitoring, and logs
- Troubleshooting
- Patterns and team practices
1. CI/CD fundamentals
1-1. CI
CI stands for Continuous Integration: developers merge code into the repository often, and every merge triggers builds, tests, and static analysis automatically.
| Item | Detail |
|---|---|
| Goal | Catch integration bugs fast |
| Triggers | push, pull request, manual run |
| Automated steps | Compile, unit tests, lint, format check |
| Central AWS service | CodeBuild |
Without CI, missed tests, environment drift, and post-merge breakage tend to surface late. The point of CI is to verify small changes quickly.
1-2. CD
CD has two meanings, and they are not interchangeable.
| Term | Meaning | Production push |
|---|---|---|
| Continuous Delivery | Keep production-ready at all times | Manual approval gate |
| Continuous Deployment | Auto-promote to production after tests | Fully automatic |
In practice, most teams want a human gate before production, so Continuous Delivery is more common. CodePipeline's manual approval stage maps cleanly to that.
1-3. End-to-end CI/CD flow
flowchart TB
A[Source control] --> B[Build]
B --> C[Test]
C --> D[Artifact storage]
D --> E[Staging deploy]
E --> F[Manual approval]
F --> G[Production deploy]
G --> H[Monitoring and logs]
On AWS, source lives in CodeCommit or GitHub, builds run in CodeBuild, deployments are driven by CodeDeploy, and CodePipeline orchestrates the whole flow.
2. The AWS Code family at a glance
2-1. The four core services
| Service | Role | Main config file |
|---|---|---|
| AWS CodeCommit | Managed Git repository | none |
| AWS CodeBuild | Build and test | buildspec.yml |
| AWS CodeDeploy | Deploy to EC2, ECS, Lambda | appspec.yml |
| AWS CodePipeline | Orchestrate the CI/CD flow | Pipeline JSON, console config |
CodePipeline does not build or deploy by itself. It chains actions like Source, Build, Deploy, and Approval, and manages order, artifacts, and what happens on failure.
2-2. CI/CD steps mapped to AWS services
| Step | AWS service | Notes |
|---|---|---|
| Source control | CodeCommit, GitHub, GitLab, Bitbucket | CodeConnections is the bridge for non-AWS sources |
| Build | CodeBuild | EC2 compute or Lambda compute |
| Artifact storage | S3, ECR | ZIPs, static files, Docker images |
| Deploy | CodeDeploy, CloudFormation, ECS, S3 | The right action depends on the target |
| Approval | CodePipeline Manual approval | Pre-production gate |
| Notifications | SNS, EventBridge, AWS Chatbot | Failure alerts, approval requests |
| Observability | CloudWatch, CloudTrail | Logs, metrics, audit trail |
2-3. Choosing services in 2026
| Goal | First choice | Notes |
|---|---|---|
| Stay fully inside AWS for Git | CodeCommit | Returned to GA in November 2025 |
| Develop primarily on GitHub | GitHub + CodeConnections | Most common in practice |
| Only the build in AWS | CodeBuild | Plays well alongside GitHub Actions |
| Safe EC2 rollout | CodeDeploy | Needs agent and appspec.yml
|
| Staged rollout for ECS or Lambda | CodeDeploy | Canary, Linear, AllAtOnce |
| Tie multiple steps together | CodePipeline V2 | Default to V2 for new pipelines |
2-4. Alternatives outside the Code family
CI/CD on AWS does not have to use the Code family. GitHub Actions, GitLab CI/CD, Bitbucket Pipelines, Terraform Cloud, and CircleCI are all valid options.
| Option | Good for | Watch out for |
|---|---|---|
| GitHub Actions | GitHub-centric workflows | Use OIDC to minimize AWS permissions |
| GitLab CI/CD | Source + CI integrated in GitLab | AWS-side permissioning is separate |
| Bitbucket Pipelines | Atlassian-aligned stacks | Confirm AWS integration design |
| CodePipeline + CodeBuild | Want the runtime inside AWS | CodeConnections and IAM design matter |
| CodeCommit + CodePipeline | Stay fully inside AWS | Collaboration features are lighter than GitHub or GitLab |
Amazon CodeCatalyst once bundled source control, issue tracking, and CI/CD into a single managed service. New customer signups stopped on November 7, 2025, so treat it as an option for existing users rather than a default for new builds.
3. Source control and where CodeCommit stands now
3-1. CodeCommit overview
AWS CodeCommit is a managed private Git repository service. The strengths are IAM-driven access control, KMS encryption at rest, TLS in transit, and CloudTrail-based auditing, all controllable from inside AWS.
| Item | Detail |
|---|---|
| Protocols | HTTPS, SSH |
| Auth | IAM, Git credentials, SSH public key |
| Encryption | At rest and in transit |
| Notifications | SNS, Lambda, EventBridge |
| Integrations | CodeBuild, CodePipeline, CloudTrail |
| Best fit | Teams that want to keep development inside AWS, regulated industries, IAM-centric governance |
3-2. CodeCommit timeline
| Date | Event |
|---|---|
| 2024-07-25 | New customer access paused |
| 2025-11-24 | Full GA return announced |
| Mid-2026 | Safe to put CodeCommit back on the shortlist for new builds |
If you migrated to GitHub or GitLab during the pause, you can keep using them. But if you care about staying inside AWS, IAM governance, VPC endpoints, or CloudTrail auditing, CodeCommit is once again a reasonable pick.
3-3. CodeCommit vs GitHub, GitLab, Bitbucket
| Lens | CodeCommit | GitHub | GitLab | Bitbucket |
|---|---|---|---|---|
| AWS integration | Strong | Via CodeConnections | Via CodeConnections | Via CodeConnections |
| IAM control | Strong | OIDC + GitHub controls | OIDC + GitLab controls | Atlassian controls |
| Collaboration | Basic | Strong (Issues, Projects, PRs) | Strong (Issue, Board, CI) | Strong Jira integration |
| CI/CD | Pairs with CodeBuild | GitHub Actions also viable | GitLab CI/CD also viable | Bitbucket Pipelines also viable |
| Fully inside AWS | Easy | Hard | Hard | Hard |
The hands-on in this article uses GitHub. If you prefer CodeCommit, swap the Source action; the CodeBuild, CodeDeploy, and CodePipeline thinking is the same.
3-4. Migrating off CodeCommit
To move history, branches, and tags in one shot, use a mirror clone.
# Mirror-clone the CodeCommit repository
git clone --mirror https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/my-repo temp-repo
# Point the mirror at the empty GitHub repo
cd temp-repo
git remote set-url origin git@github.com:my-org/my-repo.git
# Push every branch and tag
git push --mirror
# Clean up the working directory
cd ..
rm -rf temp-repo
After the move, revisit branch protection, CODEOWNERS, CI/CD configs, webhooks, secrets, and the Source action of every pipeline.
4. GitHub and CodeConnections setup
4-1. Git and SSH key setup
# Configure Git identity
git config --global user.name "your-name"
git config --global user.email "your-email@example.com"
# Default new repositories to main
git config --global init.defaultBranch main
# Generate an SSH key
ssh-keygen -t ed25519 -C "your-email@example.com"
# Verify the connection
ssh -T git@github.com
Create the repository on GitHub and push an initial file to main before moving on.
4-2. Creating the GitHub repository
Keep the demo repository minimal at first, ideally just a README. Reusing the same repo across CodeBuild, CodeDeploy, and CodePipeline makes the end-to-end flow easier to follow.
# Clone the repository
git clone git@github.com:your-name/aws-code-series-demo.git
cd aws-code-series-demo
# Add a starter file
cat > README.md << 'EOF'
# aws-code-series-demo
A demo repository for AWS Code family CI/CD experiments.
EOF
# Commit and push
git add README.md
git commit -m "Add initial README"
git push origin main
Branch protection, required reviews, and required status checks can be layered on later. Start permissive, get the pipeline working, then harden.
4-3. What CodeConnections does
AWS CodeConnections is the bridge between AWS and GitHub, GitLab, Bitbucket, and friends. It was renamed from AWS CodeStar Connections on March 29, 2024.
When you use GitHub in CodePipeline, the Source action typically uses the CodeStarSourceConnection provider. The legacy name lives on in the action, but the service itself is AWS CodeConnections.
| Item | Detail |
|---|---|
| Targets | GitHub, GitHub Enterprise Server, GitLab, Bitbucket, etc. |
| Role | Detect repo changes and fetch source on AWS' behalf |
| Required permission | codeconnections:UseConnection |
| Output | ZIP, or a full-clone reference for CodeBuild |
| Caveat | Some regions restrict the connection action |
4-4. Creating and verifying the connection
From the Developer Tools Connections console, pick GitHub, install the GitHub App, and grant access to the target repositories. Once the connection status reads AVAILABLE, the Source action in CodePipeline can use it.
# List your connections
aws codeconnections list-connections \
--provider-type GitHub \
--query 'Connections[*].{Name:ConnectionName,Status:ConnectionStatus,Arn:ConnectionArn}' \
--output table
Older CLI versions and existing resources may still surface the codestar-connections namespace. For new work, design around codeconnections from the start.
5. CodeBuild fundamentals
5-1. What CodeBuild is
AWS CodeBuild is a fully managed build, test, and packaging service. You do not run or maintain build servers.
| Trait | Detail |
|---|---|
| Server management | None |
| Scaling | Auto-scales with build demand |
| Runtime | A fresh container per build |
| Configuration | Declared in buildspec.yml
|
| Outputs | S3, ECR, or CodePipeline |
| Logs | CloudWatch Logs |
The default flow is: fetch source, start the environment, run install, pre_build, build, post_build, emit artifacts, tear down.
5-2. Compute types
| Type | Trait | Good for |
|---|---|---|
| EC2 on-demand | Minute-billed, supports Docker and long builds | General builds |
| Lambda on-demand | Second-billed, shorter max runtime | Light builds and quick tests |
| EC2 reserved capacity | Dedicated fleet | High-volume builds, predictable queue times |
Docker image builds need EC2 compute with privileged mode enabled. Lambda compute is lightweight but cannot run Docker-in-Docker workloads.
5-3. Pricing at a glance
As of mid-2026, CodeBuild is pay-as-you-go: EC2 on-demand is minute-based, Lambda on-demand is second-based.
| Item | Free tier |
|---|---|
| EC2 on-demand | 100 build minutes per month on general1.small or arm1.small
|
| Lambda on-demand | 6,000 build seconds per month on lambda.arm.1GB or lambda.x86-64.1GB
|
general1.small will keep this hands-on close to free. CloudWatch Logs, S3, KMS, and ECR are billed separately, so watch those independently.
5-4. Your first CodeBuild project
A minimal setup: a Python app, a test, and buildspec.yml.
# app.py
def hello():
return "Hello, AWS CodeBuild!"
def add(a, b):
return a + b
if __name__ == "__main__":
print(hello())
print(f"1 + 2 = {add(1, 2)}")
# test_app.py
import unittest
from app import add, hello
class TestApp(unittest.TestCase):
def test_hello(self):
self.assertEqual(hello(), "Hello, AWS CodeBuild!")
def test_add(self):
self.assertEqual(add(1, 2), 3)
self.assertEqual(add(-1, 1), 0)
if __name__ == "__main__":
unittest.main()
When you create the CodeBuild project, you pick the source provider, the GitHub connection, the branch, the runtime, the service role, the buildspec, the artifact target, and the log destination.
5-5. First build and log check
After creating the project, start the first build manually. The goal of run #1 is not "my app works", it is "CodeBuild can fetch the source, read buildspec.yml, and stream logs to CloudWatch Logs".
# Start a build
aws codebuild start-build \
--project-name code-series-demo-build
# Grab the latest build ID
BUILD_ID=$(aws codebuild list-builds-for-project \
--project-name code-series-demo-build \
--query 'ids[0]' \
--output text)
# Inspect the build state
aws codebuild batch-get-builds \
--ids "$BUILD_ID" \
--query 'builds[0].{Status:buildStatus,Start:startTime,End:endTime}'
If it fails, look at Phase details in the CodeBuild console and at CloudWatch Logs. DOWNLOAD_SOURCE_FAILED points at the connection or repo permissions, CLIENT_ERROR usually means a buildspec.yml syntax issue, and UPLOAD_ARTIFACTS_FAILED is almost always S3 permissions.
6. buildspec.yml in practice
6-1. Base structure
buildspec.yml declares what CodeBuild runs. Put it at the repository root by default.
version: 0.2
env:
variables:
ENVIRONMENT: "dev"
phases:
install:
runtime-versions:
python: 3.12
commands:
- echo "Installing dependencies"
- pip install -r requirements.txt
pre_build:
commands:
- echo "Running tests"
- python -m unittest discover -v
finally:
- echo "pre_build cleanup"
build:
commands:
- echo "Running the application"
- python app.py
post_build:
commands:
- echo "Build complete"
artifacts:
files:
- '**/*'
finally runs even when the phase's commands fail, which makes it a good place for log collection and temp cleanup.
6-2. Environment variables and secrets
| Kind | Syntax | Use |
|---|---|---|
| Plain environment variable | env.variables |
Environment name, non-sensitive config |
| Parameter Store | env.parameter-store |
API keys, configuration values |
| Secrets Manager | env.secrets-manager |
DB passwords, external service credentials |
| Exported variables | env.exported-variables |
Pass values to downstream CodePipeline actions |
env:
variables:
ENVIRONMENT: "production"
parameter-store:
API_ENDPOINT: "/app/prod/api-endpoint"
secrets-manager:
DB_PASSWORD: "prod/db:password"
exported-variables:
- IMAGE_TAG
- BUILD_VERSION
Never hardcode secrets in buildspec.yml. Pull them from Parameter Store or Secrets Manager. And resist the urge to leave echo $DB_PASSWORD lines in for debugging, they end up in CloudWatch.
6-3. Built-in environment variables
| Variable | Contents |
|---|---|
CODEBUILD_BUILD_ID |
Unique build ID |
CODEBUILD_BUILD_NUMBER |
Build number |
CODEBUILD_SOURCE_VERSION |
The requested source version |
CODEBUILD_RESOLVED_SOURCE_VERSION |
Resolved commit hash |
CODEBUILD_SRC_DIR |
Source code directory |
CODEBUILD_WEBHOOK_HEAD_REF |
Branch ref from a webhook trigger |
Using a short slice of CODEBUILD_RESOLVED_SOURCE_VERSION as the Docker image tag makes it trivial to trace any artifact back to a commit.
6-4. Cache
| Kind | Trait | Caveat |
|---|---|---|
| S3 cache | Easy to share across projects | Pays the cost of S3 round-trips |
| Local cache | Fast on the same host | Cold when the host changes |
Local cache supports source cache, Docker layer cache, and custom cache. Docker layer caching requires Linux and privileged mode.
cache:
paths:
- '/root/.cache/pip/**/*'
- 'node_modules/**/*'
- '/root/.m2/**/*'
6-5. Building Docker images and pushing to ECR
version: 0.2
phases:
pre_build:
commands:
- echo "Logging in to ECR"
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ECR_REPO
- IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
build:
commands:
- echo "Building the Docker image"
- docker build -t $ECR_REPO:$IMAGE_TAG .
- docker tag $ECR_REPO:$IMAGE_TAG $ECR_REPO:latest
post_build:
commands:
- echo "Pushing the Docker image"
- docker push $ECR_REPO:$IMAGE_TAG
- docker push $ECR_REPO:latest
- printf '[{"name":"app","imageUri":"%s"}]' $ECR_REPO:$IMAGE_TAG > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
Pushing to ECR requires the ECR-related permissions on the CodeBuild service role.
6-6. Batch builds and reports
Batch builds let you run multiple environment combinations in parallel or build a dependency graph of related builds.
| Feature | Example |
|---|---|
| Build matrix | Test on Node.js 20, 22, and 24 in parallel |
| Build graph | Run unit and integration tests in parallel after the main build |
| Reports | JUnit XML, Cucumber JSON, TRX, TestNG, NUnit |
reports:
pytest-reports:
files:
- 'test-results.xml'
base-directory: 'reports'
file-format: JUNITXML
Once test results land as a report, the CodeBuild console gives you pass/fail/skip counts and trend graphs for free.
6-7. Webhook-driven builds
CodeBuild can subscribe to webhooks on its own. Trigger events include push, pull request creation, and pull request updates. Branch and path filters keep useless builds out of the queue.
| Filter | Example |
|---|---|
| Branch | refs/heads/main |
| Pull Request |
PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED
|
| Path | Include src/**, exclude docs/**
|
7. CodeDeploy fundamentals
7-1. What CodeDeploy is
AWS CodeDeploy automates deployments to EC2, on-premises hosts, ECS, and Lambda.
| Target | Agent | Common strategies |
|---|---|---|
| EC2, on-premises | Required | In-Place, Blue/Green |
| ECS | Not required | Blue/Green, Canary, Linear, AllAtOnce |
| Lambda | Not required | Canary, Linear, AllAtOnce |
For EC2 and on-prem, the CodeDeploy Agent runs on the instance and executes the steps in appspec.yml.
7-2. Key components
| Component | Description |
|---|---|
| Application | Logical container for a deployable thing |
| Deployment group | The set of instances or ECS services it targets |
| Deployment configuration | How many or what percentage to roll at a time |
| Revision | The deployable artifact |
appspec.yml |
File layout, hooks, and target resources |
| CodeDeploy Agent | Runs on EC2 or on-prem hosts |
7-3. appspec.yml for EC2
version: 0.0
os: linux
files:
- source: /
destination: /var/www/html
permissions:
- object: /var/www/html
owner: apache
group: apache
mode: 755
type:
- directory
hooks:
ApplicationStop:
- location: scripts/stop_server.sh
timeout: 120
runas: root
BeforeInstall:
- location: scripts/install_dependencies.sh
timeout: 120
runas: root
AfterInstall:
- location: scripts/after_install.sh
timeout: 120
runas: root
ApplicationStart:
- location: scripts/start_server.sh
timeout: 120
runas: root
ValidateService:
- location: scripts/validate_service.sh
timeout: 120
runas: root
files defines the destination, permissions sets ownership, and hooks wires lifecycle events to scripts.
7-4. Lifecycle events
An In-Place deployment runs the following events in order:
ApplicationStop
DownloadBundle
BeforeInstall
Install
AfterInstall
ApplicationStart
ValidateService
CodeDeploy handles DownloadBundle and Install itself. The hook scripts you write live in the other events.
8. Deploying to EC2
8-1. Preparing the EC2 side
To deploy with CodeDeploy on EC2, you need an instance role, a CodeDeploy service role, instance tags, and the CodeDeploy Agent.
| Item | Detail |
|---|---|
| EC2 instance role | Permission to fetch revisions from S3, plus SSM permissions |
| CodeDeploy service role | Permission to read EC2 tags, ASG, and ELB |
| Tags | Filter to scope which instances are targeted |
| Agent | The on-host process that executes the deployment |
On Amazon Linux 2023, pulling the latest AMI ID from SSM Parameter Store avoids the trap of an AMI ID that quietly goes stale.
AMI_ID=$(aws ssm get-parameters \
--names /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 \
--query 'Parameters[0].Value' \
--output text)
8-2. CodeDeploy Agent
# Fetch the installer
cd /tmp
wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
# Install
chmod +x ./install
sudo ./install auto
# Verify
sudo systemctl status codedeploy-agent
sudo codedeploy-agent --version
If the agent is not running, the deployment will not progress. When things go wrong, check /var/log/aws/codedeploy-agent/ and /opt/codedeploy-agent/deployment-root/.
8-3. Deployment file layout
aws-code-series-demo/
āāā appspec.yml
āāā index.html
āāā scripts/
āāā application_stop.sh
āāā before_install.sh
āāā after_install.sh
āāā application_start.sh
āāā validate_service.sh
#!/bin/bash
echo "Running ValidateService"
sleep 5
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/)
if [ "$HTTP_CODE" = "200" ]; then
echo "Validation passed"
exit 0
else
echo "Validation failed"
exit 1
fi
Always include a ValidateService hook. Detecting trouble here is what lets CodeDeploy fail loudly and roll back cleanly.
8-4. Deployment groups
EC2 deployment groups select target instances by tag or by Auto Scaling Group.
| Setting | Example |
|---|---|
| Application name | code-series-demo-app |
| Deployment group name | code-series-demo-dg |
| Deployment type | In-Place |
| Target | EC2 tag Name=CodeDeploy-Demo
|
| Deployment configuration | CodeDeployDefault.AllAtOnce |
| Rollback | Enabled on deployment failure |
For production, prefer OneAtATime or Blue/Green over AllAtOnce.
8-5. Running the deployment
Once the CodeDeploy application and deployment group exist, kick off a deployment with a specified revision. With GitHub as the revision source, pass the repo and commit ID. Through CodePipeline, the pipeline hands an S3 artifact to CodeDeploy on your behalf.
# Grab the latest commit ID
git rev-parse HEAD
While the deployment runs, watch the progress through ApplicationStop, DownloadBundle, BeforeInstall, Install, AfterInstall, ApplicationStart, and ValidateService. Once ValidateService passes, visit the EC2 public IP or the ALB DNS name to confirm the app works.
http://<EC2 public IP>/
To try an update, bump a version string in index.html, push, and deploy again. To see what failure looks like, deliberately fail validate_service.sh and watch automatic rollback fire.
9. Deployment strategies and rollback
9-1. In-Place vs Blue/Green
| Lens | In-Place | Blue/Green |
|---|---|---|
| Approach | Update the existing environment | Spin up a new environment, swap traffic |
| Downtime | Possible | Largely avoidable |
| Cost | Low | Temporarily higher |
| Rollback | Requires a redeploy | Flip traffic back |
| Pre-test | Hard | Possible via a test listener |
| Best fit | Dev, small footprints | Production, blast-radius-sensitive workloads |
Blue/Green on EC2 leans heavily on load balancer, target group, and Auto Scaling Group design.
9-2. Load balancer integration
For Blue/Green on EC2 with CodeDeploy, the load balancer handles the swap between blue and green. Pair it with an Application Load Balancer or Network Load Balancer.
| Element | Role |
|---|---|
| ALB | Accept HTTP/HTTPS traffic from users |
| Production listener | Serve normal traffic |
| Test listener | Verify the new environment before cutover |
| Target groups | Registered targets for blue and green |
| Auto Scaling Group | Provisions the green environment |
The ALB Blue/Green flow is: build green, verify on the test listener, swap the production listener to green, keep blue around for a while.
Blue
Currently serving production traffic
Green
New version deployed, verified on the test listener
Switch
Repoint the production listener at green
Retain
Keep blue alive for a window so you can roll back fast
9-3. EC2 deployment configurations
| Configuration | Behavior |
|---|---|
CodeDeployDefault.AllAtOnce |
Update all instances at once |
CodeDeployDefault.HalfAtATime |
Update half at a time |
CodeDeployDefault.OneAtATime |
One instance at a time |
| Custom | Specify minimum healthy hosts as a count or percentage |
Production decisions weigh instance count, load balancer, Auto Scaling, and health checks together.
9-4. Automatic rollback
CodeDeploy can roll back automatically on deployment failure or when a CloudWatch alarm fires.
aws cloudwatch put-metric-alarm \
--alarm-name codedeploy-5xx-alarm \
--namespace AWS/ApplicationELB \
--metric-name HTTPCode_Target_5XX_Count \
--statistic Sum \
--period 60 \
--threshold 10 \
--comparison-operator GreaterThanOrEqualToThreshold \
--evaluation-periods 2 \
--treat-missing-data notBreaching
For Blue/Green, hold the old environment for a while instead of decommissioning right away, so cutting back is fast if you need to.
10. Canary deployments to ECS and Lambda
10-1. ECS Blue/Green
With CodeDeploy on ECS the default is Blue/Green. No agent is required. Traffic is swapped via the ALB listener and target groups.
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/my-task:1"
LoadBalancerInfo:
ContainerName: "app"
ContainerPort: 80
Hooks:
- AfterAllowTestTraffic: "arn:aws:lambda:ap-northeast-1:123456789012:function:ecs-test-hook"
A new task set serves the test listener; after verification, the production listener is swapped over.
10-2. ECS deployment configurations
| Configuration | Behavior |
|---|---|
CodeDeployDefault.ECSAllAtOnce |
Cut all traffic at once |
CodeDeployDefault.ECSCanary10Percent5Minutes |
Send 10%, wait 5 minutes, then the rest |
CodeDeployDefault.ECSCanary10Percent15Minutes |
Send 10%, wait 15 minutes, then the rest |
CodeDeployDefault.ECSLinear10PercentEvery1Minutes |
Add 10% every minute |
CodeDeployDefault.ECSLinear10PercentEvery3Minutes |
Add 10% every 3 minutes |
With NLB, only CodeDeployDefault.ECSAllAtOnce is supported among the predefined options.
10-3. Lambda deployments
For Lambda, function versions plus an alias let you shift traffic incrementally.
version: 0.0
Resources:
- myFunction:
Type: AWS::Lambda::Function
Properties:
Name: "my-function"
Alias: "live"
CurrentVersion: "1"
TargetVersion: "2"
Hooks:
- BeforeAllowTraffic: "before-allow-traffic-hook"
- AfterAllowTraffic: "after-allow-traffic-hook"
Lambda supports AllAtOnce, Canary10Percent variants, and Linear10PercentEvery variants. In production, Canary or Linear is easier to roll out safely while you watch metrics.
10-4. ECS and Lambda hooks
Both ECS and Lambda support Lambda hooks for verification before and after the traffic shift.
| Target | Common hook | Use |
|---|---|---|
| ECS | AfterAllowTestTraffic |
Verify the new task set on the test listener |
| ECS | BeforeAllowTraffic |
Final pre-cutover check |
| ECS | AfterAllowTraffic |
Post-cutover verification |
| Lambda | BeforeAllowTraffic |
Pre-traffic-shift check |
| Lambda | AfterAllowTraffic |
Post-traffic-shift metric check |
Hook functions return success or failure. A failure halts the deployment and triggers rollback per configuration.
11. CodePipeline fundamentals
11-1. What CodePipeline is
AWS CodePipeline orchestrates source, build, test, approval, and deployment as connected stages.
| Component | Description |
|---|---|
| Pipeline | The whole workflow |
| Stage | Logical grouping like Source, Build, Deploy |
| Action | A single step inside a stage |
| Artifact | The thing passed between stages |
| Transition | The handoff between stages |
11-2. Source, build, and deploy providers
| Category | Common providers |
|---|---|
| Source | CodeCommit, GitHub, GitLab, Bitbucket, S3, ECR |
| Build | CodeBuild, Jenkins |
| Test | CodeBuild, Manual approval, Lambda Invoke |
| Deploy | CodeDeploy, CloudFormation, ECS, S3, Elastic Beanstalk, AppConfig |
| Invoke | Lambda |
With GitHub, the Source action references a CodeConnections connection.
11-3. V1 vs V2
| Lens | V1 | V2 |
|---|---|---|
| Pricing | Per active pipeline | Per action-minute |
| Trigger filters | Not supported | Supported |
| Pipeline-level variables | Not supported | Supported |
| Git tag triggers | Not supported | Supported |
| PR, branch, path filters | Not supported | Supported |
| Stage conditions | Not supported | Supported |
| Stage rollback | Not supported | Supported |
For new pipelines, V2 is the default. For typical workloads running a moderate number of times per month, V2 can also work out cheaper.
11-4. Pricing notes
CodePipeline V1 is billed monthly per active pipeline. V2 is billed per action-minute, excluding manual approvals and custom actions.
| Type | Free tier |
|---|---|
| V1 | 1 active pipeline per month |
| V2 | 100 action-minutes per month |
For example, a V2 pipeline that runs Source, Build, and Deploy for 2 minutes each comes out to roughly 6 action-minutes per run. The real billing rounds per action, so always check the latest pricing page for the actual rules.
12. CodePipeline V2 in practice
12-1. Trigger filters
V2 lets you gate connection-based sources (like GitHub) on branch, tag, file path, or pull request conditions.
| Filter | Example |
|---|---|
| Branch |
main, release/*
|
| Tag | Match v*, exclude *-beta
|
| File path | Only when src/** changes |
| Pull request | Created, updated, closed |
To keep documentation-only changes from triggering production pipelines, exclude docs/** and *.md.
12-2. Pipeline variables
| Kind | Example |
|---|---|
| Pipeline-level variables | DEPLOY_ENV=staging |
| Action output variables |
IMAGE_TAG from CodeBuild |
| Namespaced variables | #{SourceVariables.CommitId} |
To pass values from CodeBuild downstream, use exported-variables.
env:
exported-variables:
- IMAGE_TAG
phases:
build:
commands:
- IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- echo "IMAGE_TAG=$IMAGE_TAG"
12-3. Manual approval
Always put a Manual approval action in front of production.
| Setting | Detail |
|---|---|
| SNS notification | Send the approval request to email or chat |
| Review URL | Link to staging, change set, or dashboard |
| Comment | Capture reason on approve or reject |
| Timeout | Up to 7 days |
aws codepipeline put-approval-result \
--pipeline-name my-pipeline \
--stage-name Approval \
--action-name ManualApproval \
--token <approval-token> \
--result summary="LGTM",status=Approved
12-4. Notifications and EventBridge
CodePipeline state changes flow through EventBridge. Trigger a Lambda on failure, or push to SNS or AWS Chatbot.
aws events put-rule \
--name codepipeline-failed-rule \
--event-pattern '{
"source": ["aws.codepipeline"],
"detail": {
"state": ["FAILED"]
}
}'
A clean split is SNS for approval-style notifications and EventBridge + Chatbot for pipeline-wide failure alerts.
SNS is well suited to emailing reviewers. For Slack or Microsoft Teams, pair AWS Chatbot with an SNS topic.
# Create an SNS topic
aws sns create-topic \
--name codepipeline-approval-topic
# Subscribe an email address
aws sns subscribe \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:codepipeline-approval-topic \
--protocol email \
--notification-endpoint reviewer@example.com
12-5. JSON definitions and IaC management
Console-built pipelines can be exported as JSON and version-controlled.
# Export the pipeline definition
aws codepipeline get-pipeline --name my-pipeline > pipeline.json
# Create from JSON
aws codepipeline create-pipeline --cli-input-json file://pipeline.json
# Update an existing pipeline
aws codepipeline update-pipeline --cli-input-json file://pipeline.json
In production, manage the pipeline itself with CloudFormation, CDK, or Terraform.
12-6. From staging to production
Pipelines that touch production deploy to staging first, validate, and then promote.
Source
Build
DeployToStaging
SmokeTest
ManualApproval
DeployToProduction
PostDeployCheck
Pack the manual approval request with everything the reviewer needs: staging URL, change summary, commit ID, CodeBuild test report, CloudFormation change set. The reviewer must be able to answer "what am I approving?".
13. Advanced pipeline design
13-1. Multi-stage layouts
Real pipelines almost never go Build straight to production. Insert multiple stages.
Source
Build
UnitTest
IntegrationTest
DeployToStaging
Approval
DeployToProduction
Separating responsibilities makes failures easy to localize.
13-2. Parallel actions
Within a stage, actions with the same runOrder run in parallel.
runOrder 1: UnitTest, Lint, SecurityScan
runOrder 2: SmokeTest
Parallelizing tests cuts wall-clock time. When actions have artifact dependencies, split them across runOrder values.
13-3. Multiple sources and artifacts
When the front end and back end, or the app and infra, live in separate repos, use multiple Source actions.
version: 0.2
phases:
build:
commands:
- echo "Main source is at $CODEBUILD_SRC_DIR"
- echo "Infra source is at $CODEBUILD_SRC_DIR_infra"
artifacts:
secondary-artifacts:
app-artifact:
files:
- '**/*'
base-directory: dist
cfn-artifact:
files:
- '**/*'
base-directory: infra
Name artifacts clearly. Downstream actions will reference them.
13-4. CloudFormation integration
CodePipeline supports a CloudFormation deploy action.
| Action mode | Use |
|---|---|
CREATE_UPDATE |
Create or update a stack directly |
DELETE_ONLY |
Delete a stack |
REPLACE_ON_FAILURE |
Replace a failed stack |
CHANGE_SET_CREATE |
Create a change set |
CHANGE_SET_EXECUTE |
Execute a change set |
For safe production rollouts, do CHANGE_SET_CREATE, then manual approval, then CHANGE_SET_EXECUTE.
AWSTemplateFormatVersion: "2010-09-09"
Description: Simple S3 bucket for the CodePipeline demo
Resources:
DemoBucket:
Type: AWS::S3::Bucket
Properties:
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
Running CloudFormation directly is fine, but the change-set-then-approve-then-execute pattern is safer for production.
13-5. Cross-account deployment
When the dev account's CodePipeline deploys into a production account, design S3, KMS, AssumeRole, and the target-service permissions across accounts.
| Element | Setup |
|---|---|
| Dev account S3 | Allow access from the production role |
| Dev account KMS | Grant decrypt to the production role |
| Production account IAM | Role assumable by CodePipeline |
| Production account targets | CodeDeploy, CloudFormation, ECS, etc. |
Set roleArn on the Deploy action in the production account to point at the cross-account role.
13-6. Cross-region and Lambda Invoke
For cross-region deployments, set region on the action. Each region needs its own artifact store.
Lambda Invoke actions are great for Slack notifications, DB migrations, external API calls, and pre-deploy checks.
import boto3
codepipeline = boto3.client("codepipeline")
def lambda_handler(event, context):
job_id = event["CodePipeline.job"]["id"]
try:
# Custom logic goes here
codepipeline.put_job_success_result(jobId=job_id)
except Exception as exc:
codepipeline.put_job_failure_result(
jobId=job_id,
failureDetails={
"type": "JobFailed",
"message": str(exc)
}
)
Always send either success or failure back to CodePipeline. Without it, the action waits until it times out.
14. Building a CI/CD pipeline from scratch
14-1. The setup
The reference setup in this article uses GitHub, CodePipeline V2, CodeBuild, CodeDeploy, and EC2.
flowchart LR
G[GitHub] --> P[CodePipeline V2]
P --> S[Source]
S --> B[CodeBuild]
B --> D[CodeDeploy]
D --> E[EC2 Apache]
B --> A[(S3 Artifacts)]
14-2. Resources you will create
| Category | Resources |
|---|---|
| Source | GitHub repo, CodeConnections |
| Build | CodeBuild project, CloudWatch Logs |
| Artifacts | S3 artifact bucket |
| Deploy | CodeDeploy application, deployment group |
| Runtime | EC2, security group, IAM instance profile |
| Orchestration | CodePipeline V2 |
| Permissions | EC2, CodeBuild, CodeDeploy, CodePipeline roles |
14-3. Repository layout
aws-code-series-handson/
āāā buildspec.yml
āāā appspec.yml
āāā index.html
āāā css/
ā āāā style.css
āāā js/
ā āāā app.js
āāā tests/
ā āāā test_app.sh
āāā scripts/
āāā install_dependencies.sh
āāā stop_server.sh
āāā start_server.sh
āāā validate_service.sh
buildspec.yml runs the tests and emits the artifact for CodePipeline. appspec.yml defines the on-EC2 layout and lifecycle scripts.
14-4. buildspec.yml
version: 0.2
phases:
install:
commands:
- echo "Preparing dependencies"
- chmod +x tests/test_app.sh
- chmod +x scripts/*.sh
pre_build:
commands:
- echo "Running tests"
- ./tests/test_app.sh
build:
commands:
- echo "Producing artifacts"
post_build:
commands:
- echo "Build complete"
artifacts:
files:
- '**/*'
14-5. appspec.yml
version: 0.0
os: linux
files:
- source: /
destination: /var/www/html
hooks:
BeforeInstall:
- location: scripts/install_dependencies.sh
timeout: 300
runas: root
ApplicationStop:
- location: scripts/stop_server.sh
timeout: 300
runas: root
ApplicationStart:
- location: scripts/start_server.sh
timeout: 300
runas: root
ValidateService:
- location: scripts/validate_service.sh
timeout: 300
runas: root
14-6. Validating the flow
| Scenario | Expected result |
|---|---|
| Healthy commit | Source, Build, Deploy all succeed after push |
| Failed test | Build halts, no Deploy |
| Failed deploy | Deploy fails, rollback if configured |
| Manual re-run |
start-pipeline-execution re-triggers |
| Stage retry | Retry only the failed stage |
# Check pipeline state
aws codepipeline get-pipeline-state \
--name code-series-demo-pipeline \
--query 'stageStates[*].{Stage:stageName,Status:latestExecution.status}'
# Manual run
aws codepipeline start-pipeline-execution \
--name code-series-demo-pipeline
# Retry only the failed actions
aws codepipeline retry-stage-execution \
--pipeline-name code-series-demo-pipeline \
--stage-name Deploy \
--pipeline-execution-id <execution-id> \
--retry-mode FAILED_ACTIONS
14-7. Cleanup
Wrong delete order will leave you blocked by dependencies.
CodePipeline
CodeDeploy deployment group
CodeDeploy application
CodeBuild project
EC2 instance
Security group
S3 bucket objects
S3 bucket
IAM instance profile
IAM role
CodeConnections connection
Empty the S3 bucket before deleting it. Detach the IAM role from the instance profile before deleting the role.
15. Security and IAM design
15-1. CI/CD security layers
flowchart TB
A[IAM and authentication] --> B[Secrets management]
B --> C[S3 and KMS encryption]
C --> D[VPC and network controls]
D --> E[CloudTrail and CloudWatch]
A CI/CD pipeline is a privileged path into production, so it deserves the same level of protection as the application itself.
15-2. Service role design
| Role | Required | Avoid |
|---|---|---|
| CodeBuild | S3, CloudWatch Logs, ECR when needed | Admin permissions, unneeded EC2 access |
| CodeDeploy | EC2 tag read, ELB, ASG, S3 read | EC2 create or delete |
| CodePipeline | CodeBuild start, CodeDeploy start, S3, CodeConnections | Direct server operations |
| EC2 | Fetch revisions from S3, SSM | Admin permissions |
It is tempting to start broad. Just make sure you tighten down after things work.
15-3. A CodeBuild custom policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CloudWatchLogs",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/codebuild/*"
},
{
"Sid": "S3Artifacts",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::my-artifact-bucket",
"arn:aws:s3:::my-artifact-bucket/*"
]
}
]
}
For ECR pushes, add ecr:GetAuthorizationToken, ecr:BatchCheckLayerAvailability, ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, and ecr:PutImage.
15-4. Secrets management
| Approach | Good for | Watch out for |
|---|---|---|
| Plain environment variables | Non-sensitive settings | Never use for secrets |
| SSM Parameter Store | API keys, per-environment values | Use SecureString |
| Secrets Manager | DB credentials | Account for cost and rotation |
| KMS | Encryption keys | Lock down key policies |
CI/CD logs live longer than you think. Never let secrets land in build logs, and watch out for failure-time debug output too.
15-5. Encrypting the artifact bucket
aws s3api put-bucket-encryption \
--bucket my-artifact-bucket \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms"
},
"BucketKeyEnabled": true
}]
}'
Force HTTPS, block unintended public access, and for cross-account use, do not forget the KMS key policy.
16. Cost, monitoring, and logs
16-1. Cost levers
| Target | Optimization |
|---|---|
| CodeBuild | Cache, right-size compute, set timeouts |
| CodePipeline V2 | Branch, tag, and path filters to skip useless runs |
| CodeDeploy | Spin verification EC2 only when needed |
| S3 | Lifecycle rules for old artifacts |
| CloudWatch Logs | Configure retention |
| KMS | Avoid an exploding key count |
For V2, every avoided execution is direct cost savings. Excluding docs/** and README changes from production pipelines pays for itself fast.
16-2. Metrics to watch
| Service | Watch |
|---|---|
| CodeBuild | Build failures, build duration, queue wait |
| CodeDeploy | Deployment failures, rollback counts |
| CodePipeline | Pipeline failures, stage failures, pending approvals |
| EC2, ALB | 5xx, latency, target health |
| S3 | Artifact bucket usage |
For production, alert on even one CodePipeline or CodeDeploy failure.
16-3. Where logs live
| Service | Location |
|---|---|
| CodeBuild | CloudWatch Logs /aws/codebuild/<project>
|
| CodeDeploy Agent | /var/log/aws/codedeploy-agent/ |
| CodeDeploy deployment | /opt/codedeploy-agent/deployment-root/ |
| CodePipeline | CloudTrail, EventBridge, console history |
CloudWatch Logs Insights makes failure searches easy.
fields @timestamp, @message
| filter @message like /ERROR|FAIL|Exception/
| sort @timestamp desc
| limit 50
16-4. Cost monitoring
Set up AWS Budgets to track CodeBuild, CodePipeline, S3, CloudWatch Logs, and KMS spend. The classic hands-on cost traps are forgotten EC2 instances, S3 buckets, CloudWatch Logs, and ECR images.
17. Troubleshooting
17-1. CodeBuild
| Error | Cause | Fix |
|---|---|---|
DOWNLOAD_SOURCE_FAILED |
GitHub connection or repo permission | Check the CodeConnections status |
CLIENT_ERROR |
buildspec.yml syntax |
Look for YAML, indentation, and tab issues |
BUILD_FAILED |
Test failure or missing dependency | Read CloudWatch Logs |
UPLOAD_ARTIFACTS_FAILED |
Insufficient S3 permissions | Check the CodeBuild role's S3 access |
| Docker daemon error | Missing privileged mode | Enable Privileged mode |
| Out of memory | Compute too small | Bump compute size or split tests |
17-2. CodeDeploy
| Error | Cause | Fix |
|---|---|---|
| Agent unresponsive | Agent stopped or not installed | systemctl status codedeploy-agent |
ScriptFailed |
Hook script failure | Read logs under deployment-root
|
ScriptTimedOut |
Timeout too short, or hung process | Extend timeout or fix the script |
HEALTH_CONSTRAINTS |
Not enough healthy instances | Recheck deployment config and health checks |
| S3 403 | EC2 role lacks S3 access | Check role permissions and bucket policy |
| First-deploy ApplicationStop fails | No previous revision | Often expected on the first run |
17-3. CodePipeline
| Error | Cause | Fix |
|---|---|---|
| Source failed | GitHub connection or repo permission | Recheck CodeConnections |
| Build failed | CodeBuild-side failure | Read CodeBuild logs |
| Deploy failed |
appspec, agent, or permission issue |
Read CodeDeploy logs |
| Insufficient permissions | Service role too narrow | Check the CodePipeline role |
| Action configuration error | Action misconfigured | Check provider, artifact, and region |
17-4. CLI you will use a lot
# Block transitions into the Deploy stage
aws codepipeline disable-stage-transition \
--pipeline-name my-pipeline \
--stage-name Deploy \
--transition-type Inbound \
--reason "Maintenance"
# Re-enable transitions
aws codepipeline enable-stage-transition \
--pipeline-name my-pipeline \
--stage-name Deploy \
--transition-type Inbound
# Re-run with a specific commit
aws codepipeline start-pipeline-execution \
--name my-pipeline \
--source-revisions actionName=Source,revisionType=COMMIT_ID,revisionValue=abc1234
18. Patterns and team practices
18-1. Pipeline design patterns
| Pattern | Good for |
|---|---|
| Single branch | Solo work, small experiments |
| Branch-based | Typical team development |
| Multi-account | Organizations that isolate production permissions |
| Microservice-per-pipeline | Independently releasable services |
A branch-based layout is the easiest starting point.
feature/*
Run tests only on pull requests
develop
Auto-deploy to dev
main
Auto-deploy to staging
Manual approval, then auto-deploy to production
release/*
Lock release candidates and verify
18-2. Team rules
| Rule | Detail |
|---|---|
main protection |
No direct push, PR required |
| Review | At least one approval |
| Tests | Required checks must pass before merge |
| Production approval | Manual approval in CodePipeline |
| Rollback | Documented procedure and on-call owner |
| Naming convention | <env>-<service>-<purpose>-pipeline |
| Tagging |
Project, Environment, Owner, CostCenter
|
18-3. Incident response flow
Alert detected
Assess blast radius
Identify root cause
Roll back or pause the pipeline
Apply a workaround
Apply the real fix
Postmortem
When a pipeline fails, do not stop at "fix the failure". Cover detection, notification, rollback, and prevention.
18-4. Pre-flight checklist
| Lens | Check |
|---|---|
| Source | CodeCommit or GitHub, connection method decided |
| Build |
buildspec.yml defines tests and artifacts |
| Deploy |
appspec.yml and hooks are organized |
| Pipeline | V2, trigger filters, manual approval considered |
| Rollback | CodeDeploy paired with a CloudWatch alarm |
| Permissions | Every service role minimized |
| Secrets | Stored in Parameter Store or Secrets Manager |
| Monitoring | EventBridge, SNS, Chatbot, CloudWatch wired up |
| Cost | Wasted runs, log retention, S3 residue under control |
| Operations | Naming, tagging, incident response, cleanup defined |
Wrap-up
Thanks for reading this far.
Looked at one at a time, the AWS Code family is a collection of fairly modest services. CodeCommit handles source. CodeBuild builds. CodeDeploy deploys. CodePipeline glues them together.
The real value shows up when you combine them. A push triggers tests, an artifact is stored, staging gets updated, an approver signs off, production receives the change, failures stop the train, and logs let you find the root cause. Once all of that holds together, CI/CD stops being "nice automation" and becomes "a safe way to release".
As of 2026, CodeCommit's return to GA puts the "fully inside AWS" option back on the table. Pairing GitHub or GitLab with CodeBuild, CodeDeploy, and CodePipeline as the AWS-side runtime is also still very much a real choice.
What matters more than service selection is the shape of the flow: small changes, automated verification, deliberate approval, deliberate rollback, and a system you can learn from when it fails.
See you in the next one.
About this article
This article is the English adaptation of a Japanese post I originally wrote on Qiita, a developer community popular in Japan.
https://qiita.com/miruky/items/REPLACE_WITH_QIITA_ID
References
AWS Code family official docs
- AWS Developer Tools - AWS
- AWS CodeCommit - AWS
- The Future of AWS CodeCommit - AWS DevOps Blog
- AWS CodeBuild User Guide
- AWS CodeBuild pricing
- Build specification reference for CodeBuild - AWS
- Cache builds to improve performance - AWS CodeBuild
- AWS CodeDeploy User Guide
- Working with deployment configurations in CodeDeploy - AWS
- AWS CodePipeline User Guide
- Pipeline types - AWS CodePipeline
- Automate starting pipelines using triggers and filtering - AWS CodePipeline
- AWS CodePipeline pricing
Connections, adjacent services, and operations
- AWS Service Availability Updates - AWS
- Introducing AWS CodeConnections, formerly known as AWS CodeStar Connections - AWS
- Connections rename - AWS Developer Tools console
- CodeStarSourceConnection for GitHub, GitLab, Bitbucket - AWS CodePipeline
- Amazon CodeCatalyst document history
- Amazon CodeGuru Reviewer availability change
- Practicing Continuous Integration and Continuous Delivery on AWS
Top comments (0)