Architecture, Migration and Hybrid Cloud

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

See the section bibliography for the reference material consulted while preparing these pages.

Commands on this page target Azure CLI 2.90.0, the connectedk8s CLI extension (auto-installed on first use, version 1.10.x at the time of writing) for Arc-enabled Kubernetes, and the Azure Connected Machine agent’s own azcmagent tool (not an az extension) for Arc-enabled servers, checked 2026-09-27 — re-verify all three against the az connectedk8s reference and the azcmagent connect reference before relying on them. The migrate CLI extension is explicitly a preview surface still under development; where it does not yet cover a task (creating a project, running an assessment), this page says so and points to the portal instead of inventing flags that do not exist.

This page steps back from any single service to the three things that decide whether and how Bookshelf (or any workload) should be on Azure at all: a structured way to judge whether an architecture is any good (the Well-Architected Framework), a structured way to plan the whole organization’s move (the Cloud Adoption Framework), the mechanics of actually moving existing workloads in (Azure Migrate and its companion services), and what to do with the workloads that cannot, or should not, move at all (Azure Arc, Azure Local, Azure VMware Solution). Choosing a compute service for something already destined for Azure is covered in Choosing a Compute Service; what a migrated workload then costs is covered in Cost Management.

export RG=rg-bookshelf
export LOCATION=eastus2

The Well-Architected Framework

The Azure Well-Architected Framework (WAF) is a set of design principles, organized under five pillars, used to evaluate and improve a workload’s architecture — not a certification or a one-time gate, but a lens applied repeatedly as a system evolves:

Pillar Workload concern

Reliability

Resiliency, availability and recovery — designing for the business’s actual uptime and recovery requirements, then for resilience and operations, while keeping the design as simple as the requirements allow.

Security

Protecting confidentiality, integrity and availability against threats — covered in depth for identity, secrets and networking on Identity and Access, Key Vault and Secrets and Virtual Networks.

Cost Optimization

Cost modeling, budgets and reducing waste — optimizing for actual usage and rate, with cost efficiency treated as a design constraint rather than an afterthought; expanded on Cost Management.

Operational Excellence

Holistic observability and DevOps practices — standards, monitoring and safe deployment practices, so operating the workload is not a manual, ad hoc activity.

Performance Efficiency

Scalability and load testing — scaling a workload horizontally where possible, testing early and often, and monitoring the health of the running solution under real load.

Every pillar embeds a tradeoff: pursuing one further (for example, maximum reliability through multi-region active-active deployment) generally costs more or adds operational complexity, so the framework’s principles are applied as a set of conscious tradeoffs against the workload’s actual business requirements, not as a checklist to maximize blindly.

The Well-Architected Review

The Azure Well-Architected Review is a free, guided self-assessment (a questionnaire covering all five pillars) that scores an existing or planned workload’s architecture against the framework’s principles and produces a prioritized list of recommendations, each linked back to the specific design principle it addresses. It complements, and feeds into, two related tools:

  • Azure Advisor continuously analyzes a subscription’s actual resource configuration and telemetry against the five pillars and surfaces recommendations directly in the portal, without a manual questionnaire.

  • Advisor score aggregates those recommendations into a single number per pillar, so the review’s point-in-time assessment and Advisor’s ongoing telemetry-based one can be tracked against the same five categories over time.

In the Azure portal

  1. Open the Azure Well-Architected Review tool (also reachable from the portal’s Advisor blade → Get workload assessment) and choose the workload category closest to the one being reviewed (for example, a generic "Foundational" review for catalog-api).

  2. Answer each pillar’s questions; the tool needs no Azure subscription selected to run and can be filled in for a design that is still on paper.

  3. Review the generated report: a per-pillar score and a prioritized recommendation list, each one linking to the Well-Architected Framework guidance it is based on.

  4. For an existing subscription, open Advisor (left navigation Advisor score) to see the same five pillars scored from actual resource telemetry instead of self-reported answers.

The Cloud Adoption Framework

Where the Well-Architected Framework judges one workload’s architecture, the Cloud Adoption Framework (CAF) is Microsoft’s guidance for an entire organization’s move to Azure: it organizes decisions into seven adoption phases, four of them foundational and sequential, three of them operational and running continuously in parallel once the foundation exists:

Phase Key decision Runs

1. Strategy

What should our Azure adoption look like?

Foundational (sequential)

2. Plan

How will we prepare for Azure adoption?

Foundational (sequential)

3. Ready

How will we build our Azure landing zone?

Foundational (sequential)

4. Adopt

How will we migrate, modernize and build workloads?

Foundational (sequential)

5. Govern

