CI/CD on AWS
Build a full deployment pipeline from GitHub to EC2 using CodePipeline, CodeBuild, and CodeDeploy.
What You'll Learn
Automate deployments from GitHub to EC2 using AWS's CI/CD trio: CodePipeline, CodeBuild, and CodeDeploy. Push code → tests run → app deploys automatically.
| Azure | AWS | Notes |
|---|---|---|
Azure DevOps Pipeline | CodePipeline | Orchestrates the full flow |
Build Agent | CodeBuild | Managed build environment |
Release Pipeline | CodeDeploy | Deploys to EC2/ASG |
Service Connection | CodeStar Connection | Links to GitHub |
azure-pipelines.yml | buildspec.yml | Build definition file |
Key difference: Azure DevOps bundles build + release into one service. AWS separates them into 3 distinct services (CodePipeline + CodeBuild + CodeDeploy). More modular, but more to configure.
The Pipeline Flow
GitHub Push
│
▼
┌─────────────────────────┐
│ Stage 1: SOURCE │ CodeStar Connection detects push
│ (CodePipeline) │ Downloads source code
└───────────┬─────────────┘
▼
┌─────────────────────────┐
│ Stage 2: BUILD │ Uses buildspec.yml
│ (CodeBuild) │ npm install → npm test → package
└───────────┬─────────────┘
▼
┌─────────────────────────┐
│ Stage 3: DEPLOY │ Uses appspec.yml
│ (CodeDeploy) │ Stop → Install → Start → Validate
└─────────────────────────┘Step 1: buildspec.yml — Build Definition
This file tells CodeBuild what to do. It's like anazure-pipelines.yml but with AWS-specific phases.
version: 0.2
phases:
install:
runtime-versions:
nodejs: 18
commands:
- cd app && npm ci
pre_build:
commands:
- cd app && npm test
build:
commands:
- echo "Build succeeded on $(date)"
artifacts:
files:
- "**/*"
discard-paths: noPhases explained: install sets up the environment,pre_build runs quality checks, build does the main build, and the artifacts section defines what gets passed to CodeDeploy.
Step 2: appspec.yml — Deployment Definition
This file tells CodeDeploy how to deploy to each EC2 instance. It defines lifecycle hooks that run scripts at specific stages.
version: 0.0
os: linux
files:
- source: /app
destination: /home/ec2-user/aws-sandbox-app
hooks:
ApplicationStop:
- location: scripts/stop_server.sh # Stop old version
BeforeInstall:
- location: scripts/install_dependencies.sh # Install Node.js
AfterInstall:
- location: scripts/after_install.sh # npm install, run migrations
ApplicationStart:
- location: scripts/start_server.sh # pm2 start
ValidateService:
- location: scripts/validate_service.sh # curl /healthDeployment Strategies
🔄 In-Place (OneAtATime)
Updates one instance at a time. Traffic is rerouted while each instance updates. Simple and safe.
🔵🟢 Blue/Green
Launches new instances, switches ALB traffic all at once. Zero-downtime, easy rollback.
Step 3: CodeStar Connection to GitHub
Before deploying the pipeline, create a GitHub connection:
- Go to CodePipeline Console → Settings → Connections
- Click Create connection → GitHub
- Authorize AWS in your GitHub account
- Copy the Connection ARN — you'll need it for the CloudFormation stack
Hands-On: Deploy Pipeline and Trigger a Build
# Deploy the CI/CD stack
aws cloudformation create-stack \
--stack-name aws-sandbox-cicd \
--template-body file://cloudformation/07-cicd-pipeline.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--parameters \
ParameterKey=GitHubConnectionArn,ParameterValue=YOUR_ARN \
ParameterKey=GitHubOwner,ParameterValue=YOUR_USERNAME \
ParameterKey=GitHubRepo,ParameterValue=AWS_sandbox
# Trigger the pipeline with a code push
echo "# Deploy test $(date)" >> README.md
git add . && git commit -m "test: trigger pipeline" && git push
# Watch the pipeline status
aws codepipeline get-pipeline-state --name aws-sandbox-pipeline \
--query 'stageStates[*].{Stage:stageName,Status:latestExecution.status}'Watch the pipeline progress through Source → Build → Deploy. Check the CodePipeline console for a visual view of each stage.
Key Takeaways
- CodePipeline orchestrates, CodeBuild builds, CodeDeploy deploys
buildspec.yml= what to build,appspec.yml= how to deploy- CodeDeploy lifecycle hooks give you full control over the deployment process
- In-Place deployment is simpler; Blue/Green is safer for production