Juju on Azure AKS

Running through this guide will ensure that you’re ready to deploy and manage Kubernetes workloads on Azure Kubernetes Service (AKS) with Juju.

Juju provides built-in support for AKS. That means, once you’ve registered your cluster, you’ll be able to deploy workloads straight away.

This guide covers:

  • making sure all necessary software is installed
  • all configuration is in place
  • a live Juju controller is available
  • a Juju model has been created

Software to Install

Using Juju to drive Kubernetes workloads on AKS requires installing some pre-requisite software:

  • Juju client
  • Azure CLI
  • Kubernetes client

Juju client (juju)

You will need to install Juju. If you’re on Linux, we recommend using snap:

snap install juju --classic

We also provide other installation methods as described on our detailed installation documentation.

Azure CLI (az)

The Azure CLI is a cross-platform command-line utility for interacting with Azure. For installation instructions, please visit the Azure CLI web pages.

Kubernetes client (kubectl)

kubectl is the command-line client for directly interacting with a Kubernetes cluster. The Azure CLI provides a sub-command that will install kubectl for you.

az aks install-cli

If you encounter any issues with this, visit the Kubernetes documentation for manual kubectl installation instructions.

Provision a Kubernetes cluster on Azure

You will need to have an AKS cluster available before Juju can connect to it. In Azure’s terminology, you need to create a “Managed Kubernetes resource”. It’s easy to do that via the Azure Dashboard via https://portal.azure.com/#create/microsoft.aks. If you prefer to use command-line tools though, here are detailed instructions.

Please refer to Azure’s own documentation for authoritative information on how to manage services and accounts with Azure.

Log in to Azure

From the command-line, login:

az login

Configure the Azure subscription

A Subscription is a container for Azure resources that enables billing and usage accounting. Subscriptions are created under an Enrollment Account.

(Optional) Create a new subscription

Creating a new subscription is unlikely to be necessary unless you have specialist requirements. Consult the Azure documentation for details about whether this applies to you.

(Optional) Account Permissions in a Locked Down Environment

As of this writing, the Azure account needs the following permissions to successfully provision a Kubernetes cluster. (In most public cloud setups, you’ll have these permissions by default, and can skip this section.)

// Required to create, delete or update LoadBalancer for LoadBalancer service
Microsoft.Network/loadBalancers/(delete, read, write)

// Required to allow query, create or delete public IPs for LoadBalancer service
Microsoft.Network/publicIPAddresses/(delete, read, write)

// Required if public IPs from another resource group are used for LoadBalancer service
// This is because of the linked access check when adding the public IP to LB frontendIPConfiguration

// Required to create or delete security rules for LoadBalancer service
Microsoft.Network/networkSecurityGroups/(read, write)

// Required to create, delete or update AzureDisks
Microsoft.Compute/disks/(delete, read, write)


// Required to create, update or delete storage accounts for AzureFile or AzureDisk
Microsoft.Storage/storageAccounts/(delete, read, write)


// Required to create, delete or update routeTables and routes for nodes
Microsoft.Network/routeTables/(read, write)
Microsoft.Network/routeTables/routes/(delete, read, write)

// Required to query information for VM (e.g. zones, faultdomain, size and data disks)
Microsoft.Compute/virtualMachines/(read, write)

// Required to query information for vmssVM (e.g. zones, faultdomain, size and data disks)

// Required to add VM to LoadBalancer backendAddressPools
// Required to add vmss to LoadBalancer backendAddressPools
// Required to attach AzureDisks and add vmssVM to LB
// Required to upgrade VMSS models to latest for all instances
// only needed for Kubernetes 1.11.0-1.11.9, 1.12.0-1.12.8, 1.13.0-1.13.5, 1.14.0-1.14.1

// Required to query internal IPs and loadBalancerBackendAddressPools for VM
// Required to query internal IPs and loadBalancerBackendAddressPools for vmssVM
// Required to get public IPs for vmssVM

// Required to check whether subnet existing for ILB in another resource group

// Required to create, update or delete snapshots for AzureDisk
Microsoft.Compute/snapshots/(delete, read, write)

// Required to get vm sizes for getting AzureDisk volume limit

Enable the subscription extension

To create subscriptions from the Azure CLI, an extension is required:

az extension add --name subscription

List your Enrollment Accounts

To print a list of Enrollment Accounts, use az billing enrollment-account list:

az billing enrollment-account list -o table

Create a new subscription

Use the desired “Name” from the output as <enrollment-account> in the next step. <subscription> is a human-readable name that you would like to use for that subscription.

az account create --display-name <subscription> --enrollment-account-object-id <enrollment-account>

Listing subscriptions