How will we control our Azure environment?

Operational (parallel, ongoing)

6. Secure

How will we protect our Azure environment?

Operational (parallel, ongoing)

7. Manage

How will we operate and optimize Azure over time?

Operational (parallel, ongoing)

flowchart LR S["1. Strategy"] --> P["2. Plan"] --> R["3. Ready"] --> A["4. Adopt"] A --> G["5. Govern"] A --> Sec["6. Secure"] A --> M["7. Manage"] G <--> Sec Sec <--> M G <--> M

The Ready phase’s output is an Azure landing zone: a pre-provisioned subscription and resource-group structure, network topology, identity baseline and policy set that every subsequent workload lands into, rather than each workload team improvising its own resource organization, networking and RBAC from scratch. Bookshelf’s own baseline — rg-bookshelf, vnet-bookshelf, the management-group/subscription hierarchy and its resource locks — follows exactly that pattern; see Resource Organization and Infrastructure as Code for how it is actually provisioned and repeated consistently via Bicep. CAF also publishes narrower scenarios that build on this same foundation for a specific technology or business need — Data platform, AI adoption, AI agents, Sovereignty and Azure VMware Solution among them — rather than one generic guide trying to cover every case.

Migration

Migration strategies (the "R’s")

CAF’s Plan phase assigns each existing workload one of eight migration strategies, commonly called the R’s; picking one starts from the business driver behind moving that workload at all, not from a default preference for any single strategy:

Strategy When to choose it

Retire

The workload has little remaining business value, or the cost of migrating or modernizing it outweighs the benefit — decommission it instead of moving it.

Retain

The workload is stable, compliant and meets its business needs with no near-term driver to move — keep it where it is, optionally managed from Azure via Azure Arc or rehosted onto Azure Local instead of public-cloud Azure.

Rehost

A like-for-like, minimal-change move (on-premises VM → Azure VM, IaaS → IaaS, PaaS → PaaS) for a stable workload needing no near-term modernization — the fastest, lowest-risk path, and what Azure Migrate’s server migration targets by default.

Replatform

A move to a managed Azure PaaS target with minimal code changes (VM → App Service, SQL Server on a VM → Azure SQL Database) when the goal is offloading operational overhead, not rewriting the application.

Refactor

Code changes that reduce technical debt or adopt Azure SDKs/cloud design patterns, without a wholesale architecture change.

Rearchitect

Architecture changes — decomposing a monolith into services, letting components scale independently — needed to unlock cloud-native capabilities the current design cannot use; see Migration Path: From a Monolith to Microservices for the pattern in depth.

Rebuild

A full rewrite as a cloud-native solution, when the legacy system is too outdated or inflexible to evolve incrementally.

Replace

Dropping a custom system in favor of a SaaS or AI-based alternative that already meets the need with little customization.

Anti-patterns

  • Rehosting a workload that is already unhealthy. Rehosting does not fix an existing performance, reliability or architectural problem — it moves the same problem onto Azure billing, and the technical debt still has to be paid down later, usually at higher cost once the workload is live in production.

  • Skipping discovery and dependency mapping. Migrating a server without first mapping which other servers and services it actually talks to (Azure Migrate’s dependency-analysis feature, below) leads to a cutover that breaks an undocumented dependency no one remembered.

  • Treating migration as a one-time event. CAF’s Govern/Secure/Manage phases are deliberately continuous: a "finished" migration that is never revisited against changing cost, security or compliance requirements drifts out of Well-Architected shape within months.

  • No rollback or failback plan. A migration wave without a tested failback path (Azure Site Recovery’s planned-failover/failback flow, below, or simply keeping the source environment live until cutover is verified) turns a routine migration into an unplanned outage the moment something in the target environment is wrong.

  • Ignoring the landing zone. Migrating workloads directly into an ad hoc resource group, bypassing the Ready-phase landing zone’s naming, policy and network baseline, recreates the governance gap CAF’s Ready phase exists to close.

Azure Migrate

Azure Migrate is the free, unified hub for discovering, assessing and migrating on-premises and other-cloud workloads — servers, SQL Server databases, web apps and (via Azure Data Box, below) offline bulk data — through one Azure Migrate project. A migration journey through it has three phases:

Decide

Discover the on-premises estate with the lightweight Azure Migrate appliance (a VM deployed in the source datacenter that continuously reports configuration and performance data back to the project) or, for air-gapped/restricted networks, the offline Azure Migrate Collector. The resulting inventory feeds a business case — an estimated on-premises-vs-Azure total cost of ownership, including the CapEx-to-OpEx shift covered conceptually on Cloud Concepts — used to justify the move before planning starts.

