DEV Community

nk sk
nk sk

Posted on

πŸš€ Modern CI/CD for Microservices: Monorepos, AWS, Jenkins & What Tech Giants Actually Use

Microservices have become the standard way to build scalable backend systems. But as teams grow, architecture questions begin flooding in:

  • Should microservices each have their own repo?
  • Is a monorepo anti-microservice?
  • What do Amazon, Google, Netflix actually use?
  • How do we deploy microservices independently from AWS without GitHub?

This guide brings a practical, real-world, and industry-backed explanation of how microservices CI/CD and repo structures truly work today β€” especially in AWS environments using Jenkins.


🧩 1. The Myth: Microservices Require Multiple Git Repos

Many developers assume:

β€œEach microservice must live in a separate repo.”

This is not a microservices rule.
It’s simply a common implementation pattern, not a requirement.

Microservices need:

βœ” Independent build
βœ” Independent test
βœ” Independent deployment
βœ” Independent scaling

None of these require separate repositories.

You can achieve all four from a single repository as well.


🟦 2. What Is a Monorepo?

A monorepo (monolithic repository) stores the code for many projects and microservices inside a single version-controlled repository:

/services
   /auth-service
   /payment-service
   /order-service

/libs
   /logging
   /common-utils
Enter fullscreen mode Exit fullscreen mode

Instead of scattered repos, everything lives together.

βœ” Benefits of Monorepos

  • Shared libraries are easy to maintain
  • One place for all code
  • Atomic changes across multiple services
  • Unified linting, testing, formatting
  • Simpler onboarding
  • Avoid version drift across services
  • Code reviews are easier and faster

πŸŸ₯ 3. β€œBut does a monorepo break microservices independence?”

No.

Why?

Because independent deployment has nothing to do with repository layout.

In a proper monorepo setup:

  • Each service has its own Dockerfile
  • Each service has its own pipeline/Jenkinsfile
  • Pipelines run only when that service changes
  • Each service deploys its own container to Kubernetes
  • Other services remain untouched

Example independent builds:

/services/user-service  -> ECR -> EKS deployment A
/services/order-service -> ECR -> EKS deployment B
/services/payment       -> ECR -> EKS deployment C
Enter fullscreen mode Exit fullscreen mode

This is fully compliant with microservices principles.


🟩 4. How Tech Giants Do It (Real Industry Practices)

Let’s break down how the largest engineering teams handle microservices.

πŸ”΅ Google

  • Massive monorepo called Piper
  • Millions of files
  • Independent builds via Bazel
  • Independent deployments via Borg/Kubernetes

πŸ”΅ Meta (Facebook)

  • Mercurial-powered monorepo
  • Thousands of microservices
  • Independently deployable

πŸ”΅ Uber

  • Hybrid monorepo
  • Go, Java, Node services
  • Independent builds + Spinnaker deployments

πŸ”Ά Netflix

  • Mostly monorepo + GitHub Enterprise
  • CI using Spinnaker
  • Deploying microservices independently to Titus/Kubernetes

🟦 Microsoft

  • Azure DevOps monorepos
  • Independent pipelines + AKS deployments

πŸ’‘ Reality:

Tech giants don’t use GitHub public repos for production code.

Most use monorepos with independent deployment pipelines.


🟨 5. Production-Grade Repositories in AWS

If you don’t want GitHub, AWS gives you:

βœ” AWS CodeCommit

A fully private Git repository inside AWS.
Used in enterprises, banks, and regulated industries.

βœ” AWS CodePipeline / CodeBuild

Complete CI/CD inside AWS.

βœ” Jenkins on AWS

For teams already using Jenkins.


🟦 6. Production Architecture: Jenkins + AWS CodeCommit + EKS

This is the architecture many real AWS customers follow:

           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
           β”‚ CodeCommit   β”‚ ← Private Git repo
           β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                  β”‚ Webhook
           β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
           β”‚   Jenkins    β”‚
           β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
   Build / Test   β”‚
                  β”‚ Build Docker Image
           β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
           β”‚    ECR      β”‚ ← Stores versioned images
           β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                  β”‚ Deploy
           β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
           β”‚    EKS      β”‚ ← Kubernetes cluster
           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

Each microservice has its own pipeline inside Jenkins.


🟧 7. Jenkinsfile for Independent Microservice Deployment

Example structure:

/services
   /user-service
      Jenkinsfile
   /order-service
      Jenkinsfile
   /payment-service
      Jenkinsfile
Enter fullscreen mode Exit fullscreen mode

Each Jenkinsfile:

  • Builds only its own service
  • Pushes only its own image
  • Updates only its own Kubernetes deployment

That’s true microservice independence.


🟩 8. Sample Jenkins Pipeline (AWS ECR + EKS)

A simplified production pipeline:

