Thursday, March 12, 2026

Configuring Azure Monitor Private Link Scope (AMPLS) for Secure Log Ingestion

In regulated industries and enterprise environments, network security requirements often mandate that monitoring data must not traverse the public internet. Azure Monitor Private Link Scope (AMPLS) addresses this by enabling Log Analytics workspaces and Application Insights resources to receive data exclusively over a private network connection.

This post covers the AMPLS architecture and provides a step-by-step configuration guide.

1. What Is AMPLS and Why Use It

Without AMPLS, Azure Monitor agents on virtual machines send telemetry to Azure Monitor's public endpoints over the internet, even if the VMs themselves are on a private network. AMPLS routes this traffic through a Private Endpoint within the virtual network, ensuring that log ingestion never leaves the private network boundary.

Key scenarios where AMPLS is required:

  • Compliance requirements that prohibit data traversal over public networks (e.g., Australian ISM, PCI-DSS)
  • Environments where outbound internet access from VMs is blocked by policy
  • Hub-and-spoke network architectures where monitoring traffic must flow through a centralised network hub

AMPLS uses two access mode settings that control its behaviour:

  • Private Only: the workspace accepts data only from private endpoint connections
  • Open: the workspace accepts data from both private endpoints and public endpoints

Start with Open mode during migration to avoid disrupting existing monitoring while private connectivity is being established

  1. Navigate to Azure Monitor > Private Link Scopes
  2. Select + Create
  3. Provide a Name and select the Resource group and Region
  4. Under Azure Monitor Private Link Scope settings, set Data Ingestion access mode to Open for initial configuration
  5. Select Review + create

Once created, the Private Link Scope is an empty container. Resources must be connected to it before it provides any routing.

3. Connecting Log Analytics Workspaces

  1. Open the newly created AMPLS resource
  2. Navigate to Azure Monitor Resources > + Add
  3. Select the Log Analytics workspace to connect
  4. Select Apply

Repeat this process for any Application Insights resources that should also route through the private endpoint. A single AMPLS instance can connect up to 50 Log Analytics workspaces and 50 Application Insights resources.

Following is a summary of what AMPLS covers once resources are connected:

Traffic TypeRouted via AMPLS
Log Analytics agent (AMA/MMA) data ingestionYes
Application Insights SDK telemetryYes
Log Analytics query APIYes
Azure Diagnostics (VM diagnostic extension)No (separate configuration required)

4. Creating the Private Endpoint

The Private Endpoint is the network interface within the virtual network that routes traffic to AMPLS.

  1. From the AMPLS resource, navigate to Private endpoint connections > + Private endpoint
  2. Provide a name and select the SubscriptionResource group, and Region
  3. Under Resource, confirm the target is the AMPLS resource with sub-resource azuremonitor
  4. Under Virtual Network, select the VNet and subnet where the private endpoint should be placed
  5. Under DNS, select Yes for private DNS zone integration. This is required for name resolution to work correctly

Azure automatically creates the required private DNS zones (privatelink.monitor.azure.comprivatelink.ods.opinsights.azure.com, and others) when DNS integration is selected.

5. Validating Connectivity

After the private endpoint is provisioned, validate that an Azure Monitor Agent on a VM in the connected VNet can reach the workspace through the private endpoint:

Heartbeat
| where TimeGenerated > ago(1h)
| summarize count() by Computer, SourceSystem

Agents routing through AMPLS report SourceSystem = "OpsManager". Confirm that expected VMs are appearing and that heartbeats are consistent.

Summary

AMPLS provides a clear network path for Azure Monitor telemetry in environments where public endpoint access is not acceptable. The configuration is straightforward: create the scope, connect workspaces, deploy a private endpoint with DNS integration, and validate with a heartbeat query. Starting in Open access mode allows existing agents to continue working while private connectivity is established and tested.

Tuesday, February 17, 2026

Scaling Azure Container Apps with KEDA

Azure Container Apps uses KEDA (Kubernetes-based Event Driven Autoscaling) as its scaling engine. Unlike traditional CPU and memory-based autoscaling, KEDA can scale workloads in response to external event sources — queue depth, HTTP request rate, or custom metrics from virtually any system. This makes it particularly well-suited for event-driven and background processing architectures where resource demand is directly tied to the number of outstanding work items.

This post covers how Container Apps scaling works, and how to configure HTTP, Azure Queue Storage, and Azure Service Bus scaling rules for common workload patterns.

1. How Scaling Works in Container Apps

Container Apps scaling operates on two dimensions:

  • Replica count: the number of running container instances, from zero to a configured maximum
  • Scale trigger: the condition under which replicas are added or removed

Scaling to zero replicas is available on the Consumption workload profile when minReplicas is set to 0. When idle, the app consumes no compute and incurs no charge. The first incoming request after a scale-to-zero event will experience a cold start — typically 2–10 seconds depending on image size and initialisation logic.

