All commands in the gist should be run from bash. You can use WSL (Windows Subsystem for Linux) to run the commands. You can also use the Azure Cloud Shell and select Bash instead of PowerShell.
Install Azure CLI (not needed in Azure Cloud Shell, CLI is pre-installed) and add the following Azure CLI extensions:
az extension add --name connectedk8s
az extension add --name k8s-extension
az extension add --name customlocation
az extension remove --name appservice-kube
az extension add --upgrade --yes --name appservice-kube
Register providers in a subscription you use for testing (preview):
az provider register --namespace Microsoft.ExtendedLocation --wait
az provider register --namespace Microsoft.Web --wait
az provider register --namespace Microsoft.KubernetesConfiguration --wait
az aks get-credentials --resource-group RESOURCEGROUP --name CLUSTERNAME --admin
Ensure a working kubeconfig to check the pods that land on the cluster. Run kubectl get nodes
to check your cluster.
Set variables for resource group and Azure Arc-enabled cluster. You can reuse the resource group where you deployed AKS. The clu variable below is the name of the Azure Arc-enabled cluster.
For example:
rg=rg-arc
clu=arcaks
Connect your AKS cluster to Azure Arc with the command below. Note that we use AKS for testing the Azure Arc Application Services. In the real world, you would never Azure Arc-enable an AKS cluster.
az group create -g $rg -l LOCATION
az connectedk8s connect --resource-group $rg --name $clu
The last command will take a few minutes. When finished, check your cluster for the Azure Arc pods in the azure-arc
namespace.
Set some variables for the extension:
- extensionName: this is the name of the extension to install; for App Service, this is "appservice-ext"
- namespace: choose a namespace for your extension
- kubeEnvironmentName: choose a name for the App Service Kubernetes environment
extensionName="appservice-ext"
namespace="appservice-ns"
kubeEnvironmentName="kube-appenv"
Install the extension using the Azure CLI.
kubectl get sc
to see the available storage classes. On other clusters besides AKS, always check the storage classes and use the one that is appropriate.
envoy.annotations.service.beta.kubernetes.io/azure-load-balancer-resource-group
is specific for AKS; if you deploy the extension to other Kubernetes clusters, like K8S in Digital Ocean, you do not need to set this. Even with AKS, it will work without setting this.
# set below variable to the resource group that contains physical cluster resources of AKS
# if not specified or not set, the extension should still install successfully :-)
aksClusterGroupName="MC_rg-aks_kub001_westeurope"
az k8s-extension create \
--resource-group $rg \
--name $extensionName \
--cluster-type connectedClusters \
--cluster-name $clu \
--extension-type 'Microsoft.Web.Appservice' \
--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=${kubeEnvironmentName}" \
--configuration-settings "keda.enabled=true" \
--configuration-settings "buildService.storageClassName=default" \
--configuration-settings "buildService.storageAccessMode=ReadWriteOnce" \
--configuration-settings "customConfigMap=${namespace}/kube-environment-config" \
--configuration-settings "envoy.annotations.service.beta.kubernetes.io/azure-load-balancer-resource-group=${aksClusterGroupName}"
The above command creates the extension, which is just an ARM resource. Azure Arc for Kubernetes will check for these extensions and start installing the extension with Helm.
Get the extension Id with the following command:
extensionId=$(az k8s-extension show \
--cluster-type connectedClusters \
--cluster-name $clu \
--resource-group $rg \
--name $extensionName \
--query id \
--output tsv)
Now wait for the installation to be complete with az resource wait --ids $extensionId --custom "properties.installState!='Pending'" --api-version "2020-07-01-preview"
When the extension is installed, you can proceed with the creation of a custom location.
Later, you will install the App Service Kubernetes environment. The environment, but also the web apps, functions apps and logic apps need a custom location.
First, set the location name and retrieve the Id of the connected cluster:
customLocationName="YOUR-LOCATION-NAME" # Name of the custom location
connectedClusterId=$(az connectedk8s show --resource-group $rg --name $clu --query id --output tsv)
Now you can create the custom location:
az customlocation create \
--resource-group $rg \
--name $customLocationName \
--host-resource-id $connectedClusterId \
--namespace $namespace \
--cluster-extension-ids $extensionId
Check the custom location with az customlocation show --resource-group $rg --name $customLocationName
Save the custom location Id. You need it to create the App Service Kubernetes environment.
customLocationId=$(az customlocation show \
--resource-group $rg \
--name $customLocationName \
--query id \
--output tsv)
Use the following command to create the environment:
az appservice kube create \
--resource-group $rg \
--name $kubeEnvironmentName \
--custom-location $customLocationId
Verify successful creation with az appservice kube show --resource-group $rg --name $kubeEnvironmentName
The above command just creates the environment to create web apps on Kubernetes.
You can use the Azure Portal as shown in the video.
If you want to tuse the Azure CLI, use the following command.
az webapp create \
--resource-group $rg \
--name WEBAPPNAME \
--custom-location $customLocationId \
--runtime 'NODE|12-lts'
Note: find the Linux runtimes to use with az webapp list-runtimes --linux
When the command succeeds, there will be a new pod in the App Service namespace called WEBAPPNAME-...
. Check the hostNames section in the output of the command, it contains the URL to access the app. You will need to use this URL to access the app as asked below.
Deploy code (ensure zip is installed with sudo apt-get install zip
))
git clone https://github.com/Azure-Samples/nodejs-docs-hello-world
cd nodejs-docs-hello-world
zip -r package.zip .
az webapp deployment source config-zip --resource-group $rg --name WEBAPPNAME --src package.zip
When you navigate to the web app, you should see a Hello World!
message.