pipeline {
    agent any

    environment {
        AWS_REGION    = "ap-south-1"
        APP_NAME      = "user-service"
        AWS_ACCOUNT   = "<ACCOUNT-ID>"
        ECR_REPO      = "${AWS_ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com/${APP_NAME}"
        IMAGE_TAG     = "${env.BUILD_NUMBER}"
    }

    stages {
        stage('Checkout') {
            steps { checkout scm }
        }

        stage('Login to ECR') {
            steps {
                sh """
                    aws ecr get-login-password --region ${AWS_REGION} |
                    docker login --username AWS --password-stdin ${ECR_REPO}
                """
            }
        }

        stage('Build & Push') {
            steps {
                sh """
                    docker build -t ${APP_NAME}:${IMAGE_TAG} .
                    docker tag ${APP_NAME}:${IMAGE_TAG} ${ECR_REPO}:${IMAGE_TAG}
                    docker push ${ECR_REPO}:${IMAGE_TAG}
                """
            }
        }

        stage('Deploy to EKS') {
            steps {
                sh """
                    aws eks update-kubeconfig --region ${AWS_REGION} --name my-eks
                    kubectl set image deployment/${APP_NAME} ${APP_NAME}=${ECR_REPO}:${IMAGE_TAG}
                    kubectl rollout status deployment/${APP_NAME}
                """
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Fully independent.
No conflict across microservices.


πŸŸ₯ 9. Should You Choose Monorepo or Polyrepo?

βœ” Choose Monorepo when:

  • Shared libraries
  • Cross-service updates
  • Unified CI/CD
  • Developer productivity
  • Medium–large engineering teams

βœ” Choose Polyrepo when:

  • Completely unrelated services
  • Different tech stacks
  • Very strict team boundaries
  • No shared dependencies

🟩 10. Final Truth Summary

Here is the honest conclusion, based on how real companies operate:

βœ” Microservices require independent builds and deployments

βœ” They do NOT require separate Git repos

βœ” Monorepos actually make microservices more efficient at scale

βœ” Tech giants rely heavily on monorepos

βœ” AWS gives you CodeCommit as a production-grade Git alternative

βœ” Jenkins + ECR + EKS is a standard enterprise setup

βœ” Each microservice has its OWN pipeline, even in a monorepo


βœ… When a Monorepo Actually Shines (Real Practical Scenarios)

Monorepo is NOT about "everything in one repo".
Monorepo shines when your microservices are not completely isolated and share things.

Here are the exact cases where a monorepo is the BEST choice:


πŸš€ 1. When services have shared libraries or shared code

If you have:

  • common-utils
  • logging
  • payment-client-sdk
  • shared protobuf models
  • DTOs
  • API schemas

Then monorepo is a huge win.

Why?

Because you update the shared library once and all services pick up the change instantly.


πŸš€ 2. When services are logically connected (domain-dependent)

Example:

  • auth-service
  • user-service
  • account-service

Updating a user schema might require a coordinated change across all three.

Monorepo lets you:

βœ” Change all services in one commit
βœ” Test them together
βœ” Deploy them independently


πŸš€ 3. When the same team works across multiple services

This is very common:

  • Backend team owns 6–10 services
  • They evolve together
  • They share patterns, libraries, standards

Monorepo increases speed and consistency dramatically.


πŸš€ 4. When services depend tightly on shared API contracts

Example:

  • gRPC .proto files
  • OpenAPI specs
  • GraphQL schema
  • Domain event contracts

In a polyrepo setup, versioning becomes painful.

Monorepo solves:

βœ” Contract drift
βœ” Compatibility issues
βœ” Manual syncing between repos


πŸš€ 5. When services evolve together over time

If two services:

  • frequently change together
  • share business logic
  • require coordinated releases

Then monorepo reduces management overhead.


❗️ When Monorepo Is Not Ideal

Polyrepo is better when:

  • Completely unrelated services
  • Different tech stacks β†’ Node + Go + Python
  • Different teams owning different domains
  • No shared libraries
  • Loose coupling
  • No cross-service code sharing

In these cases, separate repos reduce noise.


πŸ”₯ So the real truth in one sentence:

πŸ‘‰ Monorepo is best when services are dependent, share code, share contracts, or are owned by the same team.
Polyrepo is best when services are fully independent in logic and ownership.


πŸ’‘ Even Tech Giants Do This

Situation Google / Meta / Uber Repo Choice
Shared libraries Heavy Monorepo
Shared protobuf schemas Massive Monorepo
Cross-service changes Frequent Monorepo
Multiple teams, isolated domains Some Polyrepo (hybrid)

They use hybrid, and you can too.


πŸ“Œ Final Confirmation Based on Your Question

βœ” Yes β€” monorepo shines when services share libraries

βœ” Yes β€” monorepo shines when services change together

βœ” Yes β€” monorepo shines when one change affects another service

βœ” Yes β€” monorepo shines when same team works on multiple services

βœ” Yes β€” monorepo shines when services are tightly dependent

βœ” Yes β€” monorepo helps with consistent tooling & faster development

Top comments (0)