Preview context and scope

This article combines a feature comparison dated June 10, 2026 with a subsequent proof-of-concept report for Managed Instance on Azure App Service. It concerns Windows application hosting, not Azure SQL Managed Instance. Preview availability, APIs, limits, and portal screens can change: confirm the current product overview before deployment.

The feature overview initially left private-endpoint scope and maximum scale unresolved. The later PoC observed app-scoped private endpoints and a maximum of 30 workers for its P1v4 plan. These results clarify that experiment; they do not establish an immutable limit for every region, SKU, or future release.
QuestionPoC result
Private endpoints: app or plan?Per app (Microsoft.Web/sites), using group ID sites.
Azure Files mapped to F:?The UI allowed a custom drive letter, but the tested mount flow required a Key Vault secret containing key-based storage credentials. A mount was not completed in the key-disabled environment.
RDP?JIT access through Azure Bastion; the portal connection supplied temporary credentials.
Horizontal scale?The tested P1v4 plan reported maximumNumberOfWorkers: 30.
Installation-script OS/IIS changes?Not completed. Worker access and IIS Manager were confirmed; script execution and persistence still needed validation.

Where Managed Instance fits

AreaMultitenant App ServiceManaged InstanceASE v3
BoundaryDedicated workers with shared supporting infrastructureApp Service Plan-scoped boundaryA dedicated environment containing multiple plans
Windows customizationRestricted platform environmentSupported PowerShell installation scripts within platform limitsNot a general-purpose Windows VM; application/container strategies may be needed
Interactive worker diagnosticsNo comparable RDP workflowJIT RDP through BastionNo comparable RDP workflow
Typical fitCloud-native applications without OS-level dependenciesLegacy Windows web applications needing customizationDedicated environment and larger-scale isolation requirements

A Managed Instance is the plan itself; it is not an environment that contains several plans. Multiple applications can share it, but another independently scoped plan requires another Managed Instance. The source comparison cited ASE v3 limits of 100 workers per plan and 200 per environment; consult current limits rather than sizing from this historical comparison alone.

Do not equate Managed Instance with ASE. In particular, the PoC's plan-level outbound VNet integration did not turn inbound private endpoints into a shared plan endpoint.

Capabilities and operational responsibilities

Custom components and persistent configuration

The source overview identifies installation-script use cases including COM components, registry settings, IIS configuration and ACLs, MSI installers, GAC assemblies, custom runtimes, supported Windows features, and third-party components. This is a compatibility option for supported legacy Windows workloads, not permission for arbitrary OS changes.

Package PowerShell installation scripts as a ZIP in Azure Storage and configure managed-identity access. Startup execution reapplies the configuration on replacement or scale-out instances. Make scripts repeatable and test their startup and failure behavior. Manual RDP changes are temporary and are not a deployment mechanism.

Installation logs were described at C:\InstallScripts\<SCRIPT_NAME>\Install.log, with console/platform log integration. Registry adapters can separate sensitive registry values into Key Vault-backed configuration. Never embed secrets in installation scripts or source control.

Networking, identity, and storage

Plan-level VNet integration can be added after creation, subject to the supported configuration. The source discusses NSGs, NAT Gateway, routing, and private DNS. The PoC established that incoming private endpoints still target individual applications. Treat inbound access, outbound routing, name resolution, and Bastion access as distinct concerns.

The feature comparison describes plan-level managed identities and Key Vault integration. That does not imply every storage mount operation supports identity-based authentication. The later PoC specifically could not complete the portal Azure Files mount in its key-disabled environment.

UNC/network-share access, drive mapping, and temporary local storage were identified as compatibility features. Temporary storage is not durable application storage. The source cited a 2 GB temporary-storage figure; validate current SKU-specific behavior.

Who patches what?

ResponsibilityOwner
Platform Windows patches, host maintenance, load balancing, and platform-provided runtime servicingPlatform, within its supported lifecycle
Custom frameworks, runtimes, and components installed by the customerCustomer
Application code, dependencies, installation scripts, scale rules, and SKU selectionCustomer
Executing configured scaling operationsPlatform

The preview overview reviewed in the source did not establish ASE-style maintenance-window or upgrade-preference controls for Managed Instance. Do not assume those controls exist simply because the service has an isolation boundary.

Standard application operations

The source describes TLS, custom-domain bindings, App Service Authentication with Microsoft Entra ID, and familiar deployment approaches such as GitHub Actions, Azure DevOps, ZIP/package deployment, and run-from-package. These are not unique differentiators of Managed Instance. The differentiators discussed are supported Windows customization and Bastion-based diagnostics.

The source listed .NET Framework 3.5/4.8 and .NET 8 as preinstalled runtimes at the time. Confirm runtime support and lifecycle before choosing a target. Plan-level installation, registry-adapter, and mount events should be included in the logging design; validate Log Stream and Azure Monitor integration early.