You should now be able to set the are now able to see the new subscription in your list of current subscriptions:

az account list -o table

Set the correct default subscription

To ensure billing is allocated to the correct account, you should use the az account set command. <subscription> can be a subscription’s GUID or its name. To list available subscriptions, use az account list.

az account set -s <subscription>

Verify that the correct subscription is the default

Verify that you are connected to the correct subscription with the account show sub-command:

az account show -o table

Register Resource providers

A “Resource provider”, also known as a “Resource namespace”, is a set of products that are available to subscriptions through Azure. AKS requires 4 providers to be enabled to function correctly.

These providers should be enabled already, but ensuring that they’re available will prevent any problems.

az provider register --namespace 'Microsoft.Compute' --wait
az provider register --namespace 'Microsoft.Storage' --wait
az provider register --namespace 'Microsoft.Network' --wait
az provider register --namespace 'Microsoft.ContainerService' --wait

Choose an Azure region to operate in

Each Azure region has different capabilities. In particular, different Kubernetes versions are supported within each region. To get the list of regions, Juju offers the juju regions command. The Azure CLI can inspect the region to check which Kubernetes version is supported there.

juju regions azure
az aks get-versions --location <region> -o table

Note the region down that you intend to use for when you create a Resource Group.

Create a Resource Group

A “Resource Group” is a link between services and a geographic region for billing and authentication purposes.

To create a Resource Group for your project, provide a region and a human-readable name to the az group create command.

az group create --location <region> --name <resource-group>

To simplify further commands, you can set your new Resource Group as the default.

az configure --defaults group=<resource-group>

Create the Kubernetes cluster with the Azure CLI

With a Resource Group and other necessary preparation in place, we’re now able to provision an AKS cluster.

(Optional) Create a container registry

You may wish to provision a container registry for your cluster:

az acr create -n <registry-name> -g  <resource-group>

Create the Kubernetes cluster with the Azure CLI

The az aks create command provisions a cluster. Assuming that you have selected a default Resource Group, providing a human-readable name as <k8s-cluster> is the only required option.

az aks create -g <resource-group> --name <k8s-cluster>

az aks create is highly configurable, and you are recommended to read the options available via az aks create --help.

Linking the cluster to the local environment

Enable kubectl

The Azure CLI will configure kubectl on your behalf via the az aks get-credentials command. kubectl will be able to control your cluster directly.

az aks get-credentials -g <resource-group> --name <k8s-cluster>

Verify kubectl set up

To check that you have configured kubectl correctly, execute a command:

kubectl get nodes

Set up Juju within the cluster

Now that the pieces are in place, let’s join them together. This is a three step process:

  • registering the cluster as a “K8s cloud”
  • deploying a Juju controller within the cluster
  • creating a “model” (namespace) to house our deployment(s)

Register the cluster as a “K8s cloud”

In Juju’s vocabulary, a “cloud” is a space that can host deployed workloads. To register a Kubernetes cluster with Juju, execute the juju add-k8s command. The <cloud> will be used by Juju to refer to the cluster.

juju add-k8s --aks --resource-group <resource-group> --cluster-name <k8s-cluster> <cloud-name>

Create a controller

Juju, as an active agent system, requires a controller to get started. Controllers are created with the juju bootstrap command that takes a cloud’s name and our intended name for the controller.

juju bootstrap <cloud> <controller>

Create a model

A model is a workspace for inter-related applications. They correspond (roughly) to a Kubernetes namespace. To create one, use juju add-model with a name of your choice:

juju add-model <model>

Deploy workloads

You’re now able to deploy workloads into your model. Workloads are provided by charms (and sets of charms called bundles).

Use the Kubernetes filter in the Charm Store to find Kubernetes workloads to deploy, e.g. Search results for | Juju.

All of the stuff related on how to create a kubernetes cluster, could be just a link to azure documentation, similarly what we do in the GKE documentation; i.e. we can leave in the installation of the cli tools and then directly start with “Set up Juju within the cluster” chapter.

It seems command

juju add-k8s --aks --resource-group <resource-group> --cluster-name <k8s-cluster> <cloud>

Is much more verbose than the analogues for gke - juju add-k8s --gke. Although command itself could be partly removed in the future and made to be automatic (since Thomas is working on it).

Also have a different output then expected -

This operation can be applied to both a copy on this client and to the one on a controller.
Do you want to add k8s cloud aks to:
    1. client only (--client)
    2. controller "for-juju" only (--controller for-juju)
    3. both (--client --controller for-juju)
Enter your choice, or type Q|q to quit: 

It would also be cool to add links (at least) on how all of these things we just created - cloud, k8s, credentials and etc; could be removed