DEV Community

miruky
miruky

Posted on

A Field Guide to AWS CI/CD: CodeBuild, CodeDeploy, and CodePipeline End to End

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

  1. CI/CD fundamentals
  2. The AWS Code family at a glance
  3. Source control and where CodeCommit stands now
  4. GitHub and CodeConnections setup
  5. CodeBuild fundamentals
  6. buildspec.yml in practice
  7. CodeDeploy fundamentals
  8. Deploying to EC2
  9. Deployment strategies and rollback
  10. Canary deployments to ECS and Lambda
  11. CodePipeline fundamentals
  12. CodePipeline V2 in practice
  13. Advanced pipeline design
  14. Building a CI/CD pipeline from scratch
  15. Security and IAM design
  16. Cost, monitoring, and logs
  17. Troubleshooting
  18. 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]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)}")
Enter fullscreen mode Exit fullscreen mode
# 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()
Enter fullscreen mode Exit fullscreen mode

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}'
Enter fullscreen mode Exit fullscreen mode

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:
    - '**/*'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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/**/*'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
#!/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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>/
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"]
    }
  }'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
            }
        )
Enter fullscreen mode Exit fullscreen mode

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)]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:
    - '**/*'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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/*"
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

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
    }]
  }'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Connections, adjacent services, and operations

Top comments (0)