PoC prerequisites and variables

The source preview scope was Windows web apps on Pv4/Pmv4 SKUs, outside ASE. It listed East Asia, West Central US, North Europe, East US, Australia East, Central India, and South India as supported regions at that time. Domain join, NTLM/Kerberos, Linux/container workloads, WebJobs, and TCP/NetPipes were reported as unsupported in the reviewed scope. Recheck current documentation rather than treating the list as evergreen.

The PoC used two apps, a user-assigned identity, a storage account/share, separate private-endpoint and app-integration subnets, and a Standard Bastion deployment. The commands below are source-derived examples, not a complete automatic deployment. Review cost and permissions first. Choose a dedicated PoC resource group and unused, non-overlapping address ranges.

: "${SUBSCRIPTION_ID:?Set SUBSCRIPTION_ID}"
: "${RESOURCE_GROUP:?Set RESOURCE_GROUP}"
: "${LOCATION:?Set a currently supported region}"
: "${PLAN_NAME:?Set PLAN_NAME}"
: "${IDENTITY_NAME:?Set IDENTITY_NAME}"
: "${APP_ONE:?Set a globally unique APP_ONE}"
: "${APP_TWO:?Set a globally unique APP_TWO}"
: "${VNET_NAME:?Set VNET_NAME}"
: "${VNET_CIDR:?Set VNET_CIDR}"
: "${PE_SUBNET_NAME:?Set PE_SUBNET_NAME}"
: "${PE_SUBNET_CIDR:?Set PE_SUBNET_CIDR}"
: "${APP_SUBNET_NAME:?Set APP_SUBNET_NAME}"
: "${APP_SUBNET_CIDR:?Set APP_SUBNET_CIDR}"
: "${BASTION_SUBNET_CIDR:?Set a non-overlapping /26 or larger subnet}"

az account set --subscription "$SUBSCRIPTION_ID"
az group create -n "$RESOURCE_GROUP" -l "$LOCATION"
az identity create -g "$RESOURCE_GROUP" -n "$IDENTITY_NAME" -l "$LOCATION"
IDENTITY_ID=$(az identity show -g "$RESOURCE_GROUP" -n "$IDENTITY_NAME" --query id -o tsv)

Create and identify the plan

The source first created a Windows Premium v4 plan, then configured preview-specific properties through REST. Preview CLI availability and schema can change; verify the supported creation flow before using this sequence. The important discriminator observed was the plan property isCustomMode: true, not hyperV or isXenon.

# Windows is the default; do not add --is-linux for this Windows plan.
az appservice plan create -g "$RESOURCE_GROUP" -n "$PLAN_NAME" \
  -l "$LOCATION" --sku P1V4
PLAN_ID=$(az appservice plan show -g "$RESOURCE_GROUP" -n "$PLAN_NAME" --query id -o tsv)

az rest --method patch \
  --url "https://management.azure.com${PLAN_ID}?api-version=2024-11-01" \
  --body "{\"properties\":{\"isCustomMode\":true,\"planDefaultIdentity\":{\"identityType\":\"UserAssigned\",\"userAssignedIdentityResourceId\":\"$IDENTITY_ID\"}}}"

az resource show -g "$RESOURCE_GROUP" \
  --resource-type "Microsoft.Web/serverfarms" -n "$PLAN_NAME" \
  --query "{isCustomMode:properties.isCustomMode,tier:sku.tier,size:sku.size,maxWorkers:properties.maximumNumberOfWorkers}" -o json

az webapp create -g "$RESOURCE_GROUP" -p "$PLAN_NAME" -n "$APP_ONE"
az webapp create -g "$RESOURCE_GROUP" -p "$PLAN_NAME" -n "$APP_TWO"
az appservice plan show -g "$RESOURCE_GROUP" -n "$PLAN_NAME" \
  --query "{numberOfSites:numberOfSites,isCustomMode:isCustomMode}" -o json

The source's expected result was isCustomMode: true, tier PremiumV4, size P1v4, and 30 maximum workers. Verify the actual response rather than assuming that a successful plan-create command enabled the feature.

Separate private-endpoint and integration subnets

az network vnet create -g "$RESOURCE_GROUP" -n "$VNET_NAME" -l "$LOCATION" \
  --address-prefixes "$VNET_CIDR" \
  --subnet-name "$PE_SUBNET_NAME" --subnet-prefixes "$PE_SUBNET_CIDR"

az network vnet subnet create -g "$RESOURCE_GROUP" --vnet-name "$VNET_NAME" \
  -n "$APP_SUBNET_NAME" --address-prefixes "$APP_SUBNET_CIDR" \
  --delegations Microsoft.Web/serverFarms