Plan

Run assessments against the discovered inventory for Azure readiness, right-sizing (VM size, Azure SQL configuration, Azure VMware Solution node count), cost estimation and dependency analysis (network dependencies between servers, so a migration wave is planned without missing a dependency the discovery data alone would not reveal).

Execute

Migrate with the integrated Azure Migrate and Modernize tool — agentless or agent-based for VMware VMs, provider-agent-based for Hyper-V VMs, and replication-appliance-based for physical servers, other clouds' VMs, and Windows web apps migrating into Azure App Service — or with a partner tool integrated into the same hub.

Since November 2025, creating a new Azure Migrate project requires the built-in Azure Migrate Owner role or higher — a narrower permission than earlier, worth checking for before a migration project kicks off.

In the Azure portal

  1. From the portal’s search bar, type Azure Migrate and select Create project; set the resource group (rg-bookshelf), project name and region.

  2. On the project’s Servers, databases and web apps blade, select Discover → download and deploy the Azure Migrate appliance OVA/VHD into the source environment, then register it against the project with the key shown.

  3. Once discovery data arrives, select Assess → choose an assessment type (Azure VM, Azure SQL, Azure App Service) and target region/settings, then Create assessment to get sizing, readiness and cost estimates.

  4. Review the generated business case report (Business case blade) for the aggregate cost/savings picture before committing to a migration wave.

  5. Select Migrate on the chosen servers to hand off to Azure Migrate and Modernize (or a partner tool) for the actual cutover.

With the Azure CLI

Project creation, discovery and assessment are portal-driven today; the migrate CLI extension (preview, added automatically on first use) currently covers reading back discovered inventory and Azure Local-target migration operations, not creating a project or an assessment from the command line:

# List servers an already-deployed appliance has discovered in an existing project
az migrate get-discovered-server \
  --project-name migrate-bookshelf \
  --resource-group $RG \
  --source-machine-type VMware

Azure Database Migration Service

Moving the data inside a database engine — as opposed to the VM or App Service plan hosting it — is already covered in depth on the managed-databases overview page, including the current DMS classic SQL-Server-scenario retirement date; this page only places it in the wider migration picture: DMS is the data-plane counterpart to Azure Migrate’s server/VM-plane assessment and cutover, invoked from the same overall migration wave once the target Azure SQL Database, Managed Instance or SQL Server-on-VM has been sized by an Azure Migrate assessment.

Azure Site Recovery

Azure Site Recovery (ASR) is Azure’s business-continuity-and-disaster-recovery (BCDR) service: it keeps a continuous, application-consistent replica of a workload’s VMs at a secondary location and orchestrates failover (planned, with zero data loss, or unplanned, with minimal data loss depending on replication frequency) and failback once the primary site is healthy again. It covers three overlapping scenarios that share the same replication/failover mechanics:

  • Azure-to-Azure — replicating Azure VMs from one region to another (or, in preview, from an Azure Extended Zone to the region it is attached to) for regional-outage protection.

  • On-premises-to-Azure — replicating VMware VMs (via the Azure Site Recovery replication appliance), Hyper-V VMs (including those managed by System Center VMM) and physical Windows/Linux servers into Azure, which is also a migration path in its own right, not only a DR one — the same replicate-then-failover mechanism that protects a workload against an outage cuts over that workload permanently when the "failover" is never failed back.

  • Azure Local integration (preview) — replicating Hyper-V VMs running on Azure Local clusters for hybrid disaster recovery, extending the same ASR concepts to the on-premises platform covered later on this page.

Recovery plans group several VMs of a multi-tier application (Bookshelf’s catalog-api, orders-api and their database tier, for example) into one orchestrated failover sequence, optionally scripted with Azure Automation runbooks, rather than failing each VM over by hand in the right order.

