VMWARE → STACKIT · CASE STUDY

A nine-VM VMware estate, assessed end to end

One web shop, five of its servers, a Windows reporting server, a monitoring VM, an old CRM and a template: nine VMs on four port groups, exported with RVTools and assessed by StackToIT on 4 November 2026. This walkthrough gives the figures of the run, shows the files that carry the answers, and names the decisions that shaped the plan. The estate was written for this page; every number below is from the run's own output.

The estate and what the run made of it

VMRole and sizeClass and what stands out
shop-web01, shop-web02nginx storefront, 2 CPUs, 8 GiB, one 60 GiB disk eachRECONFIGURE, wave 2. Nothing flagged beyond the open settings every VM carries.
shop-app01Order API on RHEL 9, 4 CPUs, 16 GiB, disks of 60 and 100 GiBRECONFIGURE, wave 2. The second disk becomes a data volume.
shop-pg01, shop-pg02PostgreSQL 15 primary and replica, 8 CPUs, 32 GiB, disks of 100 and 500 GiBRECONFIGURE, wave 2. A memory reservation of 32768 is exported and stays open, since a server cannot express it.
shop-rep01Reporting server on Windows Server 2022 with EFI, 4 CPUs, 16 GiB, disks of 80 and 200 GiBRECONFIGURE, wave 2. Info finding for Windows guests: drivers and licence route.
shop-mon01Monitoring on Debian 12, 2 CPUs, 8 GiB, 40 GiB diskRECONFIGURE, wave 2. No finding.
legacy-crm01Old CRM on CentOS 7, E1000 adapter, a snapshot of 12288 MiBRECONFIGURE, wave 2. Warning for end of support, snapshot finding, legacy adapter finding.
tpl-ubuntu2204Base template, powered offREPLATFORM, wave 2. No image block is written; the template is the one unit left for the architect.
PG-Shop-Web, -App, -DB, -MgmtFour port groups on one distributed switchRECONFIGURE, wave 1. Four networks.

Source: assessment.json, migration/technical-sequencing.md and terraform/README.md of the run. Thirteen resources, thirteen units, twelve of them drafted as Terraform.

The figures of the run

FigureValueWhere to find it
Source resources and units13 and 13: 9 VMs including one template, 4 port groupsassessment.json, summary
Classes12 RECONFIGURE, 1 REPLATFORM; confidence MEDIUM on all 13console.txt, index.html
Sheets joinedvDisk 13 of 13 rows, vNetwork 9 of 9, vSnapshot 1 of 1, vMemory 2 of 2assessment.json, summary
Terraform12 units generated, 28 resource blocks, 28 variables to fill or confirmconsole.txt, execution/README.md
Plan61 steps: 28 automated, 33 manual in 6 work packagesexecution/README.md
Open critical settings136 on 13 units; no unit has all of its critical settings closed yetexecution/README.md
Properties321 checked on the 12 generated units: 216 carried or explained, 105 unaccounted, none named as not carriedconsole.txt
WavesWave 1: 4 networks. Wave 2: 8 VMs and 1 template.migration/technical-sequencing.md

The 105 unaccounted properties are listed per unit in assessment.json; examples are annotation, folder, hardware version and the adapter label. Read that list before you rely on the draft.

Grouping the web shop and reading its readiness

Left: the applications file written for this estate. It names five of the nine VMs as the webshop and states RTO, RPO and downtime tolerance. Right: the table of assurance/operational-readiness.md that the run built for that application.

Example inputapplications.yaml
applications:
  - id: webshop
    name: Webshop
    selectors:
      - vm.shop-web01
      - vm.shop-web02
      - vm.shop-app01
      - vm.shop-pg01
      - vm.shop-pg02
    environment: production
    owners:
      business: ecommerce
      technical: platform-team
    business_criticality: critical
    availability:
      rto: 4h
      rpo: 15m
      downtime_tolerance: 1h
