Skip to content

Latest commit

 

History

History
397 lines (304 loc) · 11.3 KB

File metadata and controls

397 lines (304 loc) · 11.3 KB

CI/CD — CodeCommit, CodeBuild, CodeDeploy, CodePipeline

The Big Picture

AWS CI/CD pipeline is a chain of four services:

Code → CodeCommit → CodeBuild → CodeDeploy → Production
       (source)     (build/test) (deploy)     

Orchestrator: CodePipeline ties them all together

Real-World: Developer pushes code → CodePipeline detects change → CodeBuild runs tests + builds Docker image → CodeDeploy rolls it out to EC2/ECS/Lambda with blue/green deployment.


CodeCommit

What it is: Fully managed Git repository hosting (like GitHub, but on AWS).

  • Private Git repositories
  • IAM-integrated (no separate username/password needed)
  • Encrypts at rest (KMS) and in transit (HTTPS/SSH)
  • Triggers: send events to Lambda/SNS on push, PR, branch creation

Authentication

Method Use case
HTTPS + Git credentials IAM username/password (generated per user)
SSH keys Upload public key to IAM user
AWS CLI credential helper For EC2 instances with IAM roles

Key: IAM policies control CodeCommit access — no separate permissions system.

Cross-Account Repository Access

User in Account B needs access to repo in Account A:

  1. Account A creates IAM role with CodeCommit permissions
  2. Account A trust policy allows Account B users to assume the role
  3. Account B user assumes the role → accesses repo

Notification Rules vs Triggers:

  • Notification rules: for collaboration (PR comments, approvals) → SNS
  • Triggers: for automation (push, PR merge) → Lambda/SNS

CodeBuild

What it is: Fully managed CI build service. No servers to manage. You define build steps in buildspec.yml.

buildspec.yml

version: 0.2

env:
  variables:
    ENVIRONMENT: production
  parameter-store:
    DB_PASSWORD: /app/prod/db-password   # from SSM Parameter Store
  secrets-manager:
    API_KEY: prod/api-key:key            # from Secrets Manager

phases:
  install:
    runtime-versions:
      nodejs: 18
    commands:
      - npm install

  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)

  build:
    commands:
      - npm test
      - docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$COMMIT_HASH .
      - docker push $ECR_REGISTRY/$ECR_REPOSITORY:$COMMIT_HASH

  post_build:
    commands:
      - echo Build completed on `date`
      - # Create imagedefinitions.json for CodeDeploy to ECS
      - printf '[{"name":"app","imageUri":"%s"}]' $ECR_REGISTRY/$ECR_REPOSITORY:$COMMIT_HASH > imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json
    - appspec.yml
    - scripts/**/*

cache:
  paths:
    - node_modules/**/*   # Cache node_modules between builds

Build Environments

CodeBuild runs in Docker containers:

  • AWS-managed images: Ubuntu, Amazon Linux 2 (pre-built for common languages)
  • Custom Docker image: bring your own ECR image
  • Runs inside VPC (optional): for accessing private RDS, ElastiCache

CodeBuild Caching

Cache Type Where stored Use case
Local Build container (same container) Fastest, same build only
S3 S3 bucket Cross-build caching, node_modules
Amazon CodeBuild layer Build environment layers Docker layers

VPC Access

If build needs to access private resources:

# CodeBuild project VPC configuration
VpcConfig:
  VpcId: vpc-abc123
  Subnets: [subnet-private-1, subnet-private-2]
  SecurityGroupIds: [sg-build-servers]

Environment Variables Priority

  1. CodeBuild API (override at run time)
  2. buildspec.yml env/variables
  3. Project-level settings

Never put secrets in buildspec.yml variables — use Parameter Store or Secrets Manager.


CodeDeploy

What it is: Automated deployment service to EC2, on-premises, Lambda, or ECS.

Deployment Targets

Target Deployment Types
EC2/On-premises In-place, Blue/Green
Lambda Canary, Linear, All-at-once
ECS Blue/Green only

appspec.yml — The Deployment Blueprint

EC2 appspec.yml:

version: 0.0
os: linux
files:
  - source: /app
    destination: /var/www/app
  - source: /config/nginx.conf
    destination: /etc/nginx/nginx.conf

permissions:
  - object: /var/www/app
    owner: www-data
    group: www-data

hooks:
  BeforeInstall:
    - location: scripts/stop_server.sh
      timeout: 30
  AfterInstall:
    - location: scripts/install_dependencies.sh
      timeout: 60
  ApplicationStart:
    - location: scripts/start_server.sh
      timeout: 30
  ValidateService:
    - location: scripts/health_check.sh
      timeout: 30

Lambda appspec.yml:

version: 0.0
Resources:
  - MyLambdaFunction:
      Type: AWS::Lambda::Function
      Properties:
        Name: checkout-function
        Alias: prod
        CurrentVersion: 5
        TargetVersion: 6
Hooks:
  BeforeAllowTraffic: ValidateNewVersion
  AfterAllowTraffic: ValidateAfterDeployment

Deployment Hook Lifecycle (EC2)

ApplicationStop (stop old app)
DownloadBundle (download from S3/GitHub)
BeforeInstall (prep work)
Install (copy files)
AfterInstall (configure)
ApplicationStart (start new app)
ValidateService (health check)
BeforeBlockTraffic / BlockTraffic / AfterBlockTraffic (Blue/Green only)
BeforeAllowTraffic / AllowTraffic / AfterAllowTraffic (Blue/Green only)

