Deploy Azure Kubernetes Service (AKS) to a preexisting VNET

I recently ran into an issue where I needed to deploy AKS in an environment with a limited number of available IP addresses. If you’ve ever deployed AKS before, you might have noticed that using the default settings creates a new VNET with a /8 CIDR range (16,777,214 hosts), which was way too large for this environment as the largest we could use could was a /23 (510 hosts).

The steps below will walk you through the process of deploying your cluster and using not only a preexisting VNET, but one that resides in a resource group that’s separate from your cluster resource group.


Create a service principal

Most guides that walk through creating a service principal for AKS recommend doing so using the command

 $ az ad sp create-for-rbac --skip-assignment

While this works just fine, it doesn’t provide any rights to the service principal and requires you to configure a role and scope after you’ve created the AKS cluster. Instead of doing this in two steps, I prefer to use this command to handle it all at once.

$ az ad sp create-for-rbac -n AKS_SP --role contributor \
    --scopes /subscriptions/061f5e92-edf2-4389-8357-a16f71a2cbf3/resourceGroups/AKS-DEMO-RG \

What I’m doing with the above command is setting the scope of the service principal to have contributor rights on two resources groups. The first resource group (AKS-DEMO-RG) will contain the AKS cluster and the second (AKS-VNET-RG) contains the virtual network and subnet that will be used for the cluster resources. I’m also providing a name for the service principal (AKS_SP) so it’s easy to identify later on down the road. If you use the default name it will be labeled azure-cli-yyyy-mm-dd-hh-mm-ss, which as you can see is not quite as friendly nor identifiable as AKS_SP

When the command completes, you should see the following output:

    "appId": "b2abba9c-ef9a-4a0e-8d8b-46d8b53d046b",
    "displayName": "AKS_SP",
    "name": "http://AKS_SP",
    "password": "2a30869c-388e-40cf-8f5f-8d99fea405bf",
    "tenant": "dbbbe410-bc70-4a57-9d46-f1a1ea293b48"

Make note of the appId and the password as that will be required in the next step

Create the cluster

In this section we’ll create our AKS cluster and configure the required tools to interact with it after deployment.

In the below example, replace the parameters with values that suit your environment. The Service Principal and Client Secret parameters should match the appId and password from the output of the az ad sp create command above.

 az aks create --resource-group AKS-DEMO-RG --name demoAKSCluster \
 --service-principal "b2abba9c-ef9a-4a0e-8d8b-46d8b53d046b" \
 --client-secret "2a30869c-388e-40cf-8f5f-8d99fea405bf" \
 --vnet-subnet-id "/subscriptions/061f5e92-edf2-4389-8357-a16f71a2cbf3/resourceGroups/AKS-VNET-RG/providers/Microsoft.Network/virtualNetworks/AKS-DEMO-VNET/subnets/S-1"

Install kubectl

$ sudo az aks install-cli

Fetch the credentials to use for the connection to the cluster

$ az aks get-credentials --resource-group AKS-DEMO-RG --name demoAKSCluster

You should see the following output

Merged "demoAKSCluster" as current context in /home/azureadmin/.kube/config

Test connectivity to the cluster

$ kubectl get nodes

All of your nodes should appear in a Ready status

Additionally, you should see the NIC for each of your nodes connected to the VNET/subnet you provided during deployment.

And that’s it. You now have an AKS cluster deployed using a preexisting virtual network and subnet.

In my next post, I’ll show you how to configure TLS for Helm and Tiller, and deploy an ingress-controller with SSL termination all with certificates issued by a Windows Certificate Authority.