---
cuppy_hub: gcp
cuppy_path: patterns/lift-and-shift-a-vm-estate.md
cuppy_section: docs
cuppy_doc: WE5R-CT3K
cuppy_doc_uuid: 7b34f4cf-a80b-4423-aace-0a2944d065f5
cuppy_permalink: https://cuppy.io/gcp/d/WE5R-CT3K
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/gcp/docs/patterns/lift-and-shift-a-vm-estate
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: f05f8d5f169420f03b4a6223c3d13071b63c9e142bb0fbb21e9d340d877ea41a
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Lift and shift a VM estate

## The handoff

```
source: vSphere | AWS | Azure | Google Cloud VMware Engine
   │
   ├─ 1. ASSESS      Migration Center → inventory WITH utilisation, network dependencies, waves
   │
   ├─ 2. PREPARE     target project(s) · one GLOBAL VPC with regional subnets · firewall rules
   │                 quota increases requested · zones chosen · disk family chosen
   │
   ├─ 3. MIGRATE     host project controls  →  target project receives
   │                 target = Compute Engine VMs + Persistent Disk / Hyperdisk volumes
   │
   └─ 4. RE-PLATFORM  a NAMED follow-on project, not an implied one
```

Assessment detail: `guides/migration/assess-before-you-move.md`. The estimate method:
`guides/parity-and-migration-method.md`.

## The decisions, and where each is documented

| Decision | Made at | Document |
|---|---|---|
| machine series and shape | step 2 | `reference/compute/compute-engine.md` — custom types exist **only** for N and E series, and cost more |
| **zone** | step 2 | `reference/overview/regions-zones-and-locations.md` — a zonal disk **must** share its instance's zone, and does not move |
| disk family | step 2 | `reference/storage/persistent-disk-and-hyperdisk.md` — Hyperdisk performance is independent of size, Persistent Disk's is not |
| network shape | step 2 | `reference/networking/vpc.md` — **one global VPC** with a subnet per region, not one network per region |
| host / target project split | step 3 | `reference/migration/migrate-to-virtual-machines.md` §2 |
| wave boundaries | step 1 | from the **network dependency graph**, never the org chart |

## Known-bad configurations

### 1. Sizing from provisioned capacity instead of measured utilisation

**Why it is bad:** most estates are provisioned at several times their usage. Lifting the provisioned shape
carries that waste onto a cloud where it is billed by the second. Migration Center's inventory includes
**performance metrics** precisely so this is avoidable, and right-sizing is usually the largest single saving
in the whole project.

### 2. One VPC network per region, mirroring the source

**Why it is bad:** a Google Cloud VPC is **global**. Reproducing `N` regional networks also reproduces the
transit object you no longer need, and then you pay to connect networks that would have been one. Build one
network with a subnet per region (`guides/parity/networking.md` §2).

### 3. An auto-mode network

**Why it is bad:** auto mode's ranges all come from `10.128.0.0/9`, so they collide with every other auto-mode
network — including the one you will later need to peer with. Custom mode, with a planned address space.

### 4. Closing egress last

A fresh VPC is **implied deny on ingress and implied allow on egress**. A lifted estate therefore arrives with
unrestricted outbound.

**Why it is bad:** it is the opposite of most on-premises postures, and the moment to fix it is while the
estate is still being built — not after the first review.

### 5. Choosing the zone after the migration has started

**Why it is bad:** a zonal disk "must be in the same zone" as its instance and does not move zones. Fixing it
afterwards is a copy, not a reconfiguration.

### 6. Waves drawn by team

**Why it is bad:** two chatty systems land in different waves and their traffic crosses clouds at egress rates
for as long as the gap lasts. This is the most expensive avoidable planning error in a migration.

### 7. Treating re-platforming as implied

**Why it is bad:** a lift-and-shift is the cheapest migration and the most expensive destination. The estate
arrives with its old sizing, its old patching model and its old operating model. **Write re-platforming into
the plan as its own project with its own number**, or it will be discovered as a surprise when the invoice
arrives.

## What this pattern deliberately does not describe

The **replication cycle, the test clone and the cut-over mechanics**. The architecture page read for this
release does not detail them in the content read, and they are exactly what a cut-over window depends on.
Read the product's own lifecycle pages before scheduling one, and treat any remembered sequence as unverified
(`reference/migration/errors.md`).

## Verification, per wave

| Test | Expected |
|---|---|
| the migrated VM boots and its application answers | yes, before cut-over |
| the instance and all its disks are in the **same zone** | yes |
| egress rules are explicit, not implied-allow | yes |
| the wave's systems can still reach their dependencies | yes — and if a dependency is in a later wave, you have found a wave boundary error |
| the destination quota was sufficient | yes. If the wave half-failed, §3 of `reference/migration/errors.md` |
| **measured** utilisation after the move | compared against step 1's figure. That comparison is the input to the next wave's sizing |


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 91 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/gcp/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