Deployment Strategies

EC2 In-Place:

All at once: stop old → deploy new → restart (downtime!)
Rolling: deploy to N instances at a time
Rolling with additional batch: launch extra instances first

Blue/Green (EC2):

Blue (current): Auto Scaling Group v1
Green (new): new ASG created with v2
LB shifts traffic from Blue to Green
Blue decommissioned (or kept for rollback)

Lambda Canary:

10Percent10Minutes: 10% traffic to new version for 10 min, then 100%
Linear10PercentEvery1Minute: add 10% every minute until 100%
AllAtOnce: instant switchover

ECS Blue/Green:

  • Creates new task set with new Docker image
  • Route traffic gradually or all-at-once
  • If health check fails → automatic rollback

Auto Rollback

{
  "autoRollbackConfiguration": {
    "enabled": true,
    "events": ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_ALARM"]
  }
}

Set CloudWatch alarm on error rate → CodeDeploy auto-rolls back if alarm triggers.


CodePipeline

What it is: Orchestrator for CI/CD workflow. Connects source → build → test → deploy.

Pipeline Structure

Stage 1: Source
  └── Action: CodeCommit (watch 'main' branch)

Stage 2: Build
  └── Action: CodeBuild (run tests + build artifact)

Stage 3: Staging Deploy
  └── Action: CodeDeploy (deploy to staging)

Stage 4: Manual Approval
  └── Action: Manual (someone clicks approve in console/email)

Stage 5: Production Deploy
  └── Action: CodeDeploy (deploy to production)

Action Types

Category Actions
Source CodeCommit, GitHub, ECR, S3
Build CodeBuild, Jenkins
Test CodeBuild, Device Farm, third-party
Deploy CodeDeploy, CloudFormation, Elastic Beanstalk, ECS, S3
Invoke Lambda
Approval Manual approval

Parallel Actions

Stages can have parallel actions:

Stage: Test
├── Action: Unit Tests (CodeBuild) ─┐
├── Action: Integration Tests       ├── Run simultaneously
└── Action: Security Scan (CodeBuild) ┘
All must pass before next stage

Artifacts Flow

Source Stage → produces artifact (source code) → stored in S3
Build Stage → takes source artifact → produces build artifact (JAR/Docker image ref)
Deploy Stage → takes build artifact → deploys

All artifacts encrypted with KMS, stored in S3.

Cross-Account Pipelines

Account: Tools (CodePipeline lives here)
          ↓
Account: Dev (CodeDeploy deploys here)
Account: Prod (CodeDeploy deploys here)

Requires cross-account IAM roles and KMS key policies.

Notifications

Pipeline events → EventBridge → SNS → email/Slack
                             → Lambda → custom workflow

CodeArtifact

What it is: Managed artifact repository (npm, pip, Maven, NuGet packages).

Developers → CodeArtifact (private packages) ← proxies → npm/PyPI/Maven public
            → CodeBuild (uses packages from CodeArtifact)

Why: Control which packages your team can use. Cache public packages internally. Share private packages across accounts.


Good Practices

Practice Reason
Never put secrets in buildspec.yml Exposed in build logs
Use blue/green for zero-downtime deploys Roll forward or back without downtime
Require manual approval before prod Human check before production changes
Set auto-rollback triggers on CloudWatch alarms Fast recovery from bad deploys
Cache dependencies in CodeBuild Faster builds = faster feedback
Use CodePipeline artifact encryption with CMK Compliance, audit trail
Run parallel tests in CodeBuild Faster pipeline

Bad Practices

Anti-Pattern Impact Fix
Deploying directly to prod without staging Breaking changes in production Add staging stage with integration tests
No rollback strategy Downtime when deploy fails Configure auto-rollback
Running CodeBuild without VPC when accessing private resources Build fails, security gaps Configure VPC for CodeBuild
Storing artifacts in same account as production Blast radius if tools account compromised Separate accounts
No manual approval before prod Accidental bad deploys Add approval action

Exam Tips

  1. CodeDeploy appspec.yml defines the deployment. Must be at root of repository.
  2. CodeBuild buildspec.yml defines the build. Can override location.
  3. Lambda deployments: CodeDeploy handles canary/linear shifts — NOT CodePipeline.
  4. EC2 CodeDeploy: requires CodeDeploy Agent running on instances.
  5. CodeDeploy rollback: creates a NEW deployment (reversal), not literally rolling back.
  6. CodePipeline stages must complete in order. Actions within a stage can be parallel.
  7. CodeCommit notifications vs triggers: Notifications = collaboration. Triggers = automation.
  8. S3 as source: CodePipeline can watch an S3 bucket for new ZIP files → trigger pipeline.
  9. Cross-region deployments: CodePipeline supports cross-region actions with regional S3 artifact buckets.

Common Exam Scenarios

Q: Deploy Lambda with 10% traffic for 10 minutes then shift 100%? → CodeDeploy with Canary10Percent10Minutes deployment config.

Q: Build process needs to access private RDS? → Configure CodeBuild VPC to run inside your VPC.

Q: Secrets needed during build? → Store in SSM Parameter Store or Secrets Manager, reference in buildspec.yml env.parameter-store.

Q: Automatic rollback when error rate exceeds 5%? → CodeDeploy auto-rollback + CloudWatch alarm on error rate.

Q: Require human approval before production deployment? → Add Manual Approval action in CodePipeline before production deploy stage.

Q: Pipeline should deploy to multiple regions? → CodePipeline cross-region actions with S3 buckets in each region.