In the Azure portal

  1. From the portal’s search bar, type Recovery Services vaults and select Create; set the resource group (rg-bookshelf), vault name and region (a different region from the protected VMs' own, for regional protection).

  2. On the vault’s Site Recovery blade, select Configure Site Recovery → Replicate application and choose the source (Azure VMs in another region, VMware, Hyper-V or physical servers) and target settings.

  3. Review replication health on the vault’s Replicated items blade, then use Failover for a planned or unplanned failover drill, and Failback once the primary is healthy again.

  4. Under Recovery Plans (Site Recovery), group related VMs into one plan and add pre/post-action Automation runbooks if the failover sequence needs scripted steps between VMs.

CLI support for configuring replication itself is narrower than the portal’s Site Recovery wizard; provisioning and day-to-day operation of ASR on this page’s scenarios is covered through the portal walkthrough above, with PowerShell (the Az.RecoveryServices module) as the scriptable alternative Microsoft documents in most depth.

Azure Data Box

Bulk, offline data transfer into or out of Azure — already introduced on the storage-accounts page as a data-movement tool — is also one of Azure Migrate’s four supported workload categories (servers, databases, web apps, data), used when a migration wave’s data volume is too large, or the link to Azure too slow or expensive, for an online copy: data is copied onto a Data Box device on-premises, shipped to a Microsoft datacenter, and ingested directly into the target storage account, without re-explaining the device models or ordering flow already covered on that page.

Hybrid and multi-cloud

Azure Arc

Azure Arc projects non-Azure and on-premises resources into Azure Resource Manager, so they can be governed, secured and monitored with the same tools — Azure Policy, Azure RBAC, Azure Monitor, Microsoft Defender for Cloud — as resources actually running in Azure, without moving the workload itself. It is the control plane extends to anywhere half of the "hybrid" story on this page, complementing Azure Local’s bring Azure infrastructure on-premises half below.

flowchart TB subgraph Azure["Azure control plane"] ARM["Azure Resource Manager"] Policy["Azure Policy / RBAC / Monitor / Defender for Cloud"] end ARM --- Policy Azure -->|"Arc agent"| Servers["Arc-enabled servers\n(on-prem / other cloud VMs)"] Azure -->|"Arc agent + Helm"| K8s["Arc-enabled Kubernetes\n(any CNCF-conformant cluster)"] Azure -->|"Arc resource bridge"| VMware["Arc-enabled VMware vSphere / SCVMM"] Azure -->|"built in"| Local["Azure Local"]

Azure Arc currently manages four kinds of resources this way: servers (physical and virtual machines outside Azure, including VM lifecycle operations on Azure Local, VMware vCenter and System Center VMM environments), Kubernetes clusters (any CNCF-conformant distribution, anywhere), Azure data services (SQL Managed Instance running on Kubernetes, on-premises or at the edge) and SQL Server instances (extending Azure services to SQL Server itself, wherever it runs). As of September 2025, Arc’s older indirectly connected mode is retired; every current onboarding path connects directly.

Azure Arc-enabled servers

Onboarding a server does not use the az CLI directly — it installs the Azure Connected Machine agent and runs that agent’s own azcmagent connect command, which creates the Arc-enabled server resource in Azure Resource Manager and associates the agent with it. Verification and day-to-day management afterwards do use az, via the connectedmachine command group.

In the Azure portal

  1. From the portal’s search bar, type Servers - Azure Arc and select Add → Add a single server (or Add multiple servers for an at-scale rollout via a generated script).

  2. Choose the subscription, resource group (rg-bookshelf) and region for the resulting Azure resource, then Generate script — the portal emits a ready-to-run PowerShell or Bash script that installs the Connected Machine agent and calls azcmagent connect with the right identifiers already filled in.

  3. Run the generated script directly on the server (or distribute it via existing configuration management); the server’s Arc resource appears under Servers - Azure Arc once onboarding completes.

With the Azure CLI

# Sign in once on the target machine, then let azcmagent reuse that session
az login

azcmagent connect \
  --subscription-id "<subscription-id>" \
  --resource-group $RG \
  --location $LOCATION \
  --resource-name catalog-api-onprem-01 \
  --use-azcli

# Verify and inspect the resulting Arc-enabled server resource with az itself
az connectedmachine list --resource-group $RG --output table
az connectedmachine show --name catalog-api-onprem-01 --resource-group $RG

Azure Arc-enabled Kubernetes

Arc-enabled Kubernetes attaches an existing Kubernetes cluster — on-premises, in another cloud, or even another Azure subscription’s AKS cluster — as a Resource Manager resource, so it can be targeted by Azure Policy, GitOps (Flux) deployments and Azure Monitor exactly like a native AKS cluster, without Azure hosting or billing the cluster’s own control plane the way it does for AKS. It also underlies Bookshelf’s route to a genuinely hybrid Kubernetes Fleet Manager membership (see Fleet Manager, briefly), which can join Arc-enabled clusters alongside AKS clusters in the same fleet.

In the Azure portal

  1. From the portal’s search bar, type Kubernetes - Azure Arc and select Create → Generate script, or connect an existing cluster from Connect an existing Kubernetes cluster to Azure Arc.

  2. Select the subscription, resource group (rg-bookshelf), cluster name and region, then either download the generated CLI script (matching the CLI flow below) or, for a cluster already registered elsewhere, review its status directly on the resulting Arc resource’s Overview blade.

  3. Once connected, use Extensions on the cluster resource to install cluster extensions (for example, Azure Monitor’s container insights, or Azure Container Apps on Arc), and GitOps configurations to wire up Flux-based deployments.

With the Azure CLI

az extension add --name connectedk8s

az provider register --namespace Microsoft.Kubernetes
az provider register --namespace Microsoft.KubernetesConfiguration
az provider register --namespace Microsoft.ExtendedLocation

# Connect whatever cluster is the current kubectl context's default
az connectedk8s connect --name arck8s-bookshelf --resource-group $RG --location $LOCATION

# Verify the connection and list the agents Arc deployed into the cluster
az connectedk8s list --resource-group $RG --output table
kubectl get deployments,pods -n azure-arc

Azure Arc-enabled data services and SQL Server, briefly

Azure Arc-enabled data services runs SQL Managed Instance (and PostgreSQL, where offered) on any Arc-enabled Kubernetes cluster, giving it Azure-style updates, monitoring and elastic scale without a continuous connection to Azure — a different deployment model from the fully managed Azure SQL Managed Instance, for a workload that specifically must not leave a particular datacenter or edge site. Separately, Arc-enabled SQL Server extends Azure services (Microsoft Defender for Cloud, Azure Monitor, best-practices assessment) to an existing SQL Server instance running anywhere, without moving the database at all — the retain-and-manage-from-Azure pattern the migration-strategy table above points to for workloads that stay put.

Azure Local

Azure Local is the current name for what was Azure Stack HCI: Microsoft renamed the product, effective 19 November 2024 (announced at Microsoft Ignite 2024), with the name updated across the product and pricing pages immediately and across the Azure portal’s own UI strings by early 2025. It is a rename and a repositioning under Microsoft’s broader adaptive cloud umbrella, not a new product or a breaking change: existing Azure Stack HCI clusters, their validated-hardware model and their Hyper-V-based virtualization continue to work, now managed and billed as Azure Local.

Azure Local delivers Azure’s management plane — the portal, Azure CLI, ARM templates, and services such as Azure Policy, Microsoft Defender for Cloud, Azure Monitor and Copilot for Azure — onto customer-owned, on-premises hardware, with Azure Arc as the unifying control plane described above. It targets workloads that must stay on-premises for latency, business-continuity or data-sovereignty reasons — local AI inferencing at a retail store, a factory floor’s production-line control systems, a regulated industry’s data-sovereignty requirement — while still being managed, governed and billed through the same Azure subscription as everything else in this guide. It is billed per physical core on the on-premises hardware plus any consumption-based Azure services used on top, rolled into the existing Azure subscription rather than a separate contract. Azure Site Recovery’s preview integration (above) already extends to Hyper-V VMs running on Azure Local clusters, and the migrate CLI extension’s az migrate local command group (preview) targets migrating servers into an Azure Local cluster the same way its other commands target public Azure.

Azure VMware Solution

Azure VMware Solution (AVS) runs a genuine VMware software-defined datacenter (vSphere, vSAN, NSX) on dedicated Azure bare-metal infrastructure, for an organization migrating an existing VMware estate into Azure without re-platforming every VM first — a rehost in the migration-strategy table’s terms, at the infrastructure layer rather than the individual-VM layer, with Azure Migrate assessments able to size the target AVS node count directly. It has its own CAF scenario for adoption planning, separate from the general Azure adoption guidance above.

Licensing is mid-transition following Broadcom’s VMware Cloud Foundation (VCF) licensing changes: Microsoft stopped selling license-included AVS from 1 November 2025. Existing license-included customers on pay-as-you-go node pricing must move to a portable Broadcom VCF license (bring-your-own-license) by 31 October 2026; existing license-included Reserved Instance customers have until 30 August 2027. AVS itself is not being retired — only the bundled-license commercial model is — but any AVS deployment still on a license-included SKU should plan its BYOL transition against whichever of those two dates applies before relying on it past 2026.

Clean up

This page’s only durable, billable resources created for its own examples are the Arc-enabled server and Arc-enabled Kubernetes registrations above (Azure Migrate, Site Recovery and Well-Architected Review usage itself is free; AVS and Azure Local are not stood up by this page’s commands and are cleaned up, if ever provisioned, through their own lifecycle):

# Remove the Arc-enabled Kubernetes registration (agents and configuration resources)
az connectedk8s delete --name arck8s-bookshelf --resource-group $RG

# Remove the Arc-enabled server resource (does not uninstall the Connected Machine agent itself)
az connectedmachine delete --name catalog-api-onprem-01 --resource-group $RG

# Full teardown of everything created for this scenario
az group delete --name "$RG" --yes --no-wait