AZURE → STACKIT · CHECKLIST

Azure to STACKIT migration checklist

Thirty-four checks in six phases, each one tied to the file where a StackToIT run holds the answer. The figures and file names come from an assessment of a small Azure estate (a scale set, PostgreSQL, Redis, a storage account, Key Vault and a network) run on 4 November 2026; your estate will have its own numbers and the same files.

What a run tells you before the first check

Left: three lines of the console summary of the demo estate. Right: two lines of execution/verify/checks.md, the file that turns the plan into checks you can tick: the first from its 'Before each step' list, the second from 'After each step'.

Console summaryconsole output
Source        9 resources · 7 units · visibility: Complete
Migration     6 drafted · 1 need no resource (of 7 units the draft considered)
Attention     7 units to review · 6 open requests (1 block the draft, marked in inputs-template.yaml)
Checks file of the runexecution/verify/checks.md
- [ ] `TF/stackit_valkey_instance.erp` · `variable-supplied` `variable=erp_cache_allowed_cidrs` — The variable `erp_cache_allowed_cidrs` has a value.
- [ ] `TF/stackit_valkey_instance.erp` · `resource-exists` `address=stackit_valkey_instance.erp` — `stackit_valkey_instance.erp` exists in the STACKIT project (OpenTofu's state lists it).
  • Seven units from nine resources

    Nine Terraform resources became seven units. A container or an attachment is read with the unit it belongs to, so counts of units and resources differ by design.

  • One request blocks the draft

    The run lists six open requests and marks one as blocking. Answer that one first: it sits in review/inputs.yaml.

  • The checks are the plan, ticked

    execution/verify/checks.md has a line for every variable that must have a value before a step, and a line for every resource that must exist after it.

Phase 1: Discovery

What goes in, and what the run cannot see.

  • Every Terraform root is in the assessed folder

    The run reads azurerm and azapi code and never connects to Azure. Anything created by hand, or outside the folder, is not seen. Check: engineering/architect-report.md states the source status and the resources read.

  • The provider lock file is committed

    Without .terraform.lock.hcl the run caps the units of that provider at MEDIUM confidence and marks none of them as suited to automated steps. Check: the provider note near the top of engineering/architect-report.md.

  • Every variable has a value

    A unit that reads an unset variable gets no draft, and the run names the variable. Check: the Next line of the console and the first section of the architect report.

  • Stateful units are listed

    migration/data-movement.md names the units that hold data: here PostgreSQL, Redis and the storage account. Key Vault is not among them, so inventory secrets and keys separately.

  • Hand-made resources are added

    Resource groups, policies, role assignments and Entra objects that live outside Terraform need their own inventory; export them to code or list them by hand.

Phase 2: Design

The decisions that change what is built.

  • The region is answered

    target.region is the one request that blocks the draft. Answer it in review/inputs.yaml and run again on the same output folder.

  • Resource groups map to projects

    STACKIT has no resource groups. The work packages in migration/work-packages.csv carry the decision per unit; settle one project layout and answer them all with it.

  • The network design is chosen

    The virtual network is drafted as no resource of its own; its address space and the Network Area question are open settings. Check: the Network Architect package.

  • Every REDESIGN and MANUAL_REVIEW unit is read first

    This demo has none: five units are RECONFIGURE and two REPLATFORM, all at MEDIUM confidence. Estates with Entra ID groups or Cosmos DB can land in REDESIGN; read those rows of engineering/review.csv before anything else.

  • Database exposure is decided

    The PostgreSQL source had public network access on. On STACKIT clients reach the instance through its access list, so the allowed CIDRs variable is the control. It has no default.

  • Secrets and keys have an owner

    Key Vault becomes a Secrets Manager instance, with KMS for keys. The Identity Architect package holds the open settings.

  • Decisions are recorded

    Write the review into review/decisions.yaml. A record is a statement that someone looked, not a change to the draft.

Phase 3: Build

Turning the draft into something that plans cleanly.

  • Variables are supplied

    The draft declares 12 variables. review/target-values.tfvars lists the 9 without a default, one stub each: project id, image, machine type, boot volume size, Valkey plan and version, PostgreSQL storage class and the two allowed-CIDR lists. Region, availability zone and nameservers carry defaults (eu01, eu01-1, STACKIT's resolver addresses) that you confirm.

  • The not-carried comments are read

    Every block in terraform/ has comments for the settings it could not carry. engineering/not-carried.csv lists them in one table.

  • The provider version is the one assessed

    terraform/terraform.tf pins the STACKIT provider the draft was written against. Keep it until the review is finished.

  • Scale sets are understood

    The scale set became a fixed group of two servers with a count. STACKIT has no scale-set object, so capacity changes by editing the count; an affinity group is optional.

  • Images exist

    The Azure image reference is not carried. Choose a public STACKIT image or import a converted one (raw, qcow2 or iso).

  • Nothing is applied yet

    The draft is for review. The run never applies anything; applying is a step a person takes with OpenTofu.

Phase 4: Data

The run lists what holds data. It does not move it.

  • A mechanism per stateful unit

    All three units show the mechanism UNKNOWN and the state DECISION_REQUIRED in migration/data-movement.md.

  • RPO, downtime and data class are written down

    The run takes RTO, RPO and downtime tolerance from an applications file (--applications) and records them as written. Without them the data-movement table shows NOT_PROVIDED for data class, RPO and downtime, and assumes nothing.

  • PostgreSQL has a dump-and-restore or replication plan

    For example pg_dump and pg_restore for a small database, logical replication for a short cut-over. Size, change rate and tolerated downtime choose.

  • Object data has a copy plan, and a second copy where needed

    The source storage account is geo-redundant. STACKIT Object Storage has no managed cross-region replication, so a second copy needs its own sync job.

  • The Redis decision is explicit

    Rebuild the cache, or carry it over. Azure exports RDB snapshots only from the Premium and Enterprise tiers, so the Standard cache of this demo has no export path. The STACKIT backup restores into the same instance; a backup for another instance is downloaded, which needs an encryption key, and restored by hand.

  • Disks are exported before the VM is touched

    A VHD cannot be downloaded from a disk attached to a running VM; stop the VM or snapshot it. STACKIT imports raw, qcow2 and iso.

Phase 5: Cutover

Order, names and the way back.

  • The wave order is accepted

    migration/technical-sequencing.md puts Key Vault, PostgreSQL, Redis, storage and the network first, the subnet second and the servers third. A wave is a starting point for a schedule.

  • Names, addresses and certificates are listed

    The run found no DNS or certificate facts in this source. That does not mean there are none: list every name, address and certificate that clients use.

  • Clients have their new credentials

    STACKIT generates the password of the Valkey credential; the draft exposes it as the sensitive output erp_valkey_credential_password, and the state holds it in plain text. The PostgreSQL user is not in this draft, so create it and its password yourself. Hand both to clients before the switch.

  • A rollback is written for each step

    The plan says of its manual steps that it does not know how they are undone. Write the way back, with its owner, before the window opens.

  • Practice: lower DNS lifetimes in advance

    A general measure, not a run output: shorten record lifetimes days before the switch so a rollback propagates quickly.

Phase 6: After

Proof, record and retirement.

  • The after-step checks are ticked

    Every resource in execution/verify/checks.md exists in the STACKIT project and the OpenTofu state lists it.

  • Progress is journalled

    review/progress.yaml is where you record each step as in progress, done, failed or waived. It records what you did; it proves nothing.

  • Access is tested per role

    Sign in with one principal per role and confirm both what works and what is refused.

  • The Azure side stays until the checks hold

    Keep the source running for an agreed overlap, then retire it with a ticket of its own.

  • The run is repeated on the final code

    Assess again after changes to the Terraform so the report matches what exists.

Which file answers which question

QuestionFile in the runWhat you find
What was read, and what did it become?assessment.json, migration/source-target.csvUnit, class, confidence, STACKIT target
What needs a person?engineering/architect-report.md, migration/work-packages.csvReview queue and work packages with owner roles
What was not carried over?engineering/not-carried.csvSetting by setting, with the reason
In what order?migration/technical-sequencing.md, migration/waves.csvWaves from dependencies
Where does data move?migration/data-movement.mdStateful units and the open mechanism
What do I tick?execution/verify/checks.mdBefore and after each step

File names are those of the demo run. The set of files depends on the input and the run options.

Questions about the checklist

Is this checklist a plan?

It is the list of checks around a plan. The plan itself, with ordered steps and owners, is execution-plan.json and the migration plan file in the run.

Do I need a run to use it?

No, but each line points to a file that a run writes. Without a run, you answer the same questions by hand and keep the answers in your own tracker.

Why does the run ask who owns a decision?

Each work package names a role, such as Identity Architect or Network Architect, so a review has an owner from the start.

What is not on this checklist?

Contracts, staff training and application tests. They are outside what a Terraform assessment can see.

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.