Tools: Azure Container Apps: Workload Profiles v2 Is Now the Default — What You Need to Know

Tools: Azure Container Apps: Workload Profiles v2 Is Now the Default — What You Need to Know

Source: Dev.to

What Changed? ## Why This Matters: The Key Benefits ## 1. Same Price, More Flexibility ## 2. Dramatically Smaller Subnet Requirements ## 3. Enhanced Networking Features ## 4. GPU Support for AI/ML Workloads ## 5. Mix Consumption and Dedicated in One Environment ## Understanding the Three Profile Types ## Consumption Profile (Serverless) ## Dedicated Profiles (Reserved Compute) ## Flexible Profile (Preview) ## Practical Migration Considerations ## Existing V1 Environments Keep Working ## When to Migrate ## Migration Is Environment-Level ## Real-World Architecture: Mixing Profiles ## Quick Reference: v1 vs v2 ## The Bottom Line Azure Container Apps just made a significant change that affects every developer creating new environments. As of January 2026, Workload Profiles (v2) is now the default environment type, replacing the legacy Consumption-only (v1) model. This isn't just a version bump — it's a fundamental shift in how Container Apps environments work, and it brings substantial benefits for production workloads. In this post, I'll break down what changed, why it matters, and how to take advantage of the new capabilities. When you create a new Azure Container Apps environment, you now get a Workload Profiles (v2) environment by default. The previous Consumption-only (v1) environment is now considered legacy. Here's the key distinction: The --enable-workload-profiles flag? You don't need it anymore. Creating an environment is now as simple as: This automatically provisions a v2 environment with a default Consumption profile included. The Consumption profile in v2 environments has identical pricing to v1's Consumption-only model. You're not paying more for the upgraded architecture. But you gain the ability to add Dedicated or GPU profiles later without recreating your environment. This is huge for enterprise deployments. V1 environments required a /23 CIDR range for your VNet — that's 512 IP addresses. V2 environments need only a /27 — just 32 addresses. If you've ever struggled with IP address exhaustion in enterprise networks, you know how valuable this is. V2 environments unlock networking capabilities that v1 simply couldn't support: Need to run inference workloads? V2 environments support GPU workload profiles with NVIDIA T4 and A100 accelerators. You can run these alongside your regular containerized apps in the same environment. Here's where v2 really shines. You can run some apps on pay-per-use Consumption profiles while others run on reserved Dedicated profiles — all in the same environment, sharing the same internal networking. Use case: Your API gateway scales to zero when idle (Consumption), while your database proxy maintains steady-state replicas (Dedicated D4 profile). V2 introduces a richer compute model. Let's break down each profile type: The default profile included in every environment. Apps automatically scale in and out based on demand, including scale-to-zero when idle. Billing: Pay only for the compute seconds your replicas actually use. Pre-provisioned VMs in your own pool. You select the size, deploy multiple apps per profile, and pay per-node regardless of utilization. Best for: Steady-state workloads, latency-sensitive apps, workloads requiring more than 4 vCPU or 8 GiB RAM per replica. A new hybrid option that combines Consumption-style billing with Dedicated-style isolation: Currently available in select regions: Australia East, Brazil South, Canada Central, Central India, North Europe, Sweden Central, West US 3, and others. If you have Consumption-only (v1) environments in production, they're not going away. Microsoft isn't forcing migrations. Your existing apps continue to run without changes. However, for new projects, the recommendation is clear: use Workload Profiles (v2). Consider migrating existing v1 environments if you need: There's no in-place upgrade from v1 to v2. Migration means: For apps with stateless workloads and external traffic managed via Azure Front Door or Traffic Manager, this is straightforward. For apps with internal service-to-service dependencies, plan your migration carefully. Here's a practical example of how you might structure an AI-powered application using multiple profile types: Infrastructure as Code (Bicep): Workload Profiles v2 is now the default for good reason. It provides a more flexible, capable platform without sacrificing the simplicity of serverless deployments. The Consumption profile within v2 environments gives you the same pay-per-use, scale-to-zero experience you're used to — but with the option to grow into Dedicated or GPU profiles as your needs evolve. For new projects, there's no reason to opt for v1. For existing projects, evaluate whether the enhanced networking and compute options justify migration. The future of Azure Container Apps is workload profiles. Time to embrace it. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK: az containerapp env create \ --name my-environment \ --resource-group my-rg \ --location eastus Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: az containerapp env create \ --name my-environment \ --resource-group my-rg \ --location eastus CODE_BLOCK: az containerapp env create \ --name my-environment \ --resource-group my-rg \ --location eastus CODE_BLOCK: V1: 10.0.0.0/23 → 512 IPs reserved V2: 10.0.0.0/27 → 32 IPs reserved Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: V1: 10.0.0.0/23 → 512 IPs reserved V2: 10.0.0.0/27 → 32 IPs reserved CODE_BLOCK: V1: 10.0.0.0/23 → 512 IPs reserved V2: 10.0.0.0/27 → 32 IPs reserved COMMAND_BLOCK: # Apps default to Consumption profile az containerapp create \ --name my-api \ --resource-group my-rg \ --environment my-environment \ --image mcr.microsoft.com/azuredocs/containerapps-helloworld:latest \ --target-port 80 \ --ingress external Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: # Apps default to Consumption profile az containerapp create \ --name my-api \ --resource-group my-rg \ --environment my-environment \ --image mcr.microsoft.com/azuredocs/containerapps-helloworld:latest \ --target-port 80 \ --ingress external COMMAND_BLOCK: # Apps default to Consumption profile az containerapp create \ --name my-api \ --resource-group my-rg \ --environment my-environment \ --image mcr.microsoft.com/azuredocs/containerapps-helloworld:latest \ --target-port 80 \ --ingress external COMMAND_BLOCK: # Add a Dedicated profile to your environment az containerapp env workload-profile add \ --name my-environment \ --resource-group my-rg \ --workload-profile-name high-memory \ --workload-profile-type E4 \ --min-nodes 1 \ --max-nodes 5 # Deploy an app to the Dedicated profile az containerapp create \ --name my-ml-service \ --resource-group my-rg \ --environment my-environment \ --workload-profile-name high-memory \ --image myregistry.azurecr.io/ml-inference:latest \ --cpu 4 \ --memory 32Gi Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: # Add a Dedicated profile to your environment az containerapp env workload-profile add \ --name my-environment \ --resource-group my-rg \ --workload-profile-name high-memory \ --workload-profile-type E4 \ --min-nodes 1 \ --max-nodes 5 # Deploy an app to the Dedicated profile az containerapp create \ --name my-ml-service \ --resource-group my-rg \ --environment my-environment \ --workload-profile-name high-memory \ --image myregistry.azurecr.io/ml-inference:latest \ --cpu 4 \ --memory 32Gi COMMAND_BLOCK: # Add a Dedicated profile to your environment az containerapp env workload-profile add \ --name my-environment \ --resource-group my-rg \ --workload-profile-name high-memory \ --workload-profile-type E4 \ --min-nodes 1 \ --max-nodes 5 # Deploy an app to the Dedicated profile az containerapp create \ --name my-ml-service \ --resource-group my-rg \ --environment my-environment \ --workload-profile-name high-memory \ --image myregistry.azurecr.io/ml-inference:latest \ --cpu 4 \ --memory 32Gi CODE_BLOCK: ┌─────────────────────────────────────────────────────────────┐ │ Container Apps Environment (v2) │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ API Gateway │ │ Background Jobs │ │ │ │ (Consumption) │ │ (Consumption) │ │ │ │ Scale: 0-10 │ │ Scale: 0-5 │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ ML Inference │ │ Vector DB Proxy │ │ │ │ (GPU NC24-A100) │ │ (Dedicated E8) │ │ │ │ Scale: 1-3 │ │ Scale: 2-4 │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: ┌─────────────────────────────────────────────────────────────┐ │ Container Apps Environment (v2) │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ API Gateway │ │ Background Jobs │ │ │ │ (Consumption) │ │ (Consumption) │ │ │ │ Scale: 0-10 │ │ Scale: 0-5 │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ ML Inference │ │ Vector DB Proxy │ │ │ │ (GPU NC24-A100) │ │ (Dedicated E8) │ │ │ │ Scale: 1-3 │ │ Scale: 2-4 │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ CODE_BLOCK: ┌─────────────────────────────────────────────────────────────┐ │ Container Apps Environment (v2) │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ API Gateway │ │ Background Jobs │ │ │ │ (Consumption) │ │ (Consumption) │ │ │ │ Scale: 0-10 │ │ Scale: 0-5 │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ ML Inference │ │ Vector DB Proxy │ │ │ │ (GPU NC24-A100) │ │ (Dedicated E8) │ │ │ │ Scale: 1-3 │ │ Scale: 2-4 │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ CODE_BLOCK: resource containerAppEnv 'Microsoft.App/managedEnvironments@2024-03-01' = { name: 'ai-platform-env' location: location properties: { workloadProfiles: [ { name: 'Consumption' workloadProfileType: 'Consumption' } { name: 'gpu-inference' workloadProfileType: 'NC24-A100' minimumCount: 1 maximumCount: 3 } { name: 'high-memory' workloadProfileType: 'E8' minimumCount: 2 maximumCount: 4 } ] vnetConfiguration: { infrastructureSubnetId: subnet.id } } } resource apiGateway 'Microsoft.App/containerApps@2024-03-01' = { name: 'api-gateway' location: location properties: { environmentId: containerAppEnv.id workloadProfileName: 'Consumption' configuration: { ingress: { external: true targetPort: 8080 } } template: { containers: [ { name: 'api' image: 'myregistry.azurecr.io/api-gateway:latest' resources: { cpu: json('0.5') memory: '1Gi' } } ] scale: { minReplicas: 0 maxReplicas: 10 } } } } resource mlInference 'Microsoft.App/containerApps@2024-03-01' = { name: 'ml-inference' location: location properties: { environmentId: containerAppEnv.id workloadProfileName: 'gpu-inference' template: { containers: [ { name: 'inference' image: 'myregistry.azurecr.io/ml-model:latest' resources: { cpu: json('24') memory: '220Gi' } } ] scale: { minReplicas: 1 maxReplicas: 3 } } } } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: resource containerAppEnv 'Microsoft.App/managedEnvironments@2024-03-01' = { name: 'ai-platform-env' location: location properties: { workloadProfiles: [ { name: 'Consumption' workloadProfileType: 'Consumption' } { name: 'gpu-inference' workloadProfileType: 'NC24-A100' minimumCount: 1 maximumCount: 3 } { name: 'high-memory' workloadProfileType: 'E8' minimumCount: 2 maximumCount: 4 } ] vnetConfiguration: { infrastructureSubnetId: subnet.id } } } resource apiGateway 'Microsoft.App/containerApps@2024-03-01' = { name: 'api-gateway' location: location properties: { environmentId: containerAppEnv.id workloadProfileName: 'Consumption' configuration: { ingress: { external: true targetPort: 8080 } } template: { containers: [ { name: 'api' image: 'myregistry.azurecr.io/api-gateway:latest' resources: { cpu: json('0.5') memory: '1Gi' } } ] scale: { minReplicas: 0 maxReplicas: 10 } } } } resource mlInference 'Microsoft.App/containerApps@2024-03-01' = { name: 'ml-inference' location: location properties: { environmentId: containerAppEnv.id workloadProfileName: 'gpu-inference' template: { containers: [ { name: 'inference' image: 'myregistry.azurecr.io/ml-model:latest' resources: { cpu: json('24') memory: '220Gi' } } ] scale: { minReplicas: 1 maxReplicas: 3 } } } } CODE_BLOCK: resource containerAppEnv 'Microsoft.App/managedEnvironments@2024-03-01' = { name: 'ai-platform-env' location: location properties: { workloadProfiles: [ { name: 'Consumption' workloadProfileType: 'Consumption' } { name: 'gpu-inference' workloadProfileType: 'NC24-A100' minimumCount: 1 maximumCount: 3 } { name: 'high-memory' workloadProfileType: 'E8' minimumCount: 2 maximumCount: 4 } ] vnetConfiguration: { infrastructureSubnetId: subnet.id } } } resource apiGateway 'Microsoft.App/containerApps@2024-03-01' = { name: 'api-gateway' location: location properties: { environmentId: containerAppEnv.id workloadProfileName: 'Consumption' configuration: { ingress: { external: true targetPort: 8080 } } template: { containers: [ { name: 'api' image: 'myregistry.azurecr.io/api-gateway:latest' resources: { cpu: json('0.5') memory: '1Gi' } } ] scale: { minReplicas: 0 maxReplicas: 10 } } } } resource mlInference 'Microsoft.App/containerApps@2024-03-01' = { name: 'ml-inference' location: location properties: { environmentId: containerAppEnv.id workloadProfileName: 'gpu-inference' template: { containers: [ { name: 'inference' image: 'myregistry.azurecr.io/ml-model:latest' resources: { cpu: json('24') memory: '220Gi' } } ] scale: { minReplicas: 1 maxReplicas: 3 } } } } - Consumption-only (v1): A single serverless tier where all apps run on shared, pay-per-use infrastructure - Workload Profiles (v2): A flexible architecture supporting multiple profile types — Consumption, Dedicated, and the new Flexible profile — within the same environment - User-Defined Routes (UDR): Route traffic through network virtual appliances (NVAs) for inspection - Egress through NAT Gateway: Control outbound traffic with static public IPs - Private Endpoints: Expose services privately within your VNet without public internet exposure - Single-tenant compute pool (better isolation than shared Consumption) - Planned maintenance windows (you control when updates happen) - Per-replica billing (like Consumption, but with larger sizes available) - Cannot scale to zero (minimum 1 replica always running) - GPU profiles for AI/ML workloads - UDR support for traffic inspection - NAT Gateway egress control - Private endpoints - Mix of Consumption and Dedicated workloads - Smaller subnet footprint - Create a new v2 environment - Redeploy your container apps to the new environment - Update DNS/traffic routing - Decommission the old environment - Workload Profiles Overview - Compute and Billing Structures - Networking in Container Apps - GitHub: Azure Container Apps Announcements