DEV Community

AlpeshKumbhare
AlpeshKumbhare

Posted on

CI/CD on AWS: Deployment Strategies, Pipeline Architectures, and the CodePipeline vs GitHub Actions Decision

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-rollback

ECS 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:

  1. Create IAM Identity Provider for GitHub in AWS
  2. Create IAM role with trust policy for specific repo/branch
  3. 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 vulnerabilities

Pipeline 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 :latest in 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:

  1. Deployment strategy — Rolling (simple), Blue/Green (zero-downtime), Canary (lowest risk), or Feature Flags (decouple deploy from release)
  2. Pipeline tool — CodePipeline (AWS-native, deep integration), GitHub Actions (flexible, multi-cloud), or GitLab CI (self-hosted, built-in security)
  3. 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.

Top comments (0)