az network vnet subnet create -g "$RESOURCE_GROUP" --vnet-name "$VNET_NAME" \
  -n AzureBastionSubnet --address-prefixes "$BASTION_SUBNET_CIDR"

az network vnet subnet update -g "$RESOURCE_GROUP" --vnet-name "$VNET_NAME" \
  -n "$PE_SUBNET_NAME" --private-endpoint-network-policies Disabled

AzureBastionSubnet is a required service subnet name, not an environment identifier. The source disabled private-endpoint subnet network policies for its setup. Apply your current supported private-endpoint/NSG design rather than assuming all environments require the same policy setting.

Validate app-scoped private endpoints

APP_ONE_ID=$(az webapp show -g "$RESOURCE_GROUP" -n "$APP_ONE" --query id -o tsv)
APP_TWO_ID=$(az webapp show -g "$RESOURCE_GROUP" -n "$APP_TWO" --query id -o tsv)
az network private-link-resource list --id "$APP_ONE_ID" \
  --query "[].{name:name,groupId:properties.groupId}" -o json

: "${PE_ONE:?Set PE_ONE}"
: "${PE_TWO:?Set PE_TWO}"
az network private-endpoint create -g "$RESOURCE_GROUP" -n "$PE_ONE" -l "$LOCATION" \
  --vnet-name "$VNET_NAME" --subnet "$PE_SUBNET_NAME" \
  --private-connection-resource-id "$APP_ONE_ID" \
  --group-id sites --connection-name "${PE_ONE}-connection"
az network private-endpoint create -g "$RESOURCE_GROUP" -n "$PE_TWO" -l "$LOCATION" \
  --vnet-name "$VNET_NAME" --subnet "$PE_SUBNET_NAME" \
  --private-connection-resource-id "$APP_TWO_ID" \
  --group-id sites --connection-name "${PE_TWO}-connection"

az network private-endpoint list -g "$RESOURCE_GROUP" \
  --query "[].{name:name,groupId:privateLinkServiceConnections[0].groupIds[0],target:privateLinkServiceConnections[0].privateLinkServiceId}" -o json

Each target in the PoC was an individual Microsoft.Web/sites resource, not a server farm. Two apps had two endpoints with distinct private IPs. The report observed different public-network-access states between its apps; explicitly inspect and configure public access rather than relying on an assumed automatic toggle. Complete private DNS and connectivity validation separately; endpoint creation alone is not an end-to-end private-access test.

Plan-level integration and Bastion RDP

In the observed preview, app-level VNet integration failed with a message directing the user to update the server farm's VirtualNetworkSubnetId. Configure the Managed Instance plan, not each site, for the outbound integration used here.

az appservice plan update -g "$RESOURCE_GROUP" -n "$PLAN_NAME" \
  --vnet "$VNET_NAME" --subnet "$APP_SUBNET_NAME"
az rest --method get \
  --url "https://management.azure.com${PLAN_ID}?api-version=2024-11-01" \
  --query "properties.{used:vnetConnectionsUsed,max:vnetConnectionsMax}" -o json

: "${NSG_NAME:?Set NSG_NAME}"
az network nsg create -g "$RESOURCE_GROUP" -n "$NSG_NAME" -l "$LOCATION"
az network nsg rule create -g "$RESOURCE_GROUP" --nsg-name "$NSG_NAME" \
  -n Allow-Bastion-RDP --priority 200 --direction Inbound --access Allow --protocol Tcp \
  --source-address-prefixes "$BASTION_SUBNET_CIDR" \
  --destination-address-prefixes "$APP_SUBNET_CIDR" --destination-port-ranges 3389
az network vnet subnet update -g "$RESOURCE_GROUP" --vnet-name "$VNET_NAME" \
  -n "$APP_SUBNET_NAME" --network-security-group "$NSG_NAME"

: "${BASTION_PUBLIC_IP_NAME:?Set BASTION_PUBLIC_IP_NAME}"
: "${BASTION_NAME:?Set BASTION_NAME}"
az network public-ip create -g "$RESOURCE_GROUP" -n "$BASTION_PUBLIC_IP_NAME" \
  -l "$LOCATION" --sku Standard --allocation-method Static
az network bastion create -g "$RESOURCE_GROUP" -n "$BASTION_NAME" -l "$LOCATION" \
  --vnet-name "$VNET_NAME" --public-ip-address "$BASTION_PUBLIC_IP_NAME" \
  --sku Standard --enable-tunneling true --enable-ip-connect true

