- Published on
Advanced CI/CD Pipeline Guide 2025: Deployment Strategies, GitOps, Monorepo, Security Pipeline
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- Introduction
- 1. Deployment Strategies
- 2. GitOps
- 3. Monorepo CI
- 4. Feature Flags
- 5. Environment Management
- 6. Pipeline Security
- 7. Rollback Strategies
- 8. Pipeline Performance Optimization
- 9. Release Management
- 10. Multi-Cloud Deployment
- 11. Quiz
- 12. CI/CD Maturity Checklist
- 13. References
Introduction
According to the 2024 DORA (DevOps Research and Assessment) report, elite teams deploy multiple times per day with a change failure rate below 5%. Low-performing teams deploy once a month and take weeks to recover. The key differentiator is CI/CD pipeline maturity.
Beyond simple build-test-deploy, modern CI/CD encompasses deployment strategies (Blue-Green, Canary), GitOps, monorepo optimization, feature flags, and security pipelines. This guide systematically covers advanced CI/CD strategies proven in production environments in 2025.
1. Deployment Strategies
1.1 Rolling Update
The most basic deployment method, replacing instances sequentially.
Time ->
Instance 1: [v1] [v1] [v2] [v2] [v2]
Instance 2: [v1] [v1] [v1] [v2] [v2]
Instance 3: [v1] [v1] [v1] [v1] [v2]
Traffic: 100% v1 -> mixed -> 100% v2
# Kubernetes Rolling Update
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Max 1 additional Pod
maxUnavailable: 0 # Zero downtime
template:
spec:
containers:
- name: api
image: myapp:v2
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
Pros: Simple, minimal extra resources, gradual replacement Cons: Mixed v1/v2 traffic during deployment, difficult instant rollback
1.2 Blue-Green Deployment
Maintain two identical environments (Blue/Green) and switch traffic all at once.
┌─────────────────────────────────────────────┐
│ │
│ Load Balancer │
│ | │
│ v (Before switch: traffic to Blue) │
│ ┌───────────┐ ┌───────────┐ │
│ │ Blue │ │ Green │ │
│ │ (v1) │ │ (v2) │ │
│ │ Active │ │ Standby │ │
│ └───────────┘ └───────────┘ │
│ │
│ After switch: 100% traffic to Green │
│ │
│ ┌───────────┐ ┌───────────┐ │
│ │ Blue │ │ Green │ │
│ │ (v1) │ │ (v2) │ │
│ │ Standby │ │ Active │ │
│ └───────────┘ └───────────┘ │
└─────────────────────────────────────────────┘
# Blue-Green with AWS ALB (GitHub Actions)
name: Blue-Green Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build and Push Docker Image
run: |
docker build -t myapp:${{ github.sha }} .
docker push myregistry/myapp:${{ github.sha }}
- name: Deploy to Green Environment
run: |
aws ecs update-service \
--cluster production \
--service green-service \
--task-definition myapp:${{ github.sha }}
- name: Run Smoke Tests on Green
run: |
./scripts/smoke-test.sh https://green.myapp.com
- name: Switch Traffic to Green
run: |
aws elbv2 modify-listener \
--listener-arn ${{ secrets.ALB_LISTENER_ARN }} \
--default-actions \
Type=forward,TargetGroupArn=${{ secrets.GREEN_TG_ARN }}
Pros: Instant rollback (switch traffic to Blue), zero downtime Cons: 2x infrastructure cost, complex database migrations
1.3 Canary Deployment
Deploy the new version to a small percentage of traffic first for validation.
Phase 1: 5% traffic to Canary (v2)
┌──────────────────────────────┐
│ v1 v1 v1 v1 v1 v1 v1 v1 v1 │ 95%
│ v2 │ 5%
└──────────────────────────────┘
Phase 2: Expand to 25% after validation
┌──────────────────────────────┐
│ v1 v1 v1 v1 v1 v1 v1 │ 75%
│ v2 v2 v2 │ 25%
└──────────────────────────────┘
Phase 3: 100% after confirming stability
┌──────────────────────────────┐
│ v2 v2 v2 v2 v2 v2 v2 v2 v2 │ 100%
└──────────────────────────────┘
# Canary Deployment with Istio
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp.example.com
http:
- route:
- destination:
host: myapp
subset: stable
weight: 95
- destination:
host: myapp
subset: canary
weight: 5
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: myapp
spec:
host: myapp
subsets:
- name: stable
labels:
version: v1
- name: canary
labels:
version: v2
Pros: Minimized risk, validation with real traffic, progressive rollout Cons: Implementation complexity, requires metrics-based automation
1.4 Deployment Strategy Comparison
| Strategy | Downtime | Rollback Speed | Cost | Complexity | Best For |
|---|---|---|---|---|---|
| Rolling | None | Slow | Low | Low | General services |
| Blue-Green | None | Instant | High (2x) | Medium | Critical services |
| Canary | None | Fast | Medium | High | High-traffic services |
| A/B Testing | None | Fast | Medium | Very High | Feature experiments |
2. GitOps
2.1 GitOps Principles
┌──────────────────────────────────────────────────────┐
│ GitOps Principles │
│ │
│ 1. Declarative │
│ - System state declared as code │
│ │
│ 2. Versioned │
│ - Git is the Single Source of Truth (SSOT) │
│ │
│ 3. Automated │
│ - Approved changes auto-applied to system │
│ │
│ 4. Self-healing │
│ - Auto-corrects drift between desired/actual state │
└──────────────────────────────────────────────────────┘
2.2 ArgoCD Configuration
# argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-production
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: apps/myapp/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true # Clean up orphaned resources
selfHeal: true # Auto-revert manual changes
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
2.3 ArgoCD App-of-Apps Pattern
# root-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests.git
targetRevision: main
path: apps
destination:
server: https://kubernetes.default.svc
# apps/ directory structure
# apps/
# myapp/
# application.yaml
# api-gateway/
# application.yaml
# monitoring/
# application.yaml
# cert-manager/
# application.yaml
2.4 ArgoCD vs Flux Comparison
| Feature | ArgoCD | Flux v2 |
|---|---|---|
| UI Dashboard | Built-in web UI | Weave GitOps (separate) |
| Multi-cluster | Supported | Supported |
| Helm Support | Native | HelmRelease CRD |
| Kustomize | Native | Native |
| Image Auto-update | ArgoCD Image Updater | Built-in |
| Notifications | ArgoCD Notifications | Notification Controller |
| RBAC | Built-in | Uses Kubernetes RBAC |
| Approach | Pull-based | Pull-based |
| Learning Curve | Medium | Medium-High |
2.5 ArgoCD Notification Setup
# argocd-notifications-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
service.slack: |
token: $slack-token
trigger.on-sync-succeeded: |
- when: app.status.sync.status == 'Synced'
send: [app-sync-succeeded]
trigger.on-sync-failed: |
- when: app.status.sync.status == 'Unknown'
send: [app-sync-failed]
template.app-sync-succeeded: |
slack:
attachments: |
[{
"color": "#18be52",
"title": "{{.app.metadata.name}} sync succeeded",
"text": "Deployment complete: {{.app.spec.source.targetRevision}}"
}]
template.app-sync-failed: |
slack:
attachments: |
[{
"color": "#E96D76",
"title": "{{.app.metadata.name}} sync failed",
"text": "Error: {{.app.status.conditions}}"
}]
3. Monorepo CI
3.1 Monorepo Structure
monorepo/
apps/
web/ # Next.js frontend
api/ # Express backend
mobile/ # React Native app
packages/
ui/ # Shared UI components
utils/ # Shared utilities
config/ # Shared configuration
turbo.json # Turborepo config
nx.json # Or Nx config
package.json
3.2 Turborepo Configuration
{
"globalDependencies": ["**/.env.*local"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"],
"cache": true
},
"test": {
"dependsOn": ["build"],
"outputs": [],
"cache": true
},
"lint": {
"outputs": [],
"cache": true
},
"deploy": {
"dependsOn": ["build", "test", "lint"],
"cache": false
}
}
}
3.3 Nx Affected Builds
# .github/workflows/monorepo-ci.yml
name: Monorepo CI
on:
pull_request:
branches: [main]
jobs:
affected:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history needed
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
# Only build/test changed projects
- name: Lint affected
run: npx nx affected --target=lint --base=origin/main
- name: Test affected
run: npx nx affected --target=test --base=origin/main
- name: Build affected
run: npx nx affected --target=build --base=origin/main
# Remote Caching
remote-cache:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- name: Build with remote cache
run: npx turbo build --team=myteam --token=${{ secrets.TURBO_TOKEN }}
env:
TURBO_TEAM: myteam
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
3.4 Turborepo vs Nx vs Bazel
| Feature | Turborepo | Nx | Bazel |
|---|---|---|---|
| Learning Curve | Low | Medium | High |
| Language Support | JS/TS | JS/TS, Go, Rust, etc. | Multi-language |
| Change Detection | File hashes | Project graph | Dependency graph |
| Remote Caching | Vercel RC | Nx Cloud | Remote Execution |
| Config Complexity | Very simple | Medium | Complex |
| Scale Suitability | Medium | Large | Very large |
| Code Generation | None | Built-in Generator | Rules |
4. Feature Flags
4.1 Types of Feature Flags
┌──────────────────────────────────────────────────┐
│ Feature Flag Types │
├──────────────────────────────────────────────────┤
│ │
│ 1. Release Flag │
│ - Hide incomplete features while deploying │
│ - Lifespan: Short (days to weeks) │
│ │
│ 2. Experiment Flag │
│ - A/B testing, feature comparison │
│ - Lifespan: Medium (weeks to months) │
│ │
│ 3. Ops Flag │
│ - System behavior control (kill switch) │
│ - Lifespan: Permanent │
│ │
│ 4. Permission Flag │
│ - Per-user/organization feature access │
│ - Lifespan: Permanent │
└──────────────────────────────────────────────────┘
4.2 Implementation Example
// featureFlags.ts
import { UnleashClient } from 'unleash-proxy-client';
const unleash = new UnleashClient({
url: 'https://unleash.myapp.com/api/frontend',
clientKey: process.env.UNLEASH_CLIENT_KEY!,
appName: 'myapp-frontend',
refreshInterval: 15,
});
unleash.start();
// React Hook
export function useFeatureFlag(flagName: string): boolean {
const [enabled, setEnabled] = useState(false);
useEffect(() => {
setEnabled(unleash.isEnabled(flagName));
const handler = () => {
setEnabled(unleash.isEnabled(flagName));
};
unleash.on('update', handler);
return () => unleash.off('update', handler);
}, [flagName]);
return enabled;
}
// Usage in component
function CheckoutPage() {
const newCheckoutEnabled = useFeatureFlag('new-checkout-flow');
if (newCheckoutEnabled) {
return <NewCheckoutFlow />;
}
return <LegacyCheckoutFlow />;
}
4.3 Progressive Rollout
// Server-side feature flags (LaunchDarkly style)
import LaunchDarkly from 'launchdarkly-node-server-sdk';
const client = LaunchDarkly.init(process.env.LD_SDK_KEY!);
async function getFeatureValue(
flagKey: string,
user: LDUser,
defaultValue: boolean
): Promise<boolean> {
await client.waitForInitialization();
return client.variation(flagKey, user, defaultValue);
}
// Progressive rollout phases:
// Phase 1: Internal employees only (beta-testers group)
// Phase 2: 5% of users
// Phase 3: 25% of users
// Phase 4: 50% of users
// Phase 5: 100% of users
// Kill switch pattern
async function processPayment(order: Order) {
const newPaymentEnabled = await getFeatureValue(
'new-payment-gateway',
{ key: order.userId },
false // Default: disabled
);
if (newPaymentEnabled) {
return newPaymentGateway.process(order);
}
return legacyPaymentGateway.process(order);
}
4.4 LaunchDarkly vs Unleash vs Flagsmith
| Feature | LaunchDarkly | Unleash | Flagsmith |
|---|---|---|---|
| Pricing | Paid (expensive) | Open source + Enterprise | Open source + Cloud |
| Targeting | Very sophisticated | Basic | Sophisticated |
| A/B Testing | Built-in | Separate | Built-in |
| SDK Support | 25+ languages | 15+ languages | 15+ languages |
| Self-hosting | Not available | Available | Available |
| Audit Logs | Supported | Supported | Supported |
5. Environment Management
5.1 Environment Hierarchy
┌─────────────────────────────────────────┐
│ Production │
│ - Real user traffic │
│ - Highest level monitoring │
│ - Change approval process │
├─────────────────────────────────────────┤
│ Staging │
│ - Identical to production config │
│ - QA team testing │
│ - Integration tests │
├─────────────────────────────────────────┤
│ Development │
│ - Latest feature integration │
│ - Auto-deploy from main branch │
├─────────────────────────────────────────┤
│ PR Preview │
│ - Independent environment per PR │
│ - Auto-deleted when PR closes │
└─────────────────────────────────────────┘
5.2 Ephemeral Environments
# .github/workflows/preview.yml
name: PR Preview Environment
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
deploy-preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy Preview
run: |
PREVIEW_URL="pr-${{ github.event.number }}.preview.myapp.com"
helm upgrade --install \
pr-${{ github.event.number }} \
./charts/myapp \
--namespace previews \
--set image.tag=${{ github.sha }} \
--set ingress.host=$PREVIEW_URL \
--set resources.requests.memory=256Mi \
--set resources.requests.cpu=100m
- name: Comment PR with URL
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `Preview deployed: https://pr-${context.issue.number}.preview.myapp.com`
})
cleanup-preview:
if: github.event.action == 'closed'
runs-on: ubuntu-latest
steps:
- name: Delete Preview
run: |
helm uninstall pr-${{ github.event.number }} \
--namespace previews
6. Pipeline Security
6.1 Secrets Management
# GitHub Actions - AWS Auth via OIDC (no long-lived secrets)
name: Secure Deploy
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# OIDC-based AWS auth (no long-lived secrets needed)
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-role
aws-region: us-east-1
# Secret scanning
- name: Scan for secrets
uses: trufflesecurity/trufflehog@v3
with:
path: ./
extra_args: --only-verified
# Container image scanning
- name: Scan container image
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
severity: 'CRITICAL,HIGH'
exit-code: '1'
6.2 SLSA (Supply-chain Levels for Software Artifacts)
# SLSA Level 3 - Signed builds + provenance attestation
name: SLSA Build
jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
attestations: write
steps:
- uses: actions/checkout@v4
- name: Build
run: npm run build
# Artifact signing with Sigstore
- name: Sign artifact
uses: sigstore/cosign-installer@v3
- name: Sign container image
run: |
cosign sign \
--yes \
myregistry/myapp:${{ github.sha }}
# Generate SLSA provenance attestation
- name: Generate SLSA provenance
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
with:
image: myregistry/myapp
digest: ${{ steps.build.outputs.digest }}
6.3 Security Scanning Pipeline
# .github/workflows/security.yml
name: Security Pipeline
on:
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1' # Every Monday at 06:00
jobs:
sast:
name: Static Analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
uses: semgrep/semgrep-action@v1
with:
config: p/owasp-top-ten
dependency-check:
name: Dependency Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm audit --audit-level=high
- name: Snyk Test
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
container-scan:
name: Container Security
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:scan .
- name: Trivy scan
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:scan
severity: 'CRITICAL,HIGH'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
iac-scan:
name: Infrastructure as Code Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Checkov scan
uses: bridgecrewio/checkov-action@master
with:
directory: ./terraform
framework: terraform
7. Rollback Strategies
7.1 Instant Rollback
# Kubernetes rollback
# Immediately rollback to last successful version
# kubectl rollout undo deployment/myapp
# GitHub Actions auto-rollback
name: Deploy with Auto-Rollback
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy new version
id: deploy
run: |
kubectl set image deployment/myapp \
myapp=myregistry/myapp:${{ github.sha }}
kubectl rollout status deployment/myapp --timeout=300s
- name: Run post-deploy checks
id: healthcheck
run: |
for i in $(seq 1 10); do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://myapp.com/health)
if [ "$STATUS" != "200" ]; then
echo "Health check failed: $STATUS"
exit 1
fi
sleep 5
done
- name: Rollback on failure
if: failure()
run: |
echo "Rolling back to previous version..."
kubectl rollout undo deployment/myapp
kubectl rollout status deployment/myapp --timeout=300s
7.2 Database-Aware Rollback
When DB schema changes are part of a deployment:
1. Forward-Compatible Migration (safe)
┌─────────────────────────────────────┐
│ Step 1: Add new column (nullable) │
│ Step 2: Deploy app v2 (uses both) │
│ Step 3: Migrate data │
│ Step 4: Remove old column │
└─────────────────────────────────────┘
2. Expand-Contract Pattern
Phase 1 (Expand): Add new schema, keep old
Phase 2 (Migrate): Transfer data
Phase 3 (Contract): Remove old schema
7.3 Forward-Fix vs Rollback Decision Guide
| Situation | Recommended Strategy | Reason |
|---|---|---|
| Simple bug fix | Forward-Fix | Fix is faster than rollback |
| Critical outage | Instant Rollback | Service recovery is top priority |
| Includes DB migration | Forward-Fix | Risk of data loss on rollback |
| Performance degradation | Canary Rollback | Assess impact before deciding |
8. Pipeline Performance Optimization
8.1 Caching Strategies
# .github/workflows/optimized-ci.yml
name: Optimized CI
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Node.js dependency caching
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
# Docker layer caching
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: myapp:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Turborepo remote caching
- name: Build with cache
run: npx turbo build --cache-dir=.turbo
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: myteam
8.2 Parallelization Strategy
# Parallel job execution
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run lint
unit-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run test:unit
type-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run type-check
# Build after all checks pass
build:
needs: [lint, unit-test, type-check]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run build
8.3 Self-Hosted Runners
# Self-hosted runners (ARM64 Mac, etc.)
jobs:
build-ios:
runs-on: [self-hosted, macOS, ARM64]
steps:
- uses: actions/checkout@v4
- name: Build iOS
run: xcodebuild -workspace MyApp.xcworkspace ...
build-android:
runs-on: [self-hosted, Linux, X64]
steps:
- uses: actions/checkout@v4
- name: Build Android
run: ./gradlew assembleRelease
9. Release Management
9.1 Semantic Versioning
MAJOR.MINOR.PATCH (e.g., 2.1.3)
MAJOR: Incompatible API changes
MINOR: Backward-compatible new features
PATCH: Backward-compatible bug fixes
Examples:
1.0.0 -> 1.0.1 (bug fix)
1.0.1 -> 1.1.0 (new feature)
1.1.0 -> 2.0.0 (Breaking Change)
9.2 Automated Release Notes
# .github/workflows/release.yml
name: Release
on:
push:
tags: ['v*']
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate Changelog
id: changelog
uses: orhun/git-cliff-action@v3
with:
config: cliff.toml
- name: Create Release
uses: softprops/action-gh-release@v2
with:
body: ${{ steps.changelog.outputs.content }}
draft: false
prerelease: false
9.3 Conventional Commits
# Commit message format
# type(scope): description
feat(auth): add OAuth2.0 login support
fix(cart): resolve quantity update race condition
docs(api): update REST API documentation
chore(deps): upgrade express to v5.0
perf(db): optimize query for order listing
refactor(payment): extract payment strategy pattern
test(checkout): add E2E tests for checkout flow
# Breaking Change notation
feat(api)!: change response format for /orders endpoint
BREAKING CHANGE: The orders endpoint now returns
paginated responses instead of a flat array.
9.4 Release Train Model
┌─────────────────────────────────────────────┐
│ Release Train (bi-weekly releases) │
│ │
│ Week 1: Feature development + Code Freeze │
│ Week 2: QA + Bug fixes + Release │
│ │
│ --+------+------+------+------+-- │
│ v2.1 v2.2 v2.3 v2.4 v2.5 │
│ │
│ Hotfixes deploy immediately from │
│ separate branch │
└─────────────────────────────────────────────┘
10. Multi-Cloud Deployment
10.1 Multi-Cloud with Terraform
# main.tf - Multi-cloud providers
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
# AWS deployment
resource "aws_ecs_service" "primary" {
name = "myapp-primary"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 3
load_balancer {
target_group_arn = aws_lb_target_group.app.arn
container_name = "myapp"
container_port = 8080
}
}
# GCP deployment (DR)
resource "google_cloud_run_service" "failover" {
name = "myapp-failover"
location = "us-central1"
template {
spec {
containers {
image = "gcr.io/myproject/myapp:latest"
}
}
}
}
11. Quiz
Q1: What is the biggest advantage of Blue-Green deployment?
A) Lower infrastructure costs B) Instant rollback capability C) Simple implementation D) Traffic splitting capability
Answer: B
Blue-Green deployment maintains two identical environments, so when issues arise, you can instantly switch the load balancer traffic back to the previous environment (Blue). The tradeoff is 2x infrastructure cost.
Q2: What is the role of the Git repository in GitOps?
A) Code backup storage B) CI/CD pipeline runner C) Single Source of Truth (SSOT) for infrastructure D) Monitoring dashboard
Answer: C
In GitOps, the Git repository serves as the Single Source of Truth (SSOT) for infrastructure and application state. All changes go through Git, and tools like ArgoCD/Flux synchronize Git state with the actual cluster state.
Q3: What is the benefit of "affected" builds in monorepo CI?
A) It always builds all projects B) It only builds changed projects and their dependents, saving time C) It ignores build caches D) It skips tests
Answer: B
Affected builds analyze the Git diff to selectively build and test only changed projects and their dependents. This significantly reduces CI time in large monorepos.
Q4: What is the "kill switch" purpose of Feature Flags?
A) Shuts down the server B) Instantly disables a problematic feature without code deployment C) Deletes the database D) Stops the CI pipeline
Answer: B
A kill switch toggles a feature flag to OFF in production when problems occur, instantly disabling that feature without deploying new code. This is much faster than a rollback.
Q5: What is the purpose of SLSA (Supply-chain Levels for Software Artifacts)?
A) Code performance optimization B) Ensures software supply chain integrity C) Database security D) UI design verification
Answer: B
SLSA is a security framework to prevent software supply chain attacks. It ensures software integrity through build provenance attestation, artifact signing, and build environment isolation.
12. CI/CD Maturity Checklist
CI/CD Maturity Checklist:
Level 1 - Basic
[ ] Automated build pipeline
[ ] Automated test execution
[ ] Code review process
Level 2 - Standard
[ ] Deployment strategy (Rolling/Blue-Green)
[ ] Environment separation (dev/staging/prod)
[ ] Secrets management (Vault/OIDC)
Level 3 - Advanced
[ ] GitOps (ArgoCD/Flux)
[ ] Feature Flags
[ ] Canary deployment
[ ] PR Preview environments
Level 4 - Elite
[ ] Pipeline security (SLSA)
[ ] Auto-rollback
[ ] Monorepo optimization
[ ] Release automation
13. References
- DORA Metrics: dora.dev
- ArgoCD Documentation: argo-cd.readthedocs.io
- Flux Documentation: fluxcd.io
- Turborepo Documentation: turbo.build
- Nx Documentation: nx.dev
- LaunchDarkly Docs: docs.launchdarkly.com
- Unleash Documentation: docs.getunleash.io
- SLSA Framework: slsa.dev
- Sigstore / Cosign: sigstore.dev
- Semgrep: semgrep.dev
- Conventional Commits: conventionalcommits.org
- Git Cliff (Changelog): git-cliff.org
- GitHub Actions Docs: docs.github.com/actions
- Kubernetes Deployment Strategies: kubernetes.io/docs