# Recreate a VM

Three problems, one procedure: growing a root disk, which is never resizable;
replacing a machine whose guest you can no longer reach; moving off hardware
that failed. Both machines exist at the cutover, so you can verify the new one
before anything points at it.

It works because **configuration is code you re-run** and **data lives on
volumes**, which detach from one VM and attach to another intact. The root
disk does not survive: anything on it you have not scripted is gone.

## The recipe

```
# 1. create the replacement (bigger root, if that is why you are here).
#    It comes up stopped, which is what lets step 2 happen before first boot.
POST /v1/vms {"name":"web2","ram_mb":4096,"disk_gb":80,
              "image":"ubuntu-lts","ssh_keys":[...]}   + Idempotency-Key

# 2. move the data — detach needs the VM stopped, so unmount in-guest first,
#    and refuses a volume the old VM's snapshots include: delete those first
#    (409 volume_in_snapshots names them)
POST /v1/vms/{vm_OLD}/actions   {"type":"stop"}
POST /v1/volumes/{id}/actions   {"type":"detach"}
POST /v1/volumes/{id}/actions   {"type":"attach","vm_id":"vm_NEW"}

# 3. start the replacement, then re-run your configuration automation
POST /v1/vms/{vm_NEW}/actions   {"type":"start"}

# 4. point DNS at the new VM's address (GET /v1/vms/{id} carries it)

# 5. verify, then delete the old VM. Its volumes
#    left in step 2; delete any snapshots it still holds first, newest first,
#    or this answers 409 vm_has_snapshots and names them.
DELETE /v1/vms/{vm_OLD}
```

## Step 4 is a DNS change, not an address move

The IP is bound to its VM for that VM's life and no endpoint reassigns one
([why](../vm.md#the-ip-is-fixed-to-the-vm)). So **put a DNS name in front of
every VM** before you need this procedure, at a low TTL — 60s is plenty. With
one, the cutover is a record change; without one, it is a search for
everything that hard-coded the address.

If a specific address genuinely has to move, that is a ticket
(`POST /v1/support/tickets`), not a call.

## What goes wrong

- `volume_in_snapshots` (409) — the old VM has a snapshot that includes the
  volume you are detaching, and a snapshot restores a volume only on the VM
  that took it. The `snapshots` extra names them; delete those first. Deleting
  a snapshot leaves the volume's current data alone.
- `vm_not_stopped` (409) — detach needs the VM stopped. Unmount in-guest,
  stop, detach.
- `vm_has_snapshots` / `vm_has_volumes` (409) — the delete in step 5 refuses
  while the old machine still holds either, and lists what is left. The order
  matters: snapshots first (newest first), then detach volumes, then delete.
- `quota_exceeded` (403) — both machines exist at once, so the project needs
  headroom for both across the cutover.
  [Quotas](../account.md#default-quotas).
- `no_capacity_available` (409) — no room for the replacement right now.
  Nothing was changed, and raising your quota will not help.

## What it costs

Both VMs bill while both exist — RAM only while each runs, root disk, address
and snapshots regardless. Delete the old machine once the new one is verified;
stopping it saves only the RAM line.
