Lab 1: runOnce Deployment (Baseline) ⚡
Objective: Implement simple runOnce deployment
Time: 25 minutes
Exercise 1.1: Basic runOnce Pipeline
1
Navigate to Project
cd $env:USERPROFILE\Desktop\testing-demo\calculator
notepad azure-pipelines-runonce.yml
2
Create runOnce Pipeline
trigger:
- main
stages:
- stage: Build
jobs:
- job: BuildJob
pool:
vmImage: 'windows-latest'
steps:
- task: Maven@3
inputs:
goals: 'clean package -DskipTests'
- task: PublishPipelineArtifact@1
inputs:
targetPath: 'target'
artifactName: 'app'
- stage: Deploy
dependsOn: Build
jobs:
- deployment: DeployApp
displayName: 'runOnce Deployment'
environment: 'Production'
pool:
vmImage: 'windows-latest'
strategy:
runOnce:
deploy:
steps:
- script: echo "Stop old version"
- task: DownloadPipelineArtifact@2
- script: echo "Deploy new version"
- script: echo "Start application"
Save, commit, push to Azure Repos
✅ Checkpoint: Baseline runOnce deployment working
Lab 2: Rolling Deployment 🔄
Objective: Implement rolling deployment with lifecycle hooks
Time: 40 minutes
Exercise 2.1: Configure Rolling Strategy
1
Create Rolling Pipeline
notepad azure-pipelines-rolling.yml
Add rolling deployment:
trigger:
- main
stages:
- stage: Build
jobs:
- job: BuildJob
pool:
vmImage: 'windows-latest'
steps:
- task: Maven@3
inputs:
goals: 'clean package -DskipTests'
- task: PublishPipelineArtifact@1
inputs:
targetPath: 'target'
artifactName: 'app'
- stage: Deploy
dependsOn: Build
jobs:
- deployment: RollingDeploy
displayName: 'Rolling Deployment'
environment: 'Production'
pool:
vmImage: 'windows-latest'
strategy:
rolling:
maxParallel: 2
preDeploy:
steps:
- script: |
echo "================================"
echo "PRE-DEPLOYMENT CHECKS"
echo "Checking server health..."
echo "Backing up configuration..."
echo "Validation passed!"
echo "================================"
displayName: 'Pre-Deploy Health Check'
deploy:
steps:
- task: DownloadPipelineArtifact@2
displayName: 'Download Artifact'
inputs:
artifactName: 'app'
targetPath: '$(Pipeline.Workspace)/app'
- script: |
echo "================================"
echo "DEPLOYING TO SERVER"
echo "Stopping application..."
timeout /t 2 /nobreak
echo "Updating files..."
dir $(Pipeline.Workspace)\app
timeout /t 2 /nobreak
echo "Starting application..."
timeout /t 2 /nobreak
echo "Server updated successfully!"
echo "================================"
displayName: 'Deploy Application'
postDeploy:
steps:
- script: |
echo "================================"
echo "POST-DEPLOYMENT VALIDATION"
echo "Testing application endpoint..."
echo "Health check: PASSED"
echo "Server is healthy and serving traffic"
echo "================================"
displayName: 'Post-Deploy Health Check'
on:
failure:
steps:
- script: |
echo "DEPLOYMENT FAILED!"
echo "Rolling back to previous version..."
echo "Rollback complete"
displayName: 'Rollback on Failure'
success:
steps:
- script: echo "Rolling deployment completed successfully!"
displayName: 'Success Notification'
Save and close
2
Commit and Run
git add azure-pipelines-rolling.yml
git commit -m "Add rolling deployment strategy"
git push
3
Create Pipeline and Watch Execution
- Create new pipeline in Azure DevOps
- Select the rolling YAML file
- Run and watch lifecycle hooks execute:
- ✅ preDeploy (health check)
- ✅ deploy (update application)
- ✅ postDeploy (validation)
- ✅ success (completion)
✅ Checkpoint: Rolling deployment with lifecycle hooks working
Lab 3: Canary Deployment 🐤
Objective: Implement gradual user percentage rollout
Time: 40 minutes
Exercise 3.1: Configure Canary Strategy
1
Create Canary Pipeline
notepad azure-pipelines-canary.yml
trigger:
- main
stages:
- stage: Build
jobs:
- job: BuildJob
pool:
vmImage: 'windows-latest'
steps:
- task: Maven@3
inputs:
goals: 'clean package -DskipTests'
- task: PublishPipelineArtifact@1
inputs:
targetPath: 'target'
artifactName: 'app'
- stage: DeployCanary
displayName: 'Canary Deployment to Production'
dependsOn: Build
jobs:
- deployment: CanaryDeploy
displayName: 'Gradual Rollout'
environment: 'Production'
pool:
vmImage: 'windows-latest'
strategy:
canary:
increments: [10, 25, 50, 100]
preDeploy:
steps:
- script: |
echo "========================================"
echo "CANARY DEPLOYMENT - STARTING"
echo "Target: $(strategy.increment)%% of users"
echo "========================================"
displayName: 'Canary Start'
deploy:
steps:
- task: DownloadPipelineArtifact@2
inputs:
artifactName: 'app'
- script: |
echo "========================================"
echo "ROUTING $(strategy.increment)%% TRAFFIC"
echo "Deploying new version..."
echo "Configuring load balancer..."
echo "New version live for $(strategy.increment)%% of users"
echo "========================================"
displayName: 'Deploy to $(strategy.increment)%'
postDeploy:
steps:
- script: |
echo "========================================"
echo "MONITORING CANARY: $(strategy.increment)%%"
echo "Checking error rates..."
echo "Monitoring response times..."
echo "Analyzing user feedback..."
timeout /t 3 /nobreak
echo "Metrics look good! ✅"
echo "Ready for next increment"
echo "========================================"
displayName: 'Monitor $(strategy.increment)%'
on:
failure:
steps:
- script: |
echo "❌ CANARY FAILED at $(strategy.increment)%%"
echo "Rolling back traffic to stable version..."
echo "Deployment stopped!"
displayName: 'Canary Rollback'
success:
steps:
- script: |
echo "🎉 CANARY DEPLOYMENT COMPLETE!"
echo "100%% of users on new version"
displayName: 'Canary Success'
Save and close
2
Push and Create Pipeline
git add azure-pipelines-canary.yml
git commit -m "Add canary deployment strategy"
git push
3
Watch Canary Rollout
Pipeline will execute in phases:
- Phase 1: Deploy to 10% of users
- Monitor and validate
- Phase 2: Increase to 25%
- Monitor and validate
- Phase 3: Increase to 50%
- Monitor and validate
- Phase 4: Complete rollout to 100%
Note: In this demo, we simulate the incremental rollout.
In production, you'd configure load balancer routing rules.
✅ Checkpoint: Canary deployment with incremental rollout
Lab 4: Blue-Green Deployment Concept 🔵🟢
Objective: Understand blue-green deployment workflow
Time: 35 minutes
Exercise 4.1: Simulated Blue-Green Pipeline
1
Create Blue-Green Pipeline
notepad azure-pipelines-bluegreen.yml
trigger:
- main
stages:
- stage: Build
jobs:
- job: BuildJob
pool:
vmImage: 'windows-latest'
steps:
- task: Maven@3
inputs:
goals: 'clean package -DskipTests'
- task: PublishPipelineArtifact@1
inputs:
targetPath: 'target'
artifactName: 'app'
- stage: DeployGreen
displayName: 'Deploy to Green Environment'
dependsOn: Build
jobs:
- deployment: DeployToGreen
environment: 'Green-Environment'
pool:
vmImage: 'windows-latest'
strategy:
runOnce:
deploy:
steps:
- task: DownloadPipelineArtifact@2
inputs:
artifactName: 'app'
- script: |
echo "========================================"
echo "DEPLOYING TO GREEN ENVIRONMENT"
echo "Blue is still serving all traffic"
echo "Green is being updated..."
echo "Deployment to Green complete!"
echo "Green is ready but not receiving traffic"
echo "========================================"
displayName: 'Deploy to Green'
- script: |
echo "VALIDATING GREEN ENVIRONMENT"
echo "Running smoke tests..."
echo "Testing database connectivity..."
echo "Testing API endpoints..."
echo "All tests passed! ✅"
displayName: 'Validate Green'
- stage: SwitchTraffic
displayName: 'Switch Traffic to Green'
dependsOn: DeployGreen
jobs:
- deployment: TrafficSwitch
environment: 'Production'
pool:
vmImage: 'windows-latest'
strategy:
runOnce:
deploy:
steps:
- script: |
echo "========================================"
echo "SWITCHING TRAFFIC"
echo "Current: Blue (v1.0) - 100%% traffic"
echo "Target: Green (v2.0) - 0%% traffic"
echo ""
echo "Updating load balancer..."
timeout /t 2 /nobreak
echo ""
echo "Traffic switched! ⚡"
echo "Blue (v1.0) - 0%% traffic (idle)"
echo "Green (v2.0) - 100%% traffic ✅"
echo "========================================"
displayName: 'Switch Load Balancer'
- script: |
echo "MONITORING NEW VERSION"
echo "Watching error rates..."
echo "Monitoring response times..."
echo "System healthy! ✅"
displayName: 'Monitor After Switch'
Save and close
2
Create Green Environment
- Go to Pipelines → Environments
- Create new environment:
Green-Environment
3
Run Blue-Green Pipeline
git add azure-pipelines-bluegreen.yml
git commit -m "Add blue-green deployment"
git push
Create pipeline and watch three-phase execution:
- Build: Create artifact
- Deploy to Green: Update inactive environment
- Switch Traffic: Make Green active
✅ Checkpoint: Blue-green workflow demonstrated
Lab 5: Compare Deployment Strategies 📊
Objective: Run and compare all three strategies
Time: 30 minutes
Exercise 5.1: Compare Execution
1
Run All Three Pipelines
- Run azure-pipelines-runonce.yml
- Run azure-pipelines-rolling.yml
- Run azure-pipelines-canary.yml
2
Compare Characteristics
| Aspect |
runOnce |
Rolling |
Canary |
| Stages |
1 deploy stage |
1 with hooks |
Multiple phases |
| Time |
~30 seconds |
~2 minutes |
~5 minutes |
| Safety |
Basic |
Good |
Excellent |
| Complexity |
Simple |
Medium |
Complex |
✅ Checkpoint: Understand tradeoffs between strategies
🎯 Lab Summary
What You've Accomplished:
- ✅ Implemented runOnce deployment (baseline)
- ✅ Created rolling deployment with lifecycle hooks
- ✅ Built canary deployment with gradual rollout
- ✅ Simulated blue-green traffic switching
- ✅ Compared all deployment strategies
- ✅ Understood tradeoffs for each approach
Key Concepts Mastered:
- Rolling: Update servers incrementally
- Blue-Green: Two environments with instant switch
- Canary: Gradual user percentage rollout
- Lifecycle Hooks: preDeploy, deploy, postDeploy
- Failure Handling: Automatic rollback on errors
🎉 Day 17 Complete!
You've mastered deployment strategies!
Ready for Day 18: Container Deployments