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
| VM | Role and size | Class and what stands out |
|---|---|---|
| shop-web01, shop-web02 | nginx storefront, 2 CPUs, 8 GiB, one 60 GiB disk each | RECONFIGURE, wave 2. Nothing flagged beyond the open settings every VM carries. |
| shop-app01 | Order API on RHEL 9, 4 CPUs, 16 GiB, disks of 60 and 100 GiB | RECONFIGURE, wave 2. The second disk becomes a data volume. |
| shop-pg01, shop-pg02 | PostgreSQL 15 primary and replica, 8 CPUs, 32 GiB, disks of 100 and 500 GiB | RECONFIGURE, wave 2. A memory reservation of 32768 is exported and stays open, since a server cannot express it. |
| shop-rep01 | Reporting server on Windows Server 2022 with EFI, 4 CPUs, 16 GiB, disks of 80 and 200 GiB | RECONFIGURE, wave 2. Info finding for Windows guests: drivers and licence route. |
| shop-mon01 | Monitoring on Debian 12, 2 CPUs, 8 GiB, 40 GiB disk | RECONFIGURE, wave 2. No finding. |
| legacy-crm01 | Old CRM on CentOS 7, E1000 adapter, a snapshot of 12288 MiB | RECONFIGURE, wave 2. Warning for end of support, snapshot finding, legacy adapter finding. |
| tpl-ubuntu2204 | Base template, powered off | REPLATFORM, wave 2. No image block is written; the template is the one unit left for the architect. |
| PG-Shop-Web, -App, -DB, -Mgmt | Four port groups on one distributed switch | RECONFIGURE, 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
| Figure | Value | Where to find it |
|---|---|---|
| Source resources and units | 13 and 13: 9 VMs including one template, 4 port groups | assessment.json, summary |
| Classes | 12 RECONFIGURE, 1 REPLATFORM; confidence MEDIUM on all 13 | console.txt, index.html |
| Sheets joined | vDisk 13 of 13 rows, vNetwork 9 of 9, vSnapshot 1 of 1, vMemory 2 of 2 | assessment.json, summary |
| Terraform | 12 units generated, 28 resource blocks, 28 variables to fill or confirm | console.txt, execution/README.md |
| Plan | 61 steps: 28 automated, 33 manual in 6 work packages | execution/README.md |
| Open critical settings | 136 on 13 units; no unit has all of its critical settings closed yet | execution/README.md |
| Properties | 321 checked on the 12 generated units: 216 carried or explained, 105 unaccounted, none named as not carried | console.txt |
| Waves | Wave 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.
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| 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.
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## 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.
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-0006resource "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 package | Owner and steps | What it asks |
|---|---|---|
| WP-01 Decide and set critical settings (foundation) | Network Architect, 4 steps | Set 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 steps | Confirm the name each network carries against what refers to the port group name. |
| WP-03 Set up by hand (platform services) | Platform Architect, 1 step | Set 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 steps | Per 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 steps | Per 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 steps | Choose 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.
- 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-DDDecisions 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
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.
Decide the application questions
Database target, reporting server licence, CRM upgrade path and the template.
Fill the variables
Machine types, image IDs and the availability zone. terraform/variables.tf declares 28 variables.
Prepare the images
Consolidate the CRM snapshot, convert disks to qcow2 or raw, upload them and record the image IDs.
Validate in a test project
Run the OpenTofu plan against a test project. The package says that StackToIT never runs apply.
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.