Run outputassurance/operational-readiness.md
| Topic | What the run knows | Context |
|---|---|---|
| Log target | customer requirement (not in the source) | none of the 5 units of the application is a log resource of the source |
| Alarm owner | customer requirement (not in the source) | technical owner the applications file names: platform-team (who owns the alarms is the customer's to state) |
| Backup job | customer requirement (not in the source) | no backup resource in the source; RPO 15m as the applications file writes it |
| Restore | customer requirement (not in the source) | RTO 4h as the applications file writes it |
  • Four VMs stay outside

    The reporting server, the monitoring VM, the CRM and the template are named by no selector. The run does not guess ownership from names.

  • Values are echoed, not invented

    RPO 15m and RTO 4h appear as the file writes them. Log target, alarm owner, backup job and restore stay marked as customer requirements, because the source states none of them.

  • A backup is a decision

    The export has no backup resource. With an RPO of 15 minutes for the web shop, the backup design is work the team still owns.

Three of the nine VMs, and the order they move in

Left: the vInfo rows of a web server, the database primary and the old CRM. Right: the wave tables of migration/technical-sequencing.md.

Example inputRVTools_tabvInfo.csv
VM,Powerstate,Template,CPUs,Memory,NICs,Disks,Provisioned MiB,In use MiB,Primary IP Address,DNS Name,Datacenter,Cluster,Host,Folder,Firmware,HW version,Path,Annotation,OS according to the configuration file,OS according to the VMware Tools,VM UUID
shop-web01,poweredOn,False,2,8192,1,1,61440,30720,10.50.10.11,,DC-Munich,CL-Prod,esx11,prod,bios,vmx-19,[ds-prod-01] shop-web01/shop-web01.vmx,"Storefront, nginx",Ubuntu Linux (64-bit),Ubuntu 22.04.4 LTS,4202-vm20-0001
shop-pg01,poweredOn,False,8,32768,1,2,614400,368640,10.50.30.31,,DC-Munich,CL-Prod,esx11,prod,bios,vmx-19,[ds-prod-01] shop-pg01/shop-pg01.vmx,PostgreSQL 15 primary,Debian GNU/Linux 12 (64-bit),Debian GNU/Linux 12,4202-vm20-0004
legacy-crm01,poweredOn,False,2,4096,1,1,51200,25600,10.50.20.99,,DC-Munich,CL-Prod,esx11,prod,bios,vmx-19,[ds-prod-01] legacy-crm01/legacy-crm01.vmx,"Old CRM, vendor gone",CentOS 7 (64-bit),CentOS Linux 7,4202-vm20-0008
Run outputmigration/technical-sequencing.md
## Wave 1 — 4 unit(s)

| Unit | Class | Target |
|---|---|---|
| `network.PG-Shop-App` | RECONFIGURE / MEDIUM | STACKIT network |
| `network.PG-Shop-DB` | RECONFIGURE / MEDIUM | STACKIT network |
| `network.PG-Shop-Mgmt` | RECONFIGURE / MEDIUM | STACKIT network |
| `network.PG-Shop-Web` | RECONFIGURE / MEDIUM | STACKIT network |

## Wave 2 — 9 unit(s)

| Unit | Class | Target |
|---|---|---|
| `vm.legacy-crm01` | RECONFIGURE / MEDIUM | STACKIT Compute Engine |
| `vm.shop-app01` | RECONFIGURE / MEDIUM | STACKIT Compute Engine |
| `vm.shop-mon01` | RECONFIGURE / MEDIUM | STACKIT Compute Engine |
| `vm.shop-pg01` | RECONFIGURE / MEDIUM | STACKIT Compute Engine |
| `vm.shop-pg02` | RECONFIGURE / MEDIUM | STACKIT Compute Engine |
| `vm.shop-rep01` | RECONFIGURE / MEDIUM | STACKIT Compute Engine |
| `vm.shop-web01` | RECONFIGURE / MEDIUM | STACKIT Compute Engine |
| `vm.shop-web02` | RECONFIGURE / MEDIUM | STACKIT Compute Engine |
| `vm.tpl-ubuntu2204` | REPLATFORM / MEDIUM | STACKIT image |
  • Networks first

    Wave 1 holds the four networks. A server moves only after every unit it depends on.

  • Parallel inside a wave

    The nine units of wave 2 can move in parallel as far as dependencies go. The file calls the waves a starting point for the architect's plan, not a schedule.

  • Cutover facts are not guessed

    The same file has a cutover section. It states the facts the scan established, and for this estate it names no DNS or certificate unit, so cutover timing comes from the application owners.

The Windows reporting server as Terraform

Left: the two disks of shop-rep01. Right: its interface, server and data volume with the attach block, without the review comments.

Example inputRVTools_tabvDisk.csv
VM,Disk,Capacity MiB,Raw,Disk Mode,Sharing mode,Thin,Controller,Shared Bus,Disk Path,VM UUID
shop-rep01,Hard disk 1,81920,False,persistent,sharingNone,True,SCSI controller 0,noSharing,[ds-prod-01] shop-rep01/shop-rep01_0.vmdk,4202-vm20-0006
shop-rep01,Hard disk 2,204800,False,persistent,sharingNone,True,SCSI controller 1,noSharing,[ds-prod-01] shop-rep01/shop-rep01_1.vmdk,4202-vm20-0006
STACKIT Terraform by StackToITterraform/compute.tf
resource "stackit_network_interface" "vm_shop_rep01_nic1" {
  project_id = var.project_id
  network_id = stackit_network.network_PG_Shop_App.network_id
  ipv4       = "10.50.20.51"
}

resource "stackit_server" "vm_shop_rep01" {
  project_id        = var.project_id
  name              = "shop-rep01"
  machine_type      = var.vm_shop_rep01_machine_type
  availability_zone = var.availability_zone
  boot_volume = {
    source_type = "image"
    source_id   = var.vm_shop_rep01_image_id
    size        = 80
  }
  network_interfaces = [stackit_network_interface.vm_shop_rep01_nic1.network_interface_id]
}

resource "stackit_volume" "vm_shop_rep01_disk2" {
  project_id        = var.project_id
  name              = "shop-rep01-disk2"
  availability_zone = var.availability_zone
  size              = 200
  performance_class = var.vmware_volume_performance_class
}

resource "stackit_server_volume_attach" "vm_shop_rep01_disk2" {
  project_id = var.project_id
  server_id  = stackit_server.vm_shop_rep01.server_id
  volume_id  = stackit_volume.vm_shop_rep01_disk2.volume_id
}
  • Sizes carried over

    The 80 GiB system disk is the boot volume, the 200 GiB disk a data volume. The address 10.50.20.51 is set on the interface.

  • Left to you

    Image ID and machine type are variables. For Windows, choose a machine type the STACKIT table marks as Windows Server compatible and decide the licence route; both are described in the Windows guide.

The work that remains, by owner

Work packageOwner and stepsWhat it asks
WP-01 Decide and set critical settings (foundation)Network Architect, 4 stepsSet the network prefix for each of the four networks. The export holds no subnet mask.
WP-02 Decide and set critical settings (foundation)Platform Architect, 4 stepsConfirm the name each network carries against what refers to the port group name.
WP-03 Set up by hand (platform services)Platform Architect, 1 stepSet up the template tpl-ubuntu2204 as a STACKIT image, or record that none is needed.
WP-04 Decide and set critical settings (workloads)Network Architect, 8 stepsPer VM: whether a disconnected adapter should be connected, and how the VM keeps its addresses.
WP-05 Decide and set critical settings (workloads)Platform Architect, 8 stepsPer VM: machine size, disk capacity and mode, power state after cutover, firmware, memory reservation and the other open settings.
WP-06 Decide and set critical settings (workloads)Security Architect, 8 stepsChoose the availability zone, since the source datacenter is not mapped to a STACKIT location, and the other settings of source placement.

From migration/work-packages.csv and execution/manual/actions.md. Every package can be started now; none waits for a decision.

Answering the one request that blocks the draft

The first run listed five open requests and one of them, the target region, blocked the draft. Left: the answer, written into a copy of review/inputs.yaml saved as answers.yaml. Right: the Decisions line of the second run, started with the --inputs flag.

Example inputanswers.yaml
  - id: INP-TSE-1eaf5b60fa62
    kind: TARGET_SELECTION
    topic: target.region
    scope:
      profile: default
    # options: eu01 | eu02
    value: eu01
    # explanation: why you chose this (optional; remove the # to write it)
    answered_by: CUSTOMER_ARCHITECT
    answered_at: "2026-11-04"   # YYYY-MM-DD
Run outputconsole.txt
Decisions     13 units to review (136 critical settings) · no decision holds a plan step · Inputs: 0 design inputs wait · 4 open requests (0 block the draft, 4 are preferences this build cannot apply — inputs-template.yaml, NOT APPLICABLE IN THIS BUILD, says where to set each)
  • The count changes

    Open requests fall from five to four, and the blocking request from one to none. The console reports one answer applied, none stale, none invalid.

  • The draft text does not

    Comparing the terraform folders of both runs shows a difference only in the run ID of the README. The region was already eu01 in the variables, so the answer confirmed it rather than changed it.

  • Four preferences wait

    Project, observability, public ingress and egress are recorded as preferences this build cannot apply. The answer file says where each is set instead: the project through the project_id variable, ingress and egress in the target environment file, observability instances in the STACKIT project itself.

Decisions that shaped the plan

  • What counts as the web shop

    Five VMs are the application. The reporting server, monitoring and CRM were left out on purpose; each needs its own owner and RPO.

  • Database: rehost or managed

    The pair is drafted as servers and volumes. PostgreSQL Flex lists version 15 as supported until November 2027, so a managed target is possible; the database guide compares both.

  • Windows reporting server

    Licence route and machine type are open. STACKIT's licensing guide separates a licence-included image from your own image and licences.

  • The CRM on CentOS 7

    The run warns that STACKIT public images will not cover a guest past end of support. Upgrade first, or migrate it as a custom image at your own risk.

  • The template

    Convert and upload the disk, or rebuild from a public image. The custom image page limits an image to 70 GB; this template is 30 GiB provisioned.

  • Prefixes and addresses

    An interface keeps its address after creation, so the four prefixes are settled before the first apply.

From here to a first apply

  1. Close WP-01 and WP-02

    Prefixes and names unlock the four networks. Put the answers into review/ and run again; the next run reads them.

  2. Decide the application questions

    Database target, reporting server licence, CRM upgrade path and the template.

  3. Fill the variables

    Machine types, image IDs and the availability zone. terraform/variables.tf declares 28 variables.

  4. Prepare the images

    Consolidate the CRM snapshot, convert disks to qcow2 or raw, upload them and record the image IDs.

  5. Validate in a test project

    Run the OpenTofu plan against a test project. The package says that StackToIT never runs apply.

  6. Cut over by application

    Use the waves as a starting point and the owners' downtime tolerance as the limit.

Questions about this walkthrough

Is this a real customer estate?

No. The estate was written for this page and assessed on 4 November 2026. Names, sizes and addresses are invented; the figures are the output of the run.

Why are 0 of the plan's automated steps ready to run?

Because 136 critical settings are open and the draft has variables without values. The package reports a partially executable plan and says what each step waits for.

What did the run not look at?

The data on the disks, application behaviour and firewall rules. RVTools describes infrastructure, and the data movement file states that data on VM disks is not assessed.

Can I reproduce the run?

Export your own estate with RVTools, including vSnapshot and vMemory, and run stacktoit assess on the export with an applications file if you want applications recorded.

Sources

Your next move: STACKIT.

Tell us about your estate. We show you what StackToIT delivers for it: target architecture, Terraform artifacts and a structured migration plan.