Shipping code to production should be boring. If your deployments are stressful, your pipeline is wrong. A well-designed CI/CD pipeline makes releases routine, reversible, and observable — whether you deploy once a day or fifty times.
AWS provides both native CI/CD services (CodePipeline, CodeBuild, CodeDeploy) and deep integration with third-party tools (GitHub Actions, GitLab CI). The choice depends on your team’s workflow preferences and how much you want to stay inside the AWS ecosystem.
This guide covers the deployment strategies that matter, the pipeline architectures that work, and the decision framework for choosing your CI/CD stack.
Deployment Strategies: How Code Reaches Production
Strategy 1: Rolling Deployment
How it works: Replace instances/tasks gradually. Old and new versions run simultaneously during the transition.
Time 0: [v1] [v1] [v1] [v1] (4 tasks, all v1)
Time 1: [v2] [v1] [v1] [v1] (1 updated)
Time 2: [v2] [v2] [v1] [v1] (2 updated)
Time 3: [v2] [v2] [v2] [v1] (3 updated)
Time 4: [v2] [v2] [v2] [v2] (complete)
Enter fullscreen mode Exit fullscreen mode
Pros: Simple, no extra infrastructure, works everywhere.
Cons: Two versions run simultaneously (must be backward-compatible). Rollback means rolling forward to v1 again.
AWS implementation: ECS rolling update (default), EKS rolling update, EC2 Auto Scaling group instance refresh.
Strategy 2: Blue/Green Deployment
How it works: Deploy new version (green) alongside old version (blue). Switch traffic atomically. Keep blue alive for instant rollback.
┌─────────────────┐ ┌─────────────────┐
│ BLUE (v1) │ │ GREEN (v2) │
│ (serving) │ │ (staged) │
└────────┬────────┘ └────────┬────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────┐
│ ALB / Route53 │
│ 100% → Blue (until cutover) │
│ Then: 100% → Green │
└─────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode
Pros: Zero downtime. Instant rollback (switch traffic back to blue). Full testing on green before cutover.
Cons: 2x infrastructure during deployment (cost). Database schema changes need careful handling.
AWS implementation:
- ECS native blue/green (GA July 2025) — built into ECS service, no CodeDeploy needed
- CodeDeploy blue/green for ECS (original approach)
- Route53 weighted routing (for broader blue/green)
- ALB target group swap
Strategy 3: Canary Deployment
How it works: Route a small percentage of traffic (1-10%) to the new version. Monitor errors. If healthy, gradually shift more traffic. If unhealthy, route all traffic back to old version.
Step 1: 95% → v1, 5% → v2 (canary)
Step 2: 70% → v1, 30% → v2 (expanding)
Step 3: 50% → v1, 50% → v2 (halfway)
Step 4: 0% → v1, 100% → v2 (complete)
Enter fullscreen mode Exit fullscreen mode
Pros: Minimal blast radius. Real production traffic validates new version. Automatic rollback on alarm.
Cons: Complex routing. Must handle session affinity. Slower than blue/green.
AWS implementation:
- ECS native canary/linear (GA October 2025) — percentage-based traffic shifting built into ECS
- CodeDeploy canary (Lambda, ECS)
- App Mesh / VPC Lattice (weighted routing between versions)
- ALB weighted target groups
Strategy 4: Feature Flags (Decouple Deploy from Release)
How it works: Deploy code with new features disabled. Enable features independently via configuration (not deployment). Rollback = toggle flag off.
AWS implementation: AppConfig feature flags (native), LaunchDarkly, or custom DynamoDB-backed flags.
Benefit: Deploy anytime. Release (enable feature) separately. Different features for different users (A/B testing).
ECS Native Deployment Capabilities (2025-2026)
ECS received major deployment upgrades — eliminating the need for CodeDeploy in most container scenarios:
Feature Release What It Does Native blue/green July 2025 Built-in blue/green without CodeDeploy Linear/canary October 2025 Percentage-based traffic shifting NLB support for linear/canary February 2026 Canary for TCP/gRPC workloads Pause/continue May 2026 Pause deployment for manual validation Configurable circuit breaker July 2026 Custom failure thresholds for auto-rollbackECS Deployment Configuration
{
"deploymentConfiguration": {
"deploymentType": "BLUE_GREEN",
"blueGreenDeploymentConfiguration": {
"trafficRoutingConfig": {
"type": "CANARY",
"canaryConfig": {
"interval": 300,
"percentage": 10
}
},
"terminationWaitTimeInMinutes": 60,
"deploymentCircuitBreaker": {
"enable": true,
"rollback": true,
"failureThreshold": 5
}
}
}
}
Enter fullscreen mode Exit fullscreen mode
This deploys with 10% canary, waits 5 minutes, then shifts remaining traffic. If 5+ tasks fail health checks, automatic rollback triggers.
Pipeline Architecture: AWS-Native Stack
AWS CodePipeline + CodeBuild + CodeDeploy
┌──────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ Source │────→│ Build │────→│ Test │────→│ Deploy │
│(CodeCommit│ │(CodeBuild)│ │(CodeBuild)│ │(CodeDeploy│
│ or GitHub)│ │ │ │ │ │ or ECS) │
└──────────┘ └───────────┘ └───────────┘ └───────────┘
Enter fullscreen mode Exit fullscreen mode
CodePipeline: Orchestrates the pipeline stages. Triggers on source change.
CodeBuild: Runs build commands, tests, security scans in managed containers.
CodeDeploy: Handles deployment strategies (rolling, blue/green, canary).
Pipeline Stages Best Practice
Source → Build → Unit Test → SAST Scan → Container Scan →
Deploy Dev → Integration Test → Deploy Staging →
Load Test → Manual Approval → Deploy Production
Enter fullscreen mode Exit fullscreen mode
Multi-Account Pipeline Pattern
Tooling Account (pipeline lives here)
│
├── Deploy → Dev Account (automatic)
├── Deploy → Staging Account (automatic + integration tests)
└── Deploy → Production Account (manual approval gate)
Enter fullscreen mode Exit fullscreen mode
Cross-account deployment uses IAM roles. Pipeline in tooling account assumes role in target account to deploy.
Pipeline Architecture: GitHub Actions
For teams using GitHub as source control, GitHub Actions provides a complete CI/CD solution with AWS integration:
name: Deploy to ECS
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write # OIDC for AWS auth
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/github-actions-deploy
aws-region: eu-west-1
- uses: aws-actions/amazon-ecr-login@v2
- name: Build and push image
run: |
docker build -t $ECR_REGISTRY/my-app:$GITHUB_SHA .
docker push $ECR_REGISTRY/my-app:$GITHUB_SHA
- uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: task-def.json
service: my-service
cluster: production
wait-for-service-stability: true
Enter fullscreen mode Exit fullscreen mode
GitHub Actions + OIDC (No Long-Lived Credentials)
Use OpenID Connect (OIDC) to authenticate GitHub Actions to AWS — no access keys needed:
- Create IAM Identity Provider for GitHub in AWS
- Create IAM role with trust policy for specific repo/branch
- GitHub Actions exchanges OIDC token for temporary AWS credentials
Security: Credentials are short-lived (1 hour), scoped to specific repos, and never stored as secrets.
CodePipeline vs GitHub Actions vs GitLab CI
Criteria CodePipeline GitHub Actions GitLab CI Source integration CodeCommit, GitHub, S3, ECR GitHub (native) GitLab (native) Build CodeBuild (managed) Hosted runners or self-hosted Shared or self-hosted runners AWS integration Deep (native IAM, VPC, cross-account) Good (via aws-actions, OIDC) Good (via CLI, OIDC) Deployment strategies CodeDeploy (full support) Manual (scripts + AWS CLI) Manual (scripts + AWS CLI) Pricing Free pipeline + CodeBuild minutes ($0.005/min) 2000 free min/month, then $0.008/min 400 free min/month, then $0.005/min Ecosystem AWS-only 20K+ marketplace actions 500+ templates Multi-cloud ❌ ✅ ✅ Pipeline as code YAML or console YAML (.github/workflows/)
YAML (.gitlab-ci.yml)
Approval gates
Manual approval action
Environment protection rules
Manual jobs
Best for
AWS-native teams, complex deployment strategies
Teams on GitHub, multi-cloud
Teams on GitLab, self-hosted preference
When to Choose What
- CodePipeline: You want native blue/green/canary via CodeDeploy, cross-account deployment patterns, or deep AWS integration without custom scripting.
- GitHub Actions: Your code lives on GitHub, team prefers GitHub’s ecosystem, and you want multi-cloud flexibility.
- GitLab CI: Your code lives on GitLab, you want self-hosted runners, or you need built-in security scanning (SAST/DAST).
Security in the Pipeline
Shift-Left Security
Stage Tool What It Catches Pre-commit git-secrets, talisman Hardcoded credentials before they enter repo Build SAST (CodeGuru, Snyk, Semgrep) Code vulnerabilities (SQL injection, XSS) Build SCA (Dependabot, Snyk) Vulnerable dependencies Container Build ECR image scanning, Trivy Container CVEs Pre-Deploy IAM policy validation (IAM Access Analyzer) Over-privileged roles Post-Deploy DAST (OWASP ZAP) Runtime vulnerabilitiesPipeline Security Best Practices
- No long-lived credentials — use OIDC (GitHub) or IAM roles (CodeBuild)
- Least privilege — pipeline role can only deploy to specific services/accounts
- Artifact signing — sign container images (cosign / Notation) to ensure integrity
-
Immutable artifacts — tag images with git SHA, never overwrite
:latestin production - Approval gates — require human approval before production deployment
- Audit trail — CloudTrail logs all deployment actions
Deployment Observability
A deployment isn’t done when the pipeline turns green. Monitor after deploy:
Post-Deploy Validation
Deploy v2 → Wait 5 min → Check:
├── Error rate increased? → Rollback
├── Latency p99 > threshold? → Rollback
├── Health check failures? → Rollback
└── All green → Deployment successful
Enter fullscreen mode Exit fullscreen mode
CloudWatch Alarms as Deployment Gates
Configure CodeDeploy / ECS circuit breaker to monitor CloudWatch alarms:
- If alarm triggers during canary/linear deployment → automatic rollback
- No human intervention needed for obvious failures
Common Pipeline Anti-Patterns
Anti-Pattern Problem Fix No staging environment Bugs found in production Always deploy to staging first Tests only in CI, not in deployment Broken integration passes build Run integration tests post-deploy Manual deployment to production Error-prone, unauditable Automate everything, gate with approval Same pipeline for all environments No quality gates between stages Multi-stage with promotion (dev → staging → prod):latest tag in production
Can’t tell which version is running
Use git SHA or semantic version tags
Secrets in pipeline code
Credential exposure
Use OIDC, Secrets Manager, or Parameter Store
No rollback plan
Stuck with broken deployment
Blue/green or canary with auto-rollback
Summary
CI/CD on AWS comes down to three decisions:
- Deployment strategy — Rolling (simple), Blue/Green (zero-downtime), Canary (lowest risk), or Feature Flags (decouple deploy from release)
- Pipeline tool — CodePipeline (AWS-native, deep integration), GitHub Actions (flexible, multi-cloud), or GitLab CI (self-hosted, built-in security)
- Safety mechanisms — Approval gates, CloudWatch alarm-based rollback, immutable artifacts, shift-left security scanning
The 2026 default for containers: ECS native blue/green with canary traffic shifting + configurable circuit breaker. No CodeDeploy needed for standard ECS workloads.
The 2026 default for pipeline: GitHub Actions with OIDC auth for most teams. CodePipeline when you need native cross-account patterns or CodeDeploy’s advanced strategies.
Alpesh Kumbhare is an AWS Architect at Atos, specializing in AWS infrastructure automation and DevOps practices. Connect on LinkedIn.