The NSG example covers the source's Bastion-to-worker RDP rule, not a complete Bastion networking policy. Review all required Bastion networking rules and existing NSGs. Bastion and the public IP incur charges even when you are not actively connected.

  1. Open the App Service Plan's Settings → Configuration → Bastion/RDP area in the supported portal.
  2. Enable the option to allow Remote Desktop through Bastion and save.
  3. Open Instances, select the intended worker, and choose Connect via Bastion.
  4. Use IIS Manager, Event Viewer, and logs for diagnostics; represent lasting changes in installation scripts.

The source reported a portal-only enablement toggle at the time and no documented CLI/API setter. It read properties.network.rdpEnabled to confirm state. Its one-click connection supplied temporary credentials automatically. Do not print or copy those credentials into logs, commands committed to Git, or documentation. Workers were not exposed as ordinary customer-owned VM/NIC resources.

Two application sites were visible on the same worker in IIS Manager. This confirms access and placement for that PoC, not successful installation-script execution.

Azure Files mount: separate UI support from authentication support

: "${STORAGE_ACCOUNT:?Set an existing STORAGE_ACCOUNT}"
: "${FILE_SHARE:?Set FILE_SHARE}"
az storage share-rm create -g "$RESOURCE_GROUP" --storage-account "$STORAGE_ACCOUNT" \
  --name "$FILE_SHARE" --quota 5
az storage account show -g "$RESOURCE_GROUP" -n "$STORAGE_ACCOUNT" \
  --query "{allowSharedKeyAccess:allowSharedKeyAccess,allowBlobPublicAccess:allowBlobPublicAccess}" -o json

In Plan → Settings → Configuration → Mounts → New mount, the tested form offered Azure Files, a storage account/share, a custom drive letter such as F:, and required Key Vault and Secret fields. The expected secret held a storage connection string or account key.

The source's storage account had allowSharedKeyAccess: false, and its PoC did not complete the mount through that flow. It reported no managed-identity mount option in the preview UI. Treat this as an observed compatibility blocker, not a blanket assertion about every Azure Files authentication mode. Validate the current Managed Instance mount feature against your organization's allowed authentication methods; do not re-enable key access merely to make a test succeed.

The source mentioned a possible script-based alternative but did not validate it. No OAuth/SAS drive-mapping workaround is presented here as supported or working.

Scale and installation-script validation

az appservice plan show -g "$RESOURCE_GROUP" -n "$PLAN_NAME" \
  --query "{maxWorkers:maximumNumberOfWorkers}" -o json

The source's portal and API both indicated 30 maximum instances for P1v4. The feature comparison's earlier statement that an MI-specific limit was not clearly documented is therefore retained as historical uncertainty, not as a contradiction to the later environment-specific measurement.

The installScripts[] reference structure was inspected, but the referenced scripts container was empty. No runnable scripts.zip or installation-script content accompanies these documents. The source's remaining validation plan was:

  1. Prepare a supported, repeatable script covering an IIS module, ACL, registry setting, and one allowed Windows feature.
  2. Upload the package and verify managed-identity access to the blob.
  3. Validate startup logs and the resulting configuration through the supported diagnostic path.
  4. Restart or replace a test instance and verify reapplication.
  5. Scale out and confirm the same configuration is applied to the new instance.

Production-readiness and cleanup

  • Keep durable configuration in reviewed scripts and secrets in Key Vault.
  • Validate logging, installation failure handling, and component patch ownership before production deployment.
  • Align NSGs, routing, and name resolution with the actual dependency inventory.
  • Use staging to test restart, maintenance, scale-out, and storage-authentication behavior.
  • Consider Microsoft Defender for Cloud and appropriate monitoring for the workload.
  • Review Bastion, public IP, storage, and plan costs, and remove dedicated PoC resources when no longer needed. Confirm the contents of a resource group before deleting it.

The original cleanup section stops mid-sentence after noting hourly Bastion charges. It does not contain a complete cleanup procedure. This article does not invent an original deletion script or claim that any resources have been removed.

Choose Managed Instance when supported legacy Windows dependencies and worker-level diagnostics are important. Prefer ordinary App Service when no OS customization is needed and its workload support fits; evaluate ASE separately when the environment-wide isolation and scale model are requirements.

Reference: ASE v3 and public multitenant App Service comparison.

Resources

No standalone companion files are distributed for this topic. Use the in-page examples and review the editorial notes below for source availability.

Editorial notes

This page consolidates the following source documents into an English technical guide:

  • App Service Managed Instance: advantages by managed feature
  • Managed Instance on App Service (Preview): PoC setup and validation
  • Actual resource names, subscription context, network addresses, and public IPs have been replaced by variables.
  • The repository contains no companion scripts.zip, install scripts, deployment templates, or complete cleanup script for this topic.
  • The original cleanup section ends mid-sentence; no missing commands have been represented as source-provided.

No original credentials or private repository links are included. Do not put populated configuration files or copied production outputs back into this public site.