This article explains how to create an Azure Kubernetes Service (AKS) cluster suitable for running Cloudmersive Private Cloud.
Two deployment options are provided:
- Store application credentials as standard Kubernetes Secrets. This is the default and simplest configuration.
- Store application credentials in Azure Key Vault and expose them through the Azure Key Vault Provider for Secrets Store CSI Driver.
The resulting cluster contains:
- A Linux system node pool for Kubernetes system components and the Cloudmersive NGINX router.
- A Windows user node pool for the Cloudmersive API services.
- Azure CNI networking.
- The Azure network dataplane rather than Cilium.
- A Standard Azure Load Balancer.
- Automatic node-image updates.
- Cluster autoscaling on both node pools.
- Windows Server 2022 worker nodes.
The Linux system pool is configured to autoscale from two to five nodes. Current AKS requirements specify that a system pool must contain at least two nodes.
The Windows user pool is configured to autoscale from one to five nodes.
Windows node size options
Each Windows node must have at least 16 GiB of memory.
The following sizes are suitable starting points:
Standard_E2s_v5 provides 2 vCPUs and 16 GiB of memory. This is the minimum option and is intended for evaluation, development, or low-volume workloads.
Standard_E4s_v5 provides 4 vCPUs and 32 GiB of memory. This is the recommended default for most deployments.
Standard_E8s_v5 provides 8 vCPUs and 64 GiB of memory. Use this option for higher concurrency or greater processing capacity.
The examples in this article use Standard_E4s_v5.
Microsoft documents the Esv5 sizes as providing 16 GiB, 32 GiB, and 64 GiB of memory for Standard_E2s_v5, Standard_E4s_v5, and Standard_E8s_v5, respectively.
Windows Server 2022 uses a Generation 1 AKS node image by default. The Esv5 sizes used in this article are compatible with that configuration, so the Generation 2 custom header is not required.
Autoscaling configuration
The AKS cluster autoscaler monitors for pods that cannot be scheduled because a node pool lacks resources. It can add nodes when additional capacity is needed and remove underutilized nodes when the workloads can be safely rescheduled. Autoscaling is configured independently for each node pool.
This article uses the following limits:
- Linux system pool: minimum two nodes and maximum five nodes.
- Windows user pool: minimum one node and maximum five nodes.
Do not configure autoscaling directly on the Azure Virtual Machine Scale Sets created by AKS. Allow the AKS cluster autoscaler to manage them.
Windows administrator credentials
The commands in this article do not ask the customer to select, record, or manage a Windows administrator password.
With the current Azure CLI behavior, when Windows administrator credentials are omitted, Azure uses azureuser as the username and generates a random password. The credentials are not required for routine Kubernetes management or node patching.
Customers normally manage the cluster through Azure and Kubernetes rather than logging directly into the worker nodes.
If break-glass access is ever required, the Windows administrator password can be changed later using az aks update.
Use Azure CLI version 2.87.0 or later. Older Azure CLI versions might not provide the same default Windows-profile behavior.
Windows Server 2022 compatibility
Windows Server 2022 is supported on AKS Kubernetes versions earlier than 1.37. It is not supported on Kubernetes version 1.37 or later, and Microsoft plans to end AKS support for Windows Server 2022 node pools on June 30, 2028.
Before creating the cluster, verify that the selected Kubernetes version supports Windows Server 2022.
Prerequisites
Before beginning, you need:
- An active Azure subscription.
- Permission to create resource groups, AKS clusters, managed identities, role assignments, and Azure Key Vault resources when applicable.
- Azure CLI version 2.87.0 or later.
- Sufficient regional quota for the selected Windows virtual-machine size.
- Access to Azure Cloud Shell or another Bash environment containing Azure CLI and
kubectl.
Azure Cloud Shell already contains Azure CLI and kubectl.
Sign in to Azure:
az login
Select the correct Azure subscription:
az account set --subscription "<subscription-name-or-id>"
Confirm the selected subscription:
az account show --output table
Option 1: Create the Cluster Without Azure Key Vault
Use this procedure when Cloudmersive application credentials will be stored as standard Kubernetes Secrets.
This is the default deployment model.
Step 1: Configure the deployment variables
Change the values as required for your environment:
RESOURCE_GROUP="rg-cloudmersive-aks"
CLUSTER_NAME="aks-cloudmersive"
LOCATION="eastus"
KUBERNETES_VERSION="1.36"
SYSTEM_POOL_NAME="systempool"
SYSTEM_POOL_MIN_COUNT="2"
SYSTEM_POOL_MAX_COUNT="5"
WINDOWS_POOL_NAME="winapi"
WINDOWS_VM_SIZE="Standard_E4s_v5"
WINDOWS_POOL_MIN_COUNT="1"
WINDOWS_POOL_MAX_COUNT="5"
TAG_NAME="Application"
TAG_VALUE="CloudmersivePrivateCloud"
The Windows node-pool name must:
- Contain only lowercase letters and numbers.
- Begin with a lowercase letter.
- Be no longer than six characters.
If the Azure tenant requires a different resource tag, replace TAG_NAME and TAG_VALUE with the required values.
Step 2: Confirm Kubernetes-version availability
List the Kubernetes versions available in the selected region:
az aks get-versions --location "$LOCATION" --output table
Confirm that the value configured in KUBERNETES_VERSION is available.
Windows Server 2022 cannot be used with Kubernetes version 1.37 or later.
Step 3: Confirm Windows VM-size availability
Check whether the selected Windows VM size is available in the intended region:
az vm list-skus --location "$LOCATION" --size "$WINDOWS_VM_SIZE" --all --output table
Review the output for regional restrictions.
You can also list the VM sizes AKS recognizes in the selected region:
az aks list-vm-skus --location "$LOCATION" --output table
Step 4: Create the resource group
az group create --name "$RESOURCE_GROUP" --location "$LOCATION" --tags "$TAG_NAME=$TAG_VALUE"
Step 5: Create the AKS cluster
The initial node pool is a Linux system node pool.
The Linux system pool hosts Kubernetes system components and the small Cloudmersive NGINX router pod. AKS requires the cluster to be created with a Linux system pool before a Windows user pool is added.
The command creates the cluster with:
- Azure CNI networking.
- The Azure network dataplane.
- A Standard Azure Load Balancer.
- Virtual Machine Scale Sets.
- Managed identity.
- Node-image automatic upgrades.
- A Linux system pool that autoscale from two to five nodes.
- Resource tags on the AKS cluster and the initial node pool.
az aks create --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --location "$LOCATION" --kubernetes-version "$KUBERNETES_VERSION" --enable-managed-identity --vm-set-type VirtualMachineScaleSets --load-balancer-sku standard --network-plugin azure --network-dataplane azure --nodepool-name "$SYSTEM_POOL_NAME" --node-count "$SYSTEM_POOL_MIN_COUNT" --enable-cluster-autoscaler --min-count "$SYSTEM_POOL_MIN_COUNT" --max-count "$SYSTEM_POOL_MAX_COUNT" --os-sku Ubuntu --node-os-upgrade-channel NodeImage --tags "$TAG_NAME=$TAG_VALUE" --nodepool-tags "$TAG_NAME=$TAG_VALUE" --generate-ssh-keys
The NodeImage channel allows AKS to apply updated, AKS-tested node images containing operating-system security and reliability fixes. NodeImage is also the current default for newly created AKS Standard clusters, but it is specified explicitly so the intended patching configuration is clear.
Step 6: Add the Windows Server 2022 node pool
az aks nodepool add --resource-group "$RESOURCE_GROUP" --cluster-name "$CLUSTER_NAME" --name "$WINDOWS_POOL_NAME" --mode User --os-type Windows --os-sku Windows2022 --node-vm-size "$WINDOWS_VM_SIZE" --node-count "$WINDOWS_POOL_MIN_COUNT" --enable-cluster-autoscaler --min-count "$WINDOWS_POOL_MIN_COUNT" --max-count "$WINDOWS_POOL_MAX_COUNT" --tags "$TAG_NAME=$TAG_VALUE"
The Windows pool is created with:
- Node-pool mode
User.
- Windows Server 2022.
- One initial node.
- A minimum of one node.
- A maximum of five nodes.
Standard_E4s_v5 as the default VM size.
- 4 vCPUs and 32 GiB of memory per node.
To use the minimum 16 GiB option, change the variable before creating the node pool:
WINDOWS_VM_SIZE="Standard_E2s_v5"
To use the 64 GiB option, change it to:
WINDOWS_VM_SIZE="Standard_E8s_v5"
The VM size of an existing AKS node pool cannot be changed in place. To move to another VM size later, create a new node pool, move the workloads, and then remove the old pool.
Step 7: Connect to the cluster
Download the Kubernetes credentials:
az aks get-credentials --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --overwrite-existing
Step 8: Verify the node pools
List the node pools and their autoscaling configuration:
az aks nodepool list --resource-group "$RESOURCE_GROUP" --cluster-name "$CLUSTER_NAME" --query "[].{Name:name,Mode:mode,OS:osType,OSSku:osSKU,VMSize:vmSize,Autoscaling:enableAutoScaling,Minimum:minCount,Maximum:maxCount,Current:count}" --output table
Confirm that:
- The Linux system pool has autoscaling enabled with a minimum of two and maximum of five.
- The Windows user pool has autoscaling enabled with a minimum of one and maximum of five.
- The Windows pool uses Windows Server 2022.
- The Windows pool uses the selected VM size.
Verify the Kubernetes nodes:
kubectl get nodes -L kubernetes.io/os,kubernetes.azure.com/mode
The output should show Linux system nodes and at least one Windows user node.
Verify the node OS upgrade channel:
az aks show --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --query autoUpgradeProfile.nodeOSUpgradeChannel --output tsv
The expected result is:
NodeImage
Cloudmersive application credentials can now be supplied during the Helm deployment as standard Kubernetes Secrets.
Option 2: Create the Cluster With Azure Key Vault
Use this procedure when Cloudmersive application credentials must be stored in Azure Key Vault rather than directly as Kubernetes Secrets.
The Azure Key Vault Provider for Secrets Store CSI Driver supports Windows containers and can mount Key Vault secrets into pods through CSI volumes.
Step 1: Configure the deployment variables
Change the values as required:
RESOURCE_GROUP="rg-cloudmersive-aks"
CLUSTER_NAME="aks-cloudmersive"
LOCATION="eastus"
KUBERNETES_VERSION="1.36"
SYSTEM_POOL_NAME="systempool"
SYSTEM_POOL_MIN_COUNT="2"
SYSTEM_POOL_MAX_COUNT="5"
WINDOWS_POOL_NAME="winapi"
WINDOWS_VM_SIZE="Standard_E4s_v5"
WINDOWS_POOL_MIN_COUNT="1"
WINDOWS_POOL_MAX_COUNT="5"
KEY_VAULT_NAME="cmx-kv-123456"
TAG_NAME="Application"
TAG_VALUE="CloudmersivePrivateCloud"
Azure Key Vault names must be globally unique, between 3 and 24 characters, and contain only supported alphanumeric characters and hyphens.
Replace cmx-kv-123456 with an available Key Vault name.
Step 2: Confirm Kubernetes-version availability
az aks get-versions --location "$LOCATION" --output table
Confirm that KUBERNETES_VERSION is available and is earlier than version 1.37.
Step 3: Confirm Windows VM-size availability
az vm list-skus --location "$LOCATION" --size "$WINDOWS_VM_SIZE" --all --output table
Step 4: Create the resource group
az group create --name "$RESOURCE_GROUP" --location "$LOCATION" --tags "$TAG_NAME=$TAG_VALUE"
Step 5: Create Azure Key Vault
Create an Azure Key Vault that uses Azure role-based access control:
az keyvault create --resource-group "$RESOURCE_GROUP" --name "$KEY_VAULT_NAME" --location "$LOCATION" --enable-rbac-authorization true --tags "$TAG_NAME=$TAG_VALUE"
Step 6: Create the AKS cluster with Key Vault support
az aks create --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --location "$LOCATION" --kubernetes-version "$KUBERNETES_VERSION" --enable-managed-identity --vm-set-type VirtualMachineScaleSets --load-balancer-sku standard --network-plugin azure --network-dataplane azure --nodepool-name "$SYSTEM_POOL_NAME" --node-count "$SYSTEM_POOL_MIN_COUNT" --enable-cluster-autoscaler --min-count "$SYSTEM_POOL_MIN_COUNT" --max-count "$SYSTEM_POOL_MAX_COUNT" --os-sku Ubuntu --node-os-upgrade-channel NodeImage --enable-addons azure-keyvault-secrets-provider --tags "$TAG_NAME=$TAG_VALUE" --nodepool-tags "$TAG_NAME=$TAG_VALUE" --generate-ssh-keys
Enabling the Key Vault provider creates a user-assigned managed identity named similarly to azurekeyvaultsecretsprovider-xxxxx in the AKS-managed node resource group. AKS automatically assigns this identity to the node Virtual Machine Scale Sets.
Step 7: Add the Windows Server 2022 node pool
az aks nodepool add --resource-group "$RESOURCE_GROUP" --cluster-name "$CLUSTER_NAME" --name "$WINDOWS_POOL_NAME" --mode User --os-type Windows --os-sku Windows2022 --node-vm-size "$WINDOWS_VM_SIZE" --node-count "$WINDOWS_POOL_MIN_COUNT" --enable-cluster-autoscaler --min-count "$WINDOWS_POOL_MIN_COUNT" --max-count "$WINDOWS_POOL_MAX_COUNT" --tags "$TAG_NAME=$TAG_VALUE"
Step 8: Obtain the Key Vault provider identity
Obtain the identity object ID:
KEYVAULT_IDENTITY_OBJECT_ID=$(az aks show --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --query "addonProfiles.azureKeyvaultSecretsProvider.identity.objectId" --output tsv)
Obtain the identity client ID:
KEYVAULT_IDENTITY_CLIENT_ID=$(az aks show --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --query "addonProfiles.azureKeyvaultSecretsProvider.identity.clientId" --output tsv)
Obtain the Key Vault resource ID:
KEY_VAULT_ID=$(az keyvault show --resource-group "$RESOURCE_GROUP" --name "$KEY_VAULT_NAME" --query id --output tsv)
Step 9: Grant access to Key Vault secrets
Assign the Key Vault Secrets User role to the Key Vault provider identity:
az role assignment create --assignee-object-id "$KEYVAULT_IDENTITY_OBJECT_ID" --assignee-principal-type ServicePrincipal --role "Key Vault Secrets User" --scope "$KEY_VAULT_ID"
The identity used by the SecretProviderClass requires the Key Vault Secrets User role to retrieve Key Vault secret objects.
Azure role assignments can take several minutes to propagate.
Display the identity client ID:
echo "$KEYVAULT_IDENTITY_CLIENT_ID"
Save this value for the Cloudmersive Helm deployment and its SecretProviderClass configuration.
Step 10: Add application secrets to Key Vault
The exact secret names depend on the Cloudmersive deployment configuration.
The following example securely prompts for a secret value:
read -s -p "Enter the secret value: " SECRET_VALUE; echo
Store the value in Key Vault:
az keyvault secret set --vault-name "$KEY_VAULT_NAME" --name "CloudmersiveExampleSecret" --value "$SECRET_VALUE"
Remove the secret from the shell environment:
unset SECRET_VALUE
Repeat these commands for each required Cloudmersive application secret.
Enabling the Key Vault provider prepares the cluster to retrieve secrets, but it does not automatically connect every Key Vault secret to the Cloudmersive deployment.
The Cloudmersive Kubernetes deployment must also include:
- A
SecretProviderClass.
- The Key Vault name.
- The Azure tenant ID.
- The Key Vault provider identity client ID.
- The names of the secrets to retrieve.
- A CSI volume and volume mount.
Step 11: Connect to the cluster
az aks get-credentials --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --overwrite-existing
Step 12: Verify the configuration
List the node pools:
az aks nodepool list --resource-group "$RESOURCE_GROUP" --cluster-name "$CLUSTER_NAME" --query "[].{Name:name,Mode:mode,OS:osType,OSSku:osSKU,VMSize:vmSize,Autoscaling:enableAutoScaling,Minimum:minCount,Maximum:maxCount,Current:count}" --output table
Verify the Kubernetes nodes:
kubectl get nodes -L kubernetes.io/os,kubernetes.azure.com/mode
Verify that the Azure Key Vault provider is enabled:
az aks show --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --query "addonProfiles.azureKeyvaultSecretsProvider.enabled" --output tsv
The expected result is:
true
Verify the Key Vault CSI pods:
kubectl get pods -n kube-system -l 'app in (secrets-store-csi-driver,secrets-store-provider-azure)' -o wide
Verify the node OS upgrade channel:
az aks show --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --query autoUpgradeProfile.nodeOSUpgradeChannel --output tsv
The expected result is:
NodeImage
Add the Windows Node Pool to an Existing AKS Cluster
An existing AKS cluster can be used only if it is compatible with Windows Server node pools.
The cluster must:
- Use Azure CNI networking.
- Use a Standard Azure Load Balancer.
- Use Virtual Machine Scale Sets.
- Contain a Linux system node pool.
- Support Windows node pools.
- Run a Kubernetes version earlier than 1.37 for Windows Server 2022.
Microsoft notes that a cluster created without Windows support might not have the required Windows profile and might need to be recreated before a Windows node pool can be added.
Step 1: Configure the existing cluster variables
RESOURCE_GROUP="<existing-resource-group>"
CLUSTER_NAME="<existing-cluster-name>"
SYSTEM_POOL_NAME="<existing-system-pool-name>"
WINDOWS_POOL_NAME="winapi"
WINDOWS_VM_SIZE="Standard_E4s_v5"
TAG_NAME="Application"
TAG_VALUE="CloudmersivePrivateCloud"
Step 2: Check the cluster configuration
az aks show --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --query "{KubernetesVersion:kubernetesVersion,NetworkPlugin:networkProfile.networkPlugin,NetworkDataplane:networkProfile.networkDataplane,LoadBalancerSku:networkProfile.loadBalancerSku,VMSetType:agentPoolProfiles[0].type,WindowsAdministrator:windowsProfile.adminUsername}" --output table
Confirm that:
NetworkPlugin is azure.
NetworkDataplane is azure or empty because Azure is the default.
LoadBalancerSku is standard.
- The pool type is
VirtualMachineScaleSets.
- The Kubernetes version is earlier than 1.37.
If adding the Windows pool reports that the Windows profile is missing, recreate the cluster using one of the preceding procedures.
Step 3: Enable autoscaling on the existing system pool
Current AKS requirements specify at least two nodes for a system pool, so configure the existing system pool with a minimum of two and maximum of five.
az aks nodepool update --resource-group "$RESOURCE_GROUP" --cluster-name "$CLUSTER_NAME" --name "$SYSTEM_POOL_NAME" --enable-cluster-autoscaler --min-count 2 --max-count 5
If autoscaling is already enabled, update the range with:
az aks nodepool update --resource-group "$RESOURCE_GROUP" --cluster-name "$CLUSTER_NAME" --name "$SYSTEM_POOL_NAME" --update-cluster-autoscaler --min-count 2 --max-count 5
Step 4: Add the Windows node pool
az aks nodepool add --resource-group "$RESOURCE_GROUP" --cluster-name "$CLUSTER_NAME" --name "$WINDOWS_POOL_NAME" --mode User --os-type Windows --os-sku Windows2022 --node-vm-size "$WINDOWS_VM_SIZE" --node-count 1 --enable-cluster-autoscaler --min-count 1 --max-count 5 --tags "$TAG_NAME=$TAG_VALUE"
Step 5: Enable node-image updates
Check the current node OS upgrade channel:
az aks show --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --query autoUpgradeProfile.nodeOSUpgradeChannel --output tsv
If it is not already set to NodeImage, update it:
az aks update --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --node-os-upgrade-channel NodeImage
Step 6: Verify both node pools
az aks nodepool list --resource-group "$RESOURCE_GROUP" --cluster-name "$CLUSTER_NAME" --query "[].{Name:name,Mode:mode,OS:osType,Autoscaling:enableAutoScaling,Minimum:minCount,Maximum:maxCount,Current:count}" --output table
Enable Azure Key Vault on an Existing Compatible Cluster
Configure the Key Vault name:
KEY_VAULT_NAME="<existing-key-vault-name>"
Enable the Azure Key Vault Secrets Store CSI Driver:
az aks enable-addons --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --addons azure-keyvault-secrets-provider
Obtain the identity object ID:
KEYVAULT_IDENTITY_OBJECT_ID=$(az aks show --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --query "addonProfiles.azureKeyvaultSecretsProvider.identity.objectId" --output tsv)
Obtain the identity client ID:
KEYVAULT_IDENTITY_CLIENT_ID=$(az aks show --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME" --query "addonProfiles.azureKeyvaultSecretsProvider.identity.clientId" --output tsv)
Obtain the Key Vault resource ID:
KEY_VAULT_ID=$(az keyvault show --name "$KEY_VAULT_NAME" --query id --output tsv)
Assign the Key Vault Secrets User role:
az role assignment create --assignee-object-id "$KEYVAULT_IDENTITY_OBJECT_ID" --assignee-principal-type ServicePrincipal --role "Key Vault Secrets User" --scope "$KEY_VAULT_ID"
Display the client ID required by the Kubernetes SecretProviderClass:
echo "$KEYVAULT_IDENTITY_CLIENT_ID"
Configure Outbound Internet Access
The AKS nodes and Cloudmersive workloads require outbound HTTPS access over TCP port 443.
If outbound traffic is filtered through Azure Firewall, a network virtual appliance, an HTTP proxy, or another security appliance, allow the Microsoft endpoints required by the AKS features enabled on the cluster.
Blocking required endpoints can prevent:
- Node provisioning.
- Container-image downloads.
- Cluster upgrades.
- Node-image updates.
- Cloudmersive licensing and management.
- Cloudmersive virus-definition updates.
- Normal cluster maintenance.
Allow outbound HTTPS access to the following Cloudmersive endpoints:
cloudmersive.com
account.cloudmersive.com
portal.cloudmersive.com
servicecore.cloudmersive.com
servicecoredr.cloudmersive.com
management.cloudmersive.com
appsapi.cloudmersive.com
virusdefinitions.cloudmersive.com
privatecloud.cloudmersive.com
diagnostics.cloudmersive.com
notification.cloudmersive.com
notify.cloudmersive.com
Allow outbound HTTPS access to the following container-registry and supporting endpoints:
927861292015.dkr.ecr.us-east-1.amazonaws.com
ecr.us-east-1.amazonaws.com
api.ecr.us-east-1.amazonaws.com
prod-us-east-1-starport-layer-bucket.s3.us-east-1.amazonaws.com
mcr.microsoft.com
eastus.data.mcr.microsoft.com
download.microsoft.com
onegetcdn.azureedge.net
go.microsoft.com
These endpoints are included in the current Cloudmersive Private Cloud outbound allow-list.
The applicable Microsoft Container Registry data endpoint can vary according to the Azure region.
Use FQDN-based outbound firewall rules because the underlying IP addresses can change.
Final Configuration Checklist
After completing either deployment procedure, confirm that the cluster has:
- A Linux node pool in
System mode.
- A system-pool autoscaling range of two to five nodes.
- A Windows node pool in
User mode.
- A Windows-pool autoscaling range of one to five nodes.
- Windows Server 2022 on the Windows node pool.
- At least 16 GiB of memory on each Windows node.
Standard_E4s_v5 with 32 GiB as the recommended default.
- Azure CNI networking.
- The Azure network dataplane rather than Cilium.
- A Standard Azure Load Balancer.
- Virtual Machine Scale Sets.
- Managed identity enabled.
- The
NodeImage node OS upgrade channel.
- Required Azure resource tags.
- Outbound TCP port 443 access to the required Microsoft and Cloudmersive endpoints.
- Either standard Kubernetes Secrets or Azure Key Vault configured for application credentials.