CI/CD for Microservices
A microservices system can have 50 or more services, each updated by a different team several times per week. Manually testing and deploying each update is impractical. CI/CD — Continuous Integration and Continuous Delivery — automates the process from code change to production deployment.
What CI/CD Means
Continuous Integration (CI)
Every time a developer commits code, an automated system builds the service, runs all tests, and reports whether the code is healthy. Problems get caught within minutes of being written — not days later during a manual review.
Continuous Delivery (CD)
After CI confirms the code is healthy, CD automatically packages the service, pushes it to a registry, and deploys it to a target environment (staging or production). Deployment becomes a routine, repeatable process rather than a stressful manual event.
The CI/CD Pipeline
A pipeline is a series of automated stages, each building on the previous one.
CI/CD PIPELINE FOR ORDER SERVICE
==================================
Developer commits code to Git
|
v
[Stage 1: Build]
Compile code
Build Docker image
Tag with commit ID (e.g., order-service:a3f9c21)
|
v
[Stage 2: Test]
Run unit tests (do individual functions work?)
Run integration tests (do services work together?)
Run security scan (any known vulnerabilities in dependencies?)
If any test fails: pipeline stops, developer is notified
|
v
[Stage 3: Publish]
Push Docker image to container registry
Available for deployment
|
v
[Stage 4: Deploy to Staging]
Deploy image to staging environment
Run smoke tests (is the service responding?)
Run end-to-end tests (does the user flow work?)
|
v
[Stage 5: Deploy to Production]
Rolling update in Kubernetes
Monitor for errors in the first 5 minutes
Auto-rollback if error rate exceeds threshold
Independent Pipelines per Service
Each microservice has its own independent CI/CD pipeline. The Payment Service team deploys without waiting for the Order Service team. Changes to the Inventory Service do not trigger rebuilds of unrelated services.
SEPARATE PIPELINES =================== [Order Service Repo] --> [Order Service Pipeline] --> Production [Payment Service Repo] --> [Payment Service Pipeline] --> Production [User Service Repo] --> [User Service Pipeline] --> Production Teams release independently. No coordination needed.
Feature Flags
Feature flags let teams deploy code to production without making it visible to users. A flag controls whether a feature is active. Teams turn the flag on for a small percentage of users first, monitor for problems, then gradually roll out to everyone.
CODE EXAMPLE (conceptual)
==========================
if (featureFlag.isEnabled("new-checkout-flow", userId)) {
showNewCheckout() // 10% of users see new flow
} else {
showOldCheckout() // 90% still see old flow
}
If new checkout has a bug:
Turn flag OFF
All users back to old checkout immediately
No deployment needed. No rollback needed.
Environment Strategy
ENVIRONMENT PIPELINE
=====================
[Development] --> [Staging] --> [Production]
Development: Developer's local machine or shared dev cluster
Fast iteration, no strict quality gates
Staging: Mirror of production environment
Full integration tests, performance tests
Real data shapes (not real user data)
Production: Live system serving real users
Reached only after passing all gates
Testing in a Microservices Pipeline
Unit Tests
Test individual functions or classes in isolation. They run in milliseconds. A pipeline runs thousands of unit tests in under a minute.
Contract Tests
Contract tests verify that a service honors its API contract. The Order Service contract test checks that the Payment Service API still accepts requests in the expected format. A contract test catches breaking changes before deployment.
CONTRACT TEST EXAMPLE
======================
Payment Service contract says:
POST /charge accepts { order_id, amount, card_token }
Returns { status, transaction_id }
Contract test sends a sample request.
Verifies response matches the documented contract.
If Payment Service team changes the response format:
Contract test fails
Team is alerted before the change reaches production
Order Service team is not surprised by a broken integration
End-to-End Tests
End-to-end tests simulate a real user flow across multiple services. They confirm that placing an order goes all the way through to payment confirmation. These tests run in staging, not on every commit, because they take longer.
Popular CI/CD Tools
- GitHub Actions — built into GitHub, YAML-based pipelines, widely used.
- GitLab CI/CD — built into GitLab, powerful and fully integrated.
- Jenkins — mature, self-hosted, highly customizable.
- ArgoCD — Kubernetes-native CD tool, uses Git as the source of truth for deployments.
- Tekton — Kubernetes-native CI/CD pipelines.
GitOps: Deployments via Git
GitOps is a deployment approach where the desired state of the production environment is stored in a Git repository. ArgoCD watches the repository. When the repository changes (a new image tag is committed), ArgoCD applies the change to the Kubernetes cluster automatically.
GITOPS FLOW ============ Developer merges PR --> CI builds and pushes image: order-service:1.5 --> CI commits updated image tag to config repo (gitops-configs) ArgoCD watches config repo --> Detects change: order-service image updated to 1.5 --> Applies to Kubernetes cluster --> Rolling update begins automatically --> Production now runs order-service:1.5 No human ran "kubectl apply". Git is the single source of truth.
GitOps provides a full audit trail — every production change corresponds to a Git commit with an author, timestamp, and reason for the change.
