3
3
Table of Contents

Problem Statement

Migration from GCP to AWS

The organization needed to migrate a stateful MongoDB workload from Google Cloud Platform to Amazon Web Services with strict requirements:

  • Zero downtime
  • No data loss
  • Ability to rollback
  • Confidence before final cutover
  • Minimal operational risk

Traditional approaches (mongodump/restore, export–import, downtime cutover) were rejected due to:

  • High downtime
  • Irreversible cutover
  • Risk of data inconsistency
  • Lack of rollback safety

The goal of this PoC was to prove a safe, reversible, production-ready migration strategy before executing a real production cutover.

Core Design Principle

  • Do not move MongoDB data manually.
  • Let MongoDB replicate data.
  • Let AWS MGN replicate infrastructure.

This approach separates concerns:

Core design principle of MGN

Why This Approach Was Chosen

Why MGN approach was chosen

Why AWS MGN

  • Continuous replication
  • No application changes
  • Test launch before cutover
  • Proven enterprise service

Why MongoDB Replica Sets

  • Strong write consistency
  • Oplog-based replication
  • Automatic elections
  • Safe failover & rollback
  • Crash-consistent recovery

This combination allows safe cutover control without risking data.

High-Level Architecture (PoC)

High-level view of PoC architecture

  • Public IPs were used only for PoC speed.
  • Production will use private networking (VPN / VPC peering).

Phase-by-Phase Execution (What We Did)

Phase 1 — GCP MongoDB Baseline Setup

Step 1️:- Install MongoDB on GCP

  • MongoDB 7.x
  • WiredTiger storage engine
Validation

mongod --version

Step 2️:- Configure Replica Set on GCP

/etc/mongod.conf:
net:
 port: 27017
 bindIp: 0.0.0.0   # PoC only

replication:
 replSetName: rs0

sudo systemctl restart mongod

Validation

sudo systemctl status mongod

Step 3️:- Initialize Replica Set on GCP

mongosh --host <GCP_IP> --port 27017

rs.initiate({
 _id: "rs0",
 members: [{ _id: 0, host: "<GCP_IP>:27017" }]
})

Validation

rs.status()

  • GCP became PRIMARY

Step 4️:- Insert Baseline Data

use test

db.migration_test.insertMany([
 { source: "gcp", step: "before-mgn" },
 { source: "gcp", step: "baseline-confirmed" }
])

Validation

db.migration_test.find().pretty()

Phase 2 — AWS MGN Replication

Step 5️:- Install AWS MGN Agent on GCP

  • MongoDB kept running
  • Continuous disk replication started
Validation
  • MGN console → Replication healthy

Step 6️:- Perform AWS MGN Test Launch

Validation

sudo systemctl status mongod

Phase 3 — MongoDB Replication (GCP → AWS)

Step 7️:- Add AWS Node as SECONDARY

On GCP PRIMARY:

rs.add("<AWS_IP>:27017")

Validation

rs.status()

  • GCP → PRIMARY
  • AWS → SECONDARY
  • Replication lag = 0

Step 8️:- Validate Live Replication

Insert on GCP:

db.migration_test.insertOne({
 source: "gcp",
 step: "replication-proof-final"
})

Read on AWS:

db.getMongo().setReadPref("secondary")

db.migration_test.find().pretty()

Data replicated successfully

Phase 4 — Failover & Rollback Validation (Critical)

This phase proves migration safety before final cutover.

Step 9️:-Force Failover (GCP → AWS)

rs.stepDown(60)

Validation

rs.status()

  • AWS elected PRIMARY
  • GCP became SECONDARY

Step 10:- Write Test on AWS PRIMARY

db.migration_test.insertOne({
 source: "aws",
 step: "failover-write-test"
})

Step 11:- Validate Replication Back to GCP

db.getMongo().setReadPref("secondary")

db.migration_test.find({ step: "failover-write-test" })

Data replicated back

Step 12:- Rollback to GCP

rs.stepDown()

Validation

rs.status()

  • GCP restored as PRIMARY
  • No data loss

Phase 5 — Final Cutover (One-Way)

Step 13:- Promote AWS as PRIMARY

On GCP:

rs.stepDown(300)

Validation

rs.status()

  • AWS → PRIMARY

Step 14:- Mark Cutover in AWS MGN

  • MGN Console → Mark Cutover Complete

Step 15:- Remove GCP from Replica Set

On AWS PRIMARY:

rs.remove("<GCP_IP>:27017")

Step 16:- Decommission GCP MongoDB

sudo systemctl stop mongod

sudo systemctl disable mongod

Phase 6 — AWS Replica Creation Using Snapshot

Step 17: Create AWS EC2 Snapshot / AMI

  • MongoDB running
  • Crash-consistent snapshot (WiredTiger journaling)

Step 18: Launch Additional AWS Nodes

  • Same AMI
  • Same Security Group

Step 19 Prepare New Nodes

sudo rm -f /var/lib/mongodb/mongod.lock

sudo rm -f /var/lib/mongodb/WiredTiger.lock

sudo systemctl start mongod

Step 20 Add AWS Replicas

rs.add("<AWS_NODE_2>:27017")

rs.add("<AWS_NODE_3>:27017")

Phase 7 — Final Validation (PoC Closure)

Final Validation (PoC closure)

Step 21:- Final Write Test (AWS PRIMARY)

db.migration_test.insertOne({

 step: "final-aws-cluster",
 source: "aws",
 msg: "final aws-only replica set validated",
 ts: new Date()
})

Step 22:- Validate on AWS SECONDARY

db.getMongo().setReadPref("secondary")
db.migration_test.find({ step: "final-aws-cluster" }).pretty()

Data visible on secondary

Final State (PoC Completed)

Final Component status when PoC was completed

What Was Fully Validated

Migration Validation
  • Live replication
  • Cross-cloud failover
  • Rollback safety
  • Snapshot-based replica creation
  • Final AWS-only replica set
  • Zero downtime
  • Zero data loss

Known PoC Limitations

Excluded intentionally:

  • TLS / authentication
  • Private networking
  • Monitoring & backups

These will be enabled in production.

Production Recommendations

  • Site-to-Site VPN / VPC peering
  • MongoDB auth & keyfile
  • TLS encryption
  • 3-node quorum from day one
  • Backups & monitoring
  • Staged GCP decommission
12
Let's discuss your cloud challenges and see how CloudKeeper can solve them all!
Meet the Author
  • Navneet Devrani
    DevOps Engineer

    Navneet is a DevOps Engineer specializing in migrations, CDN solutions, and infrastructure as code.

No Comments Yet
Leave a Comment
Certified. Trusted. Industry Recognized.

Stop paying for cloud tools. Start paying for outcomes.

Get Started with CloudKeeper