Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
---
title: 'Tutorial: Enable Azure Container Apps on Azure Arc-enabled Kubernetes'
description: 'Tutorial: learn how to set up Azure Container Apps in your Azure Arc-enabled Kubernetes clusters.'
services: container-apps
author: craigshoemaker
ms.service: azure-container-apps
ms.custom:
- devx-track-azurecli
- build-2025
ms.topic: tutorial
ms.date: 06/25/2025
ms.author: cshoe
---
# Tutorial: Enable Azure Container Apps on Azure Arc-enabled Kubernetes
With [Azure Arc-enabled Kubernetes clusters](/azure/azure-arc/kubernetes/overview), you can create a [Container Apps enabled custom location](azure-arc-create-container-app.md) in your on-premises or cloud Kubernetes cluster to deploy your Azure Container Apps applications as you would any other region.
This tutorial shows how to enable Azure Container Apps on an Azure Arcβenabled Kubernetes cluster. In this tutorial, you:
> [!div class="checklist"]
> * Create a connected cluster.
> * Create a Log Analytics workspace.
> * Install the Container Apps extension.
> * Create a custom location.
> * Create the Azure Container Apps connected environment.
## Prerequisites
Before you begin, make sure you have the following prerequisites in place:
- An Azure account with an active subscription.
- If you don't have one, you [can create one for free](https://azure.microsoft.com/pricing/purchase-options/azure-account?cid=msft_learn).
- Install the [Azure CLI](/cli/azure/install-azure-cli).
- Access to a public or private container registry, such as the [Azure Container Registry](/azure/container-registry/).
## Setup
Install the following Azure CLI extensions.
# [Azure CLI](#tab/azure-cli)
```azurecli
az extension add --name connectedk8s --upgrade --yes
az extension add --name k8s-extension --upgrade --yes
az extension add --name customlocation --upgrade --yes
az extension add --name containerapp --upgrade --yes
```
# [PowerShell](#tab/powershell)
```powershell
az extension add --name connectedk8s --upgrade --yes
az extension add --name k8s-extension --upgrade --yes
az extension add --name customlocation --upgrade --yes
az extension add --name containerapp --upgrade --yes
```
---
Register the required namespaces.
# [Azure CLI](#tab/azure-cli)
```azurecli
az provider register --namespace Microsoft.ExtendedLocation --wait
az provider register --namespace Microsoft.KubernetesConfiguration --wait
az provider register --namespace Microsoft.App --wait
az provider register --namespace Microsoft.OperationalInsights --wait
```
# [PowerShell](#tab/powershell)
```powershell
az provider register --namespace Microsoft.ExtendedLocation --wait
az provider register --namespace Microsoft.KubernetesConfiguration --wait
az provider register --namespace Microsoft.App --wait
az provider register --namespace Microsoft.OperationalInsights --wait
```
---
Set environment variables based on your Kubernetes cluster deployment.
# [Azure CLI](#tab/azure-cli)
```bash
GROUP_NAME="my-arc-cluster-group"
AKS_CLUSTER_GROUP_NAME="my-aks-cluster-group"
AKS_NAME="my-aks-cluster"
LOCATION="eastus"
```
# [PowerShell](#tab/powershell)
```powershell
$GROUP_NAME="my-arc-cluster-group"
$AKS_CLUSTER_GROUP_NAME="my-aks-cluster-group"
$AKS_NAME="my-aks-cluster"
$LOCATION="eastus"
```
---
## Create a connected cluster
These instructions are meant for evaluation and learning purposes. For production deployments, refer to [Quickstart: Connect an existing Kubernetes cluster to Azure Arc](/azure/azure-arc/kubernetes/quickstart-connect-cluster) for general instructions on creating an Azure Arc-enabled Kubernetes cluster.
To get started with service, follow these steps to create an Azure Kubernetes Service (AKS) cluster and connect it to Azure Arc:
1. Create a cluster in Azure Kubernetes Service.
# [Azure CLI](#tab/azure-cli)
```azurecli
az group create --name $AKS_CLUSTER_GROUP_NAME --location $LOCATION
az aks create \
--resource-group $AKS_CLUSTER_GROUP_NAME \
--name $AKS_NAME \
--enable-aad \
--generate-ssh-keys
```
# [PowerShell](#tab/powershell)
```powershell
az group create --name $AKS_CLUSTER_GROUP_NAME --location $LOCATION
az aks create `
--resource-group $AKS_CLUSTER_GROUP_NAME `
--name $AKS_NAME `
--enable-aad `
--generate-ssh-keys
```
---
1. Get the [kubeconfig](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) file and test your connection to the cluster. By default, the kubeconfig file is saved to `~/.kube/config`.
```azurecli
az aks get-credentials --resource-group $AKS_CLUSTER_GROUP_NAME --name $AKS_NAME --admin
kubectl get ns
```
1. Create a resource group to contain your Azure Arc resources.
# [Azure CLI](#tab/azure-cli)
```azurecli
az group create --name $GROUP_NAME --location $LOCATION
```
# [PowerShell](#tab/powershell)
```powershell
az group create --name $GROUP_NAME --location $LOCATION
```
---
1. Connect the cluster you created to Azure Arc.
# [Azure CLI](#tab/azure-cli)
```azurecli
CLUSTER_NAME="${GROUP_NAME}-cluster" # Name of the connected cluster resource
az connectedk8s connect --resource-group $GROUP_NAME --name $CLUSTER_NAME
```
# [PowerShell](#tab/powershell)
```powershell
$CLUSTER_NAME="${GROUP_NAME}-cluster" # Name of the connected cluster resource
az connectedk8s connect --resource-group $GROUP_NAME --name $CLUSTER_NAME
```
---
1. Validate the connection with the following command. It should show the `provisioningState` property as `Succeeded`. If not, run the command again after a minute.
```azurecli
az connectedk8s show --resource-group $GROUP_NAME --name $CLUSTER_NAME
```
## Create a Log Analytics workspace
A [Log Analytics workspace](/azure/azure-monitor/logs/quick-create-workspace) provides access to logs for Container Apps applications running in the Azure Arc-enabled Kubernetes cluster. A Log Analytics workspace is optional, but recommended.
1. Create a Log Analytics workspace.
# [Azure CLI](#tab/azure-cli)
```azurecli
WORKSPACE_NAME="$GROUP_NAME-workspace" # Name of the Log Analytics workspace
az monitor log-analytics workspace create \
--resource-group $GROUP_NAME \
--workspace-name $WORKSPACE_NAME
```
# [PowerShell](#tab/powershell)
```powershell
$WORKSPACE_NAME="$GROUP_NAME-workspace"
az monitor log-analytics workspace create `
--resource-group $GROUP_NAME `
--workspace-name $WORKSPACE_NAME
```
---
1. Run the following commands to get the encoded workspace ID and shared key for an existing Log Analytics workspace. You need them in the next step.
# [Azure CLI](#tab/azure-cli)
```azurecli
LOG_ANALYTICS_WORKSPACE_ID=$(az monitor log-analytics workspace show \
--resource-group $GROUP_NAME \
--workspace-name $WORKSPACE_NAME \
--query customerId \
--output tsv)
LOG_ANALYTICS_WORKSPACE_ID_ENC=$(printf %s $LOG_ANALYTICS_WORKSPACE_ID | base64 -w0) # Needed for the next step
LOG_ANALYTICS_KEY=$(az monitor log-analytics workspace get-shared-keys \
--resource-group $GROUP_NAME \
--workspace-name $WORKSPACE_NAME \
--query primarySharedKey \
--output tsv)
LOG_ANALYTICS_KEY_ENC=$(printf %s $LOG_ANALYTICS_KEY | base64 -w0) # Needed for the next step
```
# [PowerShell](#tab/powershell)
```powershell
$LOG_ANALYTICS_WORKSPACE_ID=$(az monitor log-analytics workspace show `
--resource-group $GROUP_NAME `
--workspace-name $WORKSPACE_NAME `
--query customerId `
--output tsv)
$LOG_ANALYTICS_WORKSPACE_ID_ENC=[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($LOG_ANALYTICS_WORKSPACE_ID))# Needed for the next step
$LOG_ANALYTICS_KEY=$(az monitor log-analytics workspace get-shared-keys `
--resource-group $GROUP_NAME `
--workspace-name $WORKSPACE_NAME `
--query primarySharedKey `
--output tsv)
$LOG_ANALYTICS_KEY_ENC=[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($LOG_ANALYTICS_KEY))
```
---
## Install the Container Apps extension
> [!IMPORTANT]
> If deploying onto **AKS on Azure Local**, ensure that you have [setup HAProxy or a custom load balancer](/azure/aks/aksarc/configure-load-balancer) before attempting to install the extension. You could also use `az containerapp arc setup-core-dns --distro AksAzureLocal` to set up core dns for local contexts.
1. Set the following environment variables to the desired name of the [Container Apps extension](azure-arc-create-container-app.md), the cluster namespace in which resources should be provisioned, and the name for the Azure Container Apps connected environment. Choose a unique name for `<connected-environment-name>`. The connected environment name is part of the domain name for app you create in the Azure Container Apps connected environment.
# [Azure CLI](#tab/azure-cli)
```bash
EXTENSION_NAME="appenv-ext"
NAMESPACE="appplat-ns"
CONNECTED_ENVIRONMENT_NAME="<connected-environment-name>"
```
# [PowerShell](#tab/powershell)
```powershell
$EXTENSION_NAME="appenv-ext"
$NAMESPACE="appplat-ns"
$CONNECTED_ENVIRONMENT_NAME="<connected-environment-name>"
```
---
1. Install the Container Apps extension to your Azure Arc-connected cluster with Log Analytics enabled. Log Analytics can't be added to the extension later.
# [Azure CLI](#tab/azure-cli)
```azurecli
az k8s-extension create \
--resource-group $GROUP_NAME \
--name $EXTENSION_NAME \
--cluster-type connectedClusters \
--cluster-name $CLUSTER_NAME \
--extension-type 'Microsoft.App.Environment' \
--release-train stable \
--auto-upgrade-minor-version true \
--scope cluster \
--release-namespace $NAMESPACE \
--configuration-settings "Microsoft.CustomLocation.ServiceAccount=default" \
--configuration-settings "appsNamespace=${NAMESPACE}" \
--configuration-settings "clusterName=${CONNECTED_ENVIRONMENT_NAME}" \
--configuration-settings "logProcessor.appLogs.destination=log-analytics" \
--configuration-protected-settings "logProcessor.appLogs.logAnalyticsConfig.customerId=${LOG_ANALYTICS_WORKSPACE_ID_ENC}" \
--configuration-protected-settings "logProcessor.appLogs.logAnalyticsConfig.sharedKey=${LOG_ANALYTICS_KEY_ENC}"
```
# [PowerShell](#tab/powershell)
```powershell
az k8s-extension create `
--resource-group $GROUP_NAME `
--name $EXTENSION_NAME `
--cluster-type connectedClusters `
--cluster-name $CLUSTER_NAME `
--extension-type 'Microsoft.App.Environment' `
--release-train stable `
--auto-upgrade-minor-version true `
--scope cluster `
--release-namespace $NAMESPACE `
--configuration-settings "Microsoft.CustomLocation.ServiceAccount=default" `
--configuration-settings "appsNamespace=${NAMESPACE}" `
--configuration-settings "clusterName=${CONNECTED_ENVIRONMENT_NAME}" `
--configuration-settings "logProcessor.appLogs.destination=log-analytics" `
--configuration-protected-settings "logProcessor.appLogs.logAnalyticsConfig.customerId=${LOG_ANALYTICS_WORKSPACE_ID_ENC}" `
--configuration-protected-settings "logProcessor.appLogs.logAnalyticsConfig.sharedKey=${LOG_ANALYTICS_KEY_ENC}"
```
---
> [!NOTE]
> To install the extension without Log Analytics integration, remove the last three `--configuration-settings` parameters from the command.
>
> For clusters that use a custom load balancer instead of the standard AKS load balancer, once the load balancer is set up, specify the following parameter:
>
> ```
> --configuration-settings "loadBalancerIp=<LOAD_BALANCER_INGRESS_IP>"
> ```
> Replace \<LOAD_BALANCER_INGRESS_IP> with the actual ingress IP address assigned to your load balancer.
The following table describes the various `--configuration-settings` parameters when running the command:
| Parameter | Description |
|---|---|
| `Microsoft.CustomLocation.ServiceAccount` | The service account created for the custom location. Set the value to `default`. |
| `appsNamespace` | The namespace used to create the app definitions and revisions. It **must** match that of the extension release namespace. |
| `clusterName` | The name of the Container Apps extension Kubernetes environment created against this extension. |
| `logProcessor.appLogs.destination` | Optional. Destination for application logs. Accepts `log-analytics` or `none`, choosing none disables platform logs. |
| `logProcessor.appLogs.logAnalyticsConfig.customerId` | Required only when `logProcessor.appLogs.destination` is set to `log-analytics`. The base64-encoded Log analytics workspace ID. This parameter should be configured as a protected setting. |
| `logProcessor.appLogs.logAnalyticsConfig.sharedKey` | Required only when `logProcessor.appLogs.destination` is set to `log-analytics`. The base64-encoded Log analytics workspace shared key. This parameter should be configured as a protected setting. |
| `loadBalancerIp` | The ingress IP of the load balancer. |
1. Save the `id` property of the Container Apps extension for later.
# [Azure CLI](#tab/azure-cli)
```azurecli
EXTENSION_ID=$(az k8s-extension show \
--cluster-type connectedClusters \
--cluster-name $CLUSTER_NAME \
--resource-group $GROUP_NAME \
--name $EXTENSION_NAME \
--query id \
--output tsv)
```
# [PowerShell](#tab/powershell)
```powershell
$EXTENSION_ID=$(az k8s-extension show `
--cluster-type connectedClusters `
--cluster-name $CLUSTER_NAME `
--resource-group $GROUP_NAME `
--name $EXTENSION_NAME `
--query id `
--output tsv)
```
---
1. Wait for the extension to fully install before proceeding. You can have your terminal session wait until it completes by running the following command:
```azurecli
az resource wait --ids $EXTENSION_ID --custom "properties.provisioningState!='Pending'" --api-version "2020-07-01-preview"
```
Use `kubectl` to view the pods running in your Kubernetes cluster:
```bash
kubectl get pods -n $NAMESPACE
```
To learn more about these pods and their role in the system, see [Azure Arc overview](azure-arc-overview.md#resources-created-by-the-container-apps-extension).
## Create a custom location
The [custom location](/azure/azure-arc/kubernetes/custom-locations) is an Azure location that you assign to the Azure Container Apps connected environment.
1. Set the following environment variables to the desired name of the custom location and for the ID of the Azure Arc-connected cluster.
# [Azure CLI](#tab/azure-cli)
```azurecli
CUSTOM_LOCATION_NAME="my-custom-location" # Name of the custom location
CONNECTED_CLUSTER_ID=$(az connectedk8s show --resource-group $GROUP_NAME --name $CLUSTER_NAME --query id --output tsv)
```
# [PowerShell](#tab/powershell)
```powershell
$CUSTOM_LOCATION_NAME="my-custom-location" # Name of the custom location
$CONNECTED_CLUSTER_ID=$(az connectedk8s show --resource-group $GROUP_NAME --name $CLUSTER_NAME --query id --output tsv)
```
---
1. Create the custom location:
# [Azure CLI](#tab/azure-cli)
```azurecli
az customlocation create \
--resource-group $GROUP_NAME \
--name $CUSTOM_LOCATION_NAME \
--host-resource-id $CONNECTED_CLUSTER_ID \
--namespace $NAMESPACE \
--cluster-extension-ids $EXTENSION_ID
```
# [PowerShell](#tab/powershell)
```azurecli
az customlocation create `
--resource-group $GROUP_NAME `
--name $CUSTOM_LOCATION_NAME `
--host-resource-id $CONNECTED_CLUSTER_ID `
--namespace $NAMESPACE `
--cluster-extension-ids $EXTENSION_ID
```
---
> [!NOTE]
> If you experience issues creating a custom location on your cluster, you may need to [enable the custom location feature on your cluster](/azure/azure-arc/kubernetes/custom-locations#enable-custom-locations-on-your-cluster). Enable this feature when logged into the CLI using a Service Principal or a Microsoft Entra user with restricted permissions on the cluster resource.
>
1. Validate that the custom location is successfully created with the following command. The output should show the `provisioningState` property as `Succeeded`. If not, rerun the command after a minute.
```azurecli
az customlocation show --resource-group $GROUP_NAME --name $CUSTOM_LOCATION_NAME
```
1. Save the custom location ID for the next step.
# [Azure CLI](#tab/azure-cli)
```azurecli
CUSTOM_LOCATION_ID=$(az customlocation show \
--resource-group $GROUP_NAME \
--name $CUSTOM_LOCATION_NAME \
--query id \
--output tsv)
```
# [PowerShell](#tab/powershell)
```azurecli
$CUSTOM_LOCATION_ID=$(az customlocation show `
--resource-group $GROUP_NAME `
--name $CUSTOM_LOCATION_NAME `
--query id `
--output tsv)
```
---
## Create the Azure Container Apps connected environment
Before you can start creating apps in the custom location, you need an [Azure Container Apps connected environment](azure-arc-create-container-app.md).
1. Create the Container Apps connected environment:
# [Azure CLI](#tab/azure-cli)
```azurecli
az containerapp connected-env create \
--resource-group $GROUP_NAME \
--name $CONNECTED_ENVIRONMENT_NAME \
--custom-location $CUSTOM_LOCATION_ID \
--location $LOCATION
```
# [PowerShell](#tab/powershell)
```powershell
az containerapp connected-env create `
--resource-group $GROUP_NAME `
--name $CONNECTED_ENVIRONMENT_NAME `
--custom-location $CUSTOM_LOCATION_ID `
--location $LOCATION
```
---
1. Validate that the Container Apps connected environment is successfully created with the following command. The output should show the `provisioningState` property as `Succeeded`. If not, run it again after a minute.
```azurecli
az containerapp connected-env show --resource-group $GROUP_NAME --name $CONNECTED_ENVIRONMENT_NAME
```
## Next steps
> [!div class="nextstepaction"]
> [Create a container app on Azure Arc](azure-arc-create-container-app.md)