Elastic stack in AKS. Part 2 Provisioning Kubernetes with az CLI

Deploying a Kubernetes cluster in Azure using command line interface is an easy task. We will deploy a k8s cluster with custom nodes configuration specified for Elasticsearch.

Elastic stack in AKS. Part 1 Provisioning Kubernetes with Terraform

Source code is available at repository https://github.com/mchudinov/K8sAzureAzCli

Let’s get started.


We deploy the following infrastructure. It looks very much the same as in Elastic stack in AKS Part 1 but without storage for Terraform state, since we do not use Terraform now.

Azure Kubernetes Service (AKS)The environment for running Elastic stack
Ingress NginxIngress controller based on Nginx
DeploymentAny arbital deployment inside AKS
Inbound IPPublic static IP for inbound traffic
Outbound IPPublic static IP for outbound traffic. With static outbound IP can be whitelisted in any external services or components for incoming traffic from our cluster. Particular useful for Elastic Heartbeat.
BackupAzure storage account for Elastic snapshots
Log AnalyticsAzure Log Analytics workspace for AKS logs and monitoring


Hardcoded parameters

  • Kubernetes version 1.20.5
  • VM nodes size: Standard_B2s with 2vCPU, 4GiB memory

These are defined as variables in deploy.sh script and can be changed there.


The easiest way with no tools required is to use Azure Cloud Shell

In order to use this from a local environment, the following tools are required:

  • Azure CLI version >= 2.8
  • git
  • kubectl – Kubernetes command line tool
  • helm
  • Bash shell (the deployment script is written in Bash)


  1. Login to Azure Cloud Shell https://shell.azure.com
  2. Clone the repository
git clone https://github.com/mchudinov/K8sAzureAzCli.git

3. Change to source code directory cd K8sAzureAzCli

4. Run deploy.sh script

For example:

./deploy.sh -c mytestk8s -n 3 -r westeurope

The keys for the deployment script are:

  • -c Cluster name
  • -n Number of nodes (default 1)
  • -r Azure region (default West Europe)

After a couple of minutes a new Kubernetes cluster will be ready.

All the created resource are in a single resource group rg-<cluster_name> 


The main command for provisioning of AKS :

az aks create --resource-group $RESOURCE_GROUP --location $region \
  --name $AKS_NAME \
  --dns-name-prefix $AKS_NAME \
  --kubernetes-version "1.20.5" \
  --node-count $nodes \
  --node-vm-size "Standard_B2s" \
  --nodepool-name "kubenet" \
  --outbound-type "loadBalancer" \
  --enable-addons monitoring  \
  --load-balancer-outbound-ips $PUBLIC_IP_OUTBOUND_ID \
  --linux-os-config ./linuxosconfig.json \
  --workspace-resource-id $LOGANALTICS_WORKSPACE_ID \

-–generate-ssh-keys is optional it generates keys and prevents en error message An RSA key file or key value must be supplied to SSH Key Value.


Add Kubernetes credentials to the local .cube config file

az aks get-credentials --name <AKS_NAME> --resource-group <RESOURCE_GROUP>

How to run an interactive shell

kubectl apply -f interactive.yaml

Check CSI driver is running

kubectl get csidrivers
kubectl describe csidriver secrets-store.csi.k8s.io
kubectl get pods -l app=secrets-store-csi-driver

Log Analytics Workspace works immediately after deployment.


Delete everything created in Azure using destroy.sh script.

destroy.sh script has a single parameter – the name of the cluster. For example:

./destroy.sh -c mytestk8s 

Delete everything created manually. If destroy.sh script fails everything that was created can be easily erased manually. Just delete the resource groups created by script: 

az group delete --resource-group rg-<cluster_name>

Discard all local changes in git repository

git reset --hard

Delete the source code directory in Cloud Shell

rm -rf K8sAzureAzCli

Pros and cons

Deployment of AKS with az CLI has one important advantage – it supports AKS custom node configuration. Customize node configuration for Azure Kubernetes Service (AKS) node pools (preview) Custom AKS node configuration in particular useful for running Elasticsearch as it requires vm.max_map_count=262144

Without custom configuration Elasticsearch pods must be run privileged in order to satisfy virtual that memory requirement.

Wrapping up

We have successfully deployed a managed Kubernetes service in Azure using az command line tool. This cluster suits for deployment of Elasticsearch as well as other services.

The newly created Kubernetes cluster has static outbound and inbound IPs which make it easy to whitelist these addresses in any external infrastructures.

Kubernetes cluster got an Nginx-based ingress bound to public static inbound IP. It also got installed Container Storage Interface (CSI) driver for Azure Key Vault. This is in particular useful for ingestion of certificates and secrets such as login credentials for Elasticsearch.