Each scaling rule defines a target metric and a threshold per replica. Container Apps evaluates the active rules every 30 seconds and adjusts the replica count to maintain the target. If multiple scale rules are active, the rule requesting the most replicas takes precedence.

Scale rules are defined per container app, either in the Azure portal, a Bicep template, or the Azure CLI.

2. HTTP Scaling for Web-Facing Apps

HTTP scaling is the default choice for apps serving synchronous web requests. Container Apps counts concurrent HTTP requests and adds replicas when the count per replica exceeds a configured threshold.

Following is a Bicep definition for an HTTP scaling rule targeting 50 concurrent requests per replica, with a maximum of 10 replicas:

scale: {
  minReplicas: 1
  maxReplicas: 10
  rules: [
    {
      name: 'http-scaling'
      http: {
        metadata: {
          concurrentRequests: '50'
        }
      }
    }
  ]
}

concurrentRequests: '50' means a new replica is added approximately every 50 concurrent requests. Tune this value based on your app's throughput characteristics — a lower value scales more aggressively, a higher value tolerates more load per instance.

For HTTP workloads, set minReplicas to at least 1. A web-facing app that scales to zero will expose users to a cold start on the first request after idle, which is rarely acceptable for interactive workloads.

3. Azure Queue Storage Scaling for Background Workers

Workers that consume messages from Azure Queue Storage should scale in proportion to the number of waiting messages. The Azure Queue KEDA scaler reads the queue depth and scales replicas to maintain a target messages-per-replica ratio.

Following is a Bicep definition for a queue-based scaling rule targeting 5 messages per replica:

scale: {
  minReplicas: 0
  maxReplicas: 20
  rules: [
    {
      name: 'queue-scaling'
      custom: {
        type: 'azure-queue'
        metadata: {
          queueName: 'work-items'
          queueLength: '5'
          accountName: '<storage-account-name>'
        }
        auth: [
          {
            secretRef: 'storage-connection-string'
            triggerParameter: 'connection'
          }
        ]
      }
    }
  ]
}

With queueLength: '5', Container Apps scales to 10 replicas when 50 messages are queued. When the queue is empty, it scales to 0 replicas after the cool-down period (300 seconds by default).

Store the storage account connection string in a Container Apps secret and reference it via secretRef, rather than embedding it in the scaling rule metadata.

4. Azure Service Bus Scaling for Event-Driven Workloads

The Azure Service Bus KEDA scaler works similarly to the queue storage scaler but targets the active message count in a Service Bus queue or topic subscription. It is the preferred approach for Service Bus consumers because it scales based on the number of messages actually available for processing.

Following is a Bicep definition for a Service Bus scaling rule:

scale: {
  minReplicas: 0
  maxReplicas: 15
  rules: [
    {
      name: 'servicebus-scaling'
      custom: {
        type: 'azure-servicebus'
        metadata: {
          queueName: 'orders'
          messageCount: '10'
          namespace: '<servicebus-namespace>'
        }
        auth: [
          {
            secretRef: 'servicebus-connection-string'
            triggerParameter: 'connection'
          }
        ]
      }
    }
  ]
}

I recommend keeping the Service Bus connection string in Azure Key Vault and referencing it via a Container Apps secret backed by a Key Vault reference, rather than storing the value directly in the app configuration.

5. Setting Minimum Replicas and Scale-to-Zero Behaviour

The minReplicas value is the most consequential scaling decision for each workload. Setting it to 0 eliminates idle compute cost but introduces cold start latency on the first request after the app scales down. Setting it to 1 or higher ensures the app is always ready, at the cost of continuous baseline compute.

Following is a practical guide for choosing minReplicas by workload type:

Workload typeRecommended minReplicasReasoning
Queue or Service Bus consumer0Latency on first message is acceptable
Internal HTTP API1Eliminates cold start for internal callers
Customer-facing HTTP API2Eliminates cold start and provides basic redundancy
Scheduled or batch job0Triggered on a schedule; cold start is acceptable

To configure minimum and maximum replicas in the portal:

  1. Navigate to Container Apps > [app] > Scale and replicas
  2. Set Min replicas and Max replicas
  3. Select + Add under Scale rules to configure a new rule
  4. Select Save

Monitor the Replica Count metric under Container Apps > [app] > Metrics to observe scale-out and scale-in events over time, and adjust the maxReplicas ceiling if the app consistently reaches it under normal operating conditions.

Summary

KEDA gives Container Apps a flexible, event-driven scaling model that goes well beyond CPU and memory thresholds. HTTP scaling ensures web workloads respond proportionally to request volume; Queue Storage and Service Bus scaling ensure background workers process backlogs efficiently without idle compute waste. Matching minReplicas to the latency tolerance of each workload type — zero for batch processors, one or more for synchronous APIs — is the configuration decision that most directly determines both cost and responsiveness.