Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
---
title: Prepare the Infrastructure for Deploying Kafka on Azure Kubernetes Service (AKS)
description: In this article, you prepare the infrastructure for deploying a Kafka cluster on Azure Kubernetes Service (AKS) using the Strimzi Operator.
ms.topic: how-to
ms.service: azure-kubernetes-service
ms.date: 09/15/2025
author: carols
ms.author: carols
zone_pivot_groups: azure-cli-or-terraform
ms.custom: 'stateful-workloads'
# Customer intent: As a cloud architect, I want to prepare the infrastructure for deploying a Kafka cluster on Azure Kubernetes Service, so that I can ensure high availability and efficient resource management for my data workloads.
---
# Prepare the infrastructure for deploying Kafka on Azure Kubernetes Service (AKS)
In this article, you prepare the infrastructure for deploying a Kafka cluster on Azure Kubernetes Service (AKS).
## Architecture overview
The target AKS architecture for Kafka deployment prioritizes high availability through a comprehensive zone-redundant design. The design requires three node poolsโone per availability zoneโto maintain workload distribution and storage alignment. This zonal configuration is critical because persistent volumes in this architecture have zonal affinity. Any new nodes that are provisioned with cluster autoscaler must be created in the appropriate zone. Without this zonal specificity, pods with zone-bound persistent volumes would remain in a pending state. Multiple replicas of the Strimzi Cluster Operator and Kafka broker instances are defined and distributed across zones, providing resilience against both node and entire zone failures within the target region. To prevent resource contention and ensure predictable performance, dedicated node pools for Kafka workloads are strongly recommended.
## Prerequisites
- If you haven't already, review the [Overview for deploying Kafka on Azure Kubernetes Service (AKS) using Strimzi](./kafka-overview.md).
- Terraform v1.3.0 or later installed.
- Azure CLI installed and authenticated.
- Sufficient permissions to create infrastructure resources and assign RBAC to managed identities: Network Contributor, Azure Kubernetes Service Contributor, and Role Based Access Control Administrator.
## Deploy infrastructure
The following steps guide you through deploying the AKS cluster and supporting infrastructure needed for your Kafka deployment.
> [!TIP]
> **If you have an existing AKS cluster or existing supporting infrastructure**: You can skip the full deployment steps or make code adjustments, but ensure your infrastructure and AKS cluster meets the following requirements:
>
> - Virtual network with subnet for nodes.
> - Azure Disk CSI driver enabled on the AKS cluster (enabled by default).
> - Node pool per availability zone (1, 2, and 3).
> - Dedicated node pools for Kafka with [appropriate VM sizes](./kafka-overview.md#node-pools) based on your workload's requirements.
> - Azure Managed Prometheus and Azure Managed Grafana configured.
::: zone pivot="azure-cli"
### Set environment variables
- Before running any CLI commands, set the following environment variables to use throughout this guide with values that meet your requirements:
```azurecli-interactive
export RESOURCE_GROUP_NAME="rg-kafka"
export LOCATION="canadacentral"
export VNET_NAME="vnet-aks-kafka"
export SUBNET_NAME="node-subnet"
export AKS_CLUSTER_NAME="aks-kafka-cluster"
export AKS_TIER=standard
export NAT_GATEWAY_NAME="nat-kafka"
export ADDRESS_SPACE="10.31.0.0/20"
export SUBNET_PREFIX="10.31.0.0/21"
export SYSTEM_NODE_COUNT_MIN=3
export SYSTEM_NODE_COUNT_MAX=6
export SYSTEM_NODE_VM_SIZE="Standard_D4ds_v5"
export KAFKA_NODE_COUNT_MIN=1
export KAFKA_NODE_COUNT_MAX=3
export KAFKA_NODE_COUNT=1
export KAFKA_NODE_VM_SIZE="Standard_D16ds_v5"
export LOG_ANALYTICS_WORKSPACE_NAME="law-monitoring"
export DIAGNOSTIC_SETTINGS_NAME="aks-diagnostic-settings"
export ACR_NAME="aksacr123"
export ACR_SKU="Premium"
export USER_ASSIGNED_IDENTITY_NAME="uami-aks"
export KUBERNETES_VERSION="1.30.0"
export AAD_ADMIN_GROUP_OBJECT_IDS="<your-admin-group-object-id>"
export AAD_TENANT_ID="<your-tenant-id>"
export GRAFANA_NAME="grafana-kafka-aks"
export PROMETHEUS_WORKSPACE_NAME="prometheus-aks"
```
### Pre-cluster network deployments
Before deploying the AKS cluster for Kafka, deploy the prerequisite network resources that support the AKS cluster deployment.
1. Create a resource group using the [`az group create`](/cli/azure/group#az-group-create) command.
```azurecli-interactive
az group create --name $RESOURCE_GROUP_NAME --location $LOCATION
```
1. Create a virtual network using the [`az network vnet create`](/cli/azure/network/vnet#az-network-vnet-create) command.
```azurecli-interactive
az network vnet create \
--resource-group $RESOURCE_GROUP_NAME \
--name $VNET_NAME \
--address-prefix $ADDRESS_SPACE \
--location $LOCATION
```
1. Create a subnet using the [`az network vnet subnet create`](/cli/azure/network/vnet/subnet#az-network-vnet-subnet-create) command.
```azurecli-interactive
az network vnet subnet create \
--resource-group $RESOURCE_GROUP_NAME \
--vnet-name $VNET_NAME \
--name $SUBNET_NAME \
--address-prefix $SUBNET_PREFIX
```
1. Create a public IP for the NAT Gateway using the [`az network public-ip create`](/cli/azure/network/public-ip#az-network-public-ip-create) command.
```azurecli-interactive
az network public-ip create \
--resource-group $RESOURCE_GROUP_NAME \
--name ${NAT_GATEWAY_NAME}-public-ip \
--sku Standard \
--location $LOCATION
```
1. Create a NAT Gateway using the [`az network nat gateway create`](/cli/azure/network/nat/gateway#az-network-nat-gateway-create) command.
```azurecli-interactive
az network nat gateway create \
--resource-group $RESOURCE_GROUP_NAME \
--name $NAT_GATEWAY_NAME \
--public-ip-addresses ${NAT_GATEWAY_NAME}-public-ip \
--location $LOCATION
```
1. Associate the NAT Gateway to the node subnet using [`az network vnet subnet update`](/cli/azure/network/vnet/subnet#az-network-vnet-subnet-update) command.
```azurecli-interactive
az network vnet subnet update \
--resource-group $RESOURCE_GROUP_NAME \
--vnet-name $VNET_NAME \
--name $SUBNET_NAME \
--nat-gateway $NAT_GATEWAY_NAME
```
### Pre-cluster monitoring and governance deployments
Before deploying the AKS cluster for Kafka, deploy the prerequisite monitoring and governance resources that support the AKS cluster deployment.
1. Create a log analytics workspace using the [`az monitor log-analytics workspace create`](/cli/azure/monitor/log-analytics/workspace#az-monitor-log-analytics-workspace-create) command.
```azurecli-interactive
az monitor log-analytics workspace create \
--resource-group $RESOURCE_GROUP_NAME \
--workspace-name $LOG_ANALYTICS_WORKSPACE_NAME \
--location $LOCATION
```
1. Create an Azure monitor workspace for Prometheus using the [`az monitor account create`](/cli/azure/monitor/account#az-monitor-account-create) command.
```azurecli-interactive
az monitor account create \
--resource-group $RESOURCE_GROUP_NAME \
--name $PROMETHEUS_WORKSPACE_NAME \
--location $LOCATION
```
1. Create an Azure managed Grafana instance using the [`az grafana create`](/cli/azure/grafana#az-grafana-create) command.
```azurecli-interactive
az grafana create \
--resource-group $RESOURCE_GROUP_NAME \
--name $GRAFANA_NAME \
--location $LOCATION \
--api-key Enabled \
--deterministic-outbound-ip Enabled \
--public-network-access Enabled \
--grafana-major-version 11
```
> [!NOTE]
> Azure Managed Grafana has zone redundancy available in [select regions](/azure/managed-grafana/high-availability#supported-regions). If your target region has zone redundancy, use the `--zone-redundancy Enabled` argument.
1. Create an Azure container registry using the [`az acr create`](/cli/azure/acr#az-acr-create) command.
```azurecli-interactive
az acr create \
--resource-group $RESOURCE_GROUP_NAME \
--name $ACR_NAME \
--sku $ACR_SKU \
--location $LOCATION \
--admin-enabled false \
--zone-redundancy Enabled
```
1. Create a user-assigned managed identity using the [`az identity create`](/cli/azure/identity#az-identity-create) command.
```azurecli-interactive
az identity create \
--resource-group $RESOURCE_GROUP_NAME \
--name $USER_ASSIGNED_IDENTITY_NAME \
--location $LOCATION
```
1. Assign RBAC permissions to the managed identity of the Grafana instance using the [`az role assignment create`](/cli/azure/role/assignment#az-role-assignment-create) command.
```azurecli-interactive
az role assignment create \
--assignee $(az grafana show --resource-group $RESOURCE_GROUP_NAME --name $GRAFANA_NAME --query identity.principalId -o tsv) \
--role "Monitoring Reader" --scope $(az group show --name $RESOURCE_GROUP_NAME --query id -o tsv)
```
### AKS cluster deployment
Deploy the AKS cluster with dedicated node pools for Kafka per availability zone using Azure CLI.
1. Assign the network contributor role to the user-assigned managed identity for AKS using the [`az role assignment create`](/cli/azure/role/assignment#az-role-assignment-create) command.
```azurecli-interactive
az role assignment create \
--assignee $(az identity show --resource-group $RESOURCE_GROUP_NAME --name $USER_ASSIGNED_IDENTITY_NAME --query principalId -o tsv) \
--role "Network Contributor" \
--scope $(az group show --name $RESOURCE_GROUP_NAME --query id -o tsv)
```
1. Create an AKS cluster using the [`az aks create`](/cli/azure/aks#az-aks-create) command.
```azurecli-interactive
az aks create \
--name $AKS_CLUSTER_NAME \
--aad-admin-group-object-ids $AAD_ADMIN_GROUP_OBJECT_IDS \
--aad-tenant-id $AAD_TENANT_ID \
--assign-identity $(az identity show --resource-group $RESOURCE_GROUP_NAME --name $USER_ASSIGNED_IDENTITY_NAME --query id -o tsv) \
--attach-acr $(az acr show --resource-group $RESOURCE_GROUP_NAME --name $ACR_NAME --query id -o tsv) \
--auto-upgrade-channel patch \
--enable-aad \
--enable-addons monitoring \
--enable-azure-monitor-metrics \
--enable-cluster-autoscaler \
--enable-managed-identity \
--enable-oidc-issuer \
--enable-workload-identity \
--kubernetes-version $KUBERNETES_VERSION \
--load-balancer-sku standard \
--location $LOCATION \
--max-count $SYSTEM_NODE_COUNT_MAX \
--max-pods 110 \
--min-count $SYSTEM_NODE_COUNT_MIN \
--network-dataplane cilium \
--network-plugin azure \
--network-plugin-mode overlay \
--network-policy cilium \
--node-osdisk-type Ephemeral \
--node-os-upgrade-channel NodeImage \
--node-vm-size $SYSTEM_NODE_VM_SIZE \
--nodepool-labels "role=system" \
--nodepool-name systempool \
--nodepool-tags "env=production" \
--os-sku AzureLinux \
--outbound-type userAssignedNATGateway \
--pod-cidr 10.244.0.0/16 \
--resource-group $RESOURCE_GROUP_NAME \
--tags "env=production" \
--tier $AKS_TIER \
--vnet-subnet-id $(az network vnet subnet show --resource-group $RESOURCE_GROUP_NAME --vnet-name $VNET_NAME --name $SUBNET_NAME --query id -o tsv) \
--workspace-resource-id $(az monitor log-analytics workspace show --resource-group $RESOURCE_GROUP_NAME --workspace-name $LOG_ANALYTICS_WORKSPACE_NAME --query id -o tsv) \
--zones 1 2 3
```
1. Create an additional node pool per availability zone using a for loop and the [`az aks nodepool add`](/cli/azure/aks/nodepool#az-aks-nodepool-add) command.
```azurecli-interactive
for zone in 1 2 3; do
az aks nodepool add \
--cluster-name $AKS_CLUSTER_NAME \
--enable-cluster-autoscaler \
--labels app=kafka \
--max-count $KAFKA_NODE_COUNT_MAX \
--max-surge 10% \
--min-count $KAFKA_NODE_COUNT_MIN \
--node-count $KAFKA_NODE_COUNT \
--mode User \
--name "kafka$zone" \
--node-osdisk-type Ephemeral \
--node-vm-size $KAFKA_NODE_VM_SIZE \
--os-sku AzureLinux \
--resource-group $RESOURCE_GROUP_NAME \
--vnet-subnet-id $(az network vnet subnet show --resource-group $RESOURCE_GROUP_NAME --vnet-name $VNET_NAME --name $SUBNET_NAME --query id -o tsv) \
--zones $zone
done
```
1. Enable Azure Managed Prometheus and Grafana integration using the [`az aks update`](/cli/azure/aks#az-aks-update) command.
```azurecli-interactive
az aks update \
--name $AKS_CLUSTER_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--enable-azure-monitor-metrics \
--azure-monitor-workspace-resource-id $(az monitor account show --resource-group $RESOURCE_GROUP_NAME --name $PROMETHEUS_WORKSPACE_NAME --query id -o tsv) \
--grafana-resource-id $(az grafana show --resource-group $RESOURCE_GROUP_NAME --name $GRAFANA_NAME --query id -o tsv)
```
1. **Optional**: Configure diagnostic setting for the AKS cluster using the [`az monitor diagnostic-settings create`](/cli/azure/monitor/diagnostic-settings#az-monitor-diagnostic-settings-create) command.
```azurecli-interactive
az monitor diagnostic-settings create \
--resource $(az aks show --resource-group $RESOURCE_GROUP_NAME --name $AKS_CLUSTER_NAME --query id -o tsv) \
--name $DIAGNOSTIC_SETTINGS_NAME \
--workspace $(az monitor log-analytics workspace show --resource-group $RESOURCE_GROUP_NAME --workspace-name $LOG_ANALYTICS_WORKSPACE_NAME --query id -o tsv) \
--logs '[{"category": "kube-apiserver", "enabled": true}, {"category": "kube-audit", "enabled": true}, {"category": "kube-audit-admin", "enabled": true}, {"category": "kube-controller-manager", "enabled": true}, {"category": "kube-scheduler", "enabled": true}, {"category": "cluster-autoscaler", "enabled": true}, {"category": "cloud-controller-manager", "enabled": true}, {"category": "guard", "enabled": true}, {"category": "csi-azuredisk-controller", "enabled": true}, {"category": "csi-azurefile-controller", "enabled": true}, {"category": "csi-snapshot-controller", "enabled": true}]' \
--metrics '[{"category": "AllMetrics", "enabled": true}]'
```
::: zone-end
::: zone pivot="terraform"
In this section, you deploy an AKS cluster and supporting infrastructure resources using Terraform:
- A private AKS cluster with a node pool per availability zone using the Azure Verified Module (AVM).
- Virtual network and subnet configurations.
- NAT gateway for outbound connectivity.
- Azure Container Registry with private endpoint.
- User-assigned managed identity for AKS.
- Azure Monitor workspace for Prometheus metrics.
- Azure Managed Grafana dashboard with Prometheus integration.
- Dedicated node pools for Kafka workloads with appropriate labels.
- Azure Disk CSI driver for persistent volumes (enabled by default).
> [!NOTE]
> This Terraform deployment uses the [Azure Verified Module](https://github.com/Azure/terraform-azurerm-avm-ptn-aks-production) for a production AKS cluster. As a result, the cluster is deployed as a private cluster and with opinionated configurations. Appropriate connectivity must be in place to run the subsequent kubectl commands.
>
> To customize the module configuration to meet your needs, fork or clone the repo and update your module source reference.
1. Copy the `variables.tf` to your Terraform directory.
```tf
variable "azure_subscription_id" {
type = string
description = "The Azure subscription ID to use for the resources."
}
variable "enable_telemetry" {
type = bool
default = true
description = "This variable controls whether or not telemetry is enabled for the module."
}
variable "kubernetes_cluster_name" {
type = string
default = "kafka-cluster"
description = "The name of the Kubernetes cluster."
}
variable "kubernetes_version" {
type = string
default = "1.30"
description = "The version of Kubernetes to use for the cluster."
}
variable "resource_group_name" {
type = string
description = "The name of the resource group in which to create the resources."
}
variable "rbac_aad_admin_group_object_ids" {
type = list(string)
description = "The object IDs of the Azure AD groups that should be granted admin access to the Kubernetes cluster."
}
variable "location" {
type = string
description = "The location in which to create the resources."
}
```
1. Review the variables and create a `kafka.tfvars` as needed. Update with values that meet your requirements:
```tf
# Replace placeholder values with your actual configuration
azure_subscription_id = "00000000-0000-0000-0000-000000000000" # Replace with your actual subscription ID
location = "Canada Central"
enable_telemetry = true
kubernetes_cluster_name = "kafka-aks-cluster"
kubernetes_version = "1.30"
resource_group_name = "rg-kafka-prod"
rbac_aad_admin_group_object_ids = [
"0000-0000-0000-0000",
# Add additional admin group object IDs as needed
]
```
1. Copy the `main.tf` to your Terraform directory.
```tf
terraform {
required_version = ">= 1.3.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 4, <5"
}
}
}
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
subscription_id = var.azure_subscription_id
}
module "naming" {
source = "Azure/naming/azurerm"
version = ">= 0.3.0"
}
resource "azurerm_user_assigned_identity" "this" {
location = var.location
name = "uami-${var.kubernetes_cluster_name}"
resource_group_name = var.resource_group_name
}
data "azurerm_client_config" "current" {}
module "avm-ptn-aks-production" {
source = "github.com/Azure/terraform-azurerm-avm-ptn-aks-production"
kubernetes_version = "1.30"
enable_telemetry = var.enable_telemetry
name = var.kubernetes_cluster_name
resource_group_name = var.resource_group_name
location = var.location
default_node_pool_vm_sku = "Standard_D8ds_v5"
network = {
name = module.avm_res_network_virtualnetwork.name
resource_group_name = var.resource_group_name
node_subnet_id = module.avm_res_network_virtualnetwork.subnets["subnet"].resource_id
pod_cidr = "192.168.0.0/16"
}
acr = {
name = module.naming.container_registry.name_unique
subnet_resource_id = module.avm_res_network_virtualnetwork.subnets["private_link_subnet"].resource_id
private_dns_zone_resource_ids = [azurerm_private_dns_zone.this.id]
}
managed_identities = {
user_assigned_resource_ids = [
azurerm_user_assigned_identity.this.id
]
}
rbac_aad_tenant_id = data.azurerm_client_config.current.tenant_id
rbac_aad_admin_group_object_ids = var.rbac_aad_admin_group_object_ids
rbac_aad_azure_rbac_enabled = true
node_pools = {
kafka = {
name = "kafka"
vm_size = "Standard_D16ds_v5"
orchestrator_version = "1.30"
max_count = 3
min_count = 1
os_sku = "AzureLinux"
mode = "User"
os_disk_size_gb = 128
labels = {
"app" = "kafka"
}
}
}
}
resource "azurerm_private_dns_zone" "this" {
name = "privatelink.azurecr.io"
resource_group_name = var.resource_group_name
}
resource "azurerm_nat_gateway" "this" {
location = var.location
name = module.naming.nat_gateway.name_unique
resource_group_name = var.resource_group_name
}
resource "azurerm_public_ip" "this" {
name = module.naming.public_ip.name_unique
location = var.location
resource_group_name = var.resource_group_name
allocation_method = "Static"
sku = "Standard"
}
resource "azurerm_nat_gateway_public_ip_association" "this" {
nat_gateway_id = azurerm_nat_gateway.this.id
public_ip_address_id = azurerm_public_ip.this.id
}
module "avm_res_network_virtualnetwork" {
source = "Azure/avm-res-network-virtualnetwork/azurerm"
version = "0.7.1"
address_space = ["10.31.0.0/16"]
location = var.location
name = "vnet-aks-lab"
resource_group_name = var.resource_group_name
subnets = {
"subnet" = {
name = "nodecidr"
address_prefixes = ["10.31.0.0/17"]
nat_gateway = {
id = azurerm_nat_gateway.this.id
}
private_link_service_network_policies_enabled = false
}
"private_link_subnet" = {
name = "private_link_subnet"
address_prefixes = ["10.31.129.0/24"]
}
}
}
resource "azurerm_monitor_workspace" "this" {
name = "prometheus-aks"
location = var.location
resource_group_name = var.resource_group_name
}
resource "azurerm_monitor_data_collection_endpoint" "dataCollectionEndpoint" {
name = "prom-aks-endpoint"
location = var.location
resource_group_name = var.resource_group_name
kind = "Linux"
}
resource "azurerm_monitor_data_collection_rule" "dataCollectionRule" {
name = "prom-aks-dcr"
location = var.location
resource_group_name = var.resource_group_name
data_collection_endpoint_id = azurerm_monitor_data_collection_endpoint.dataCollectionEndpoint.id
kind = "Linux"
description = "DCR for Azure Monitor Metrics Profile (Managed Prometheus)"
destinations {
monitor_account {
monitor_account_id = azurerm_monitor_workspace.this.id
name = "PrometheusAzMonitorAccount"
}
}
data_flow {
streams = ["Microsoft-PrometheusMetrics"]
destinations = ["PrometheusAzMonitorAccount"]
}
data_sources {
prometheus_forwarder {
streams = ["Microsoft-PrometheusMetrics"]
name = "PrometheusDataSource"
}
}
}
resource "azurerm_monitor_data_collection_rule_association" "dataCollectionRuleAssociation" {
name = "prom-aks-dcra"
target_resource_id = module.avm-ptn-aks-production.resource_id
data_collection_rule_id = azurerm_monitor_data_collection_rule.dataCollectionRule.id
description = "Association of data collection rule. Deleting this association will break the data collection for this AKS Cluster."
}
resource "azurerm_dashboard_grafana" "this" {
name = "grafana-kafka-aks"
location = var.location
resource_group_name = var.resource_group_name
api_key_enabled = true
deterministic_outbound_ip_enabled = true
public_network_access_enabled = true
grafana_major_version = 11
azure_monitor_workspace_integrations {
resource_id = azurerm_monitor_workspace.this.id
}
identity {
type = "SystemAssigned"
}
}
data "azurerm_resource_group" "current" {
name = var.resource_group_name
depends_on = [azurerm_dashboard_grafana.this]
}
resource "azurerm_role_assignment" "grafana_monitoring_reader" {
scope = data.azurerm_resource_group.current.id
role_definition_name = "Monitoring Reader"
principal_id = azurerm_dashboard_grafana.this.identity[0].principal_id
skip_service_principal_aad_check = true
}
resource "azurerm_kubernetes_cluster_extension" "container_storage" {
name = "microsoft-azurecontainerstorage"
cluster_id = module.avm-ptn-aks-production.resource_id
extension_type = "microsoft.azurecontainerstorage"
configuration_settings = {
"enable-azure-container-storage" : "azureDisk",
}
}
```
1. Initialize Terraform using the `terraform init` command.
```bash
terraform init
```
1. Create a deployment plan using the `terraform plan` command.
```bash
terraform plan -var-file="kafka.tfvars"
```
1. Apply the configuration using the `terraform apply` command.
```bash
terraform apply -var-file="kafka.tfvars"
```
::: zone-end
## Validate deployment and connect to cluster
After deploying your AKS cluster, use the following steps to validate the deployment and connect to the AKS API server.
1. Verify the deployment of the AKS cluster using the [`az aks show`](/cli/azure/aks#az-aks-show) command.
```azurecli-interactive
az aks show --resource-group $RESOURCE_GROUP_NAME --name $AKS_CLUSTER_NAME --output table
```
1. After verifying the deployment, connect to your AKS cluster using the [`az aks get-credentials`](/cli/azure/aks#az-aks-get-credentials) command.
```azurecli-interactive
az aks get-credentials --resource-group $RESOURCE_GROUP_NAME --name $AKS_CLUSTER_NAME
```
1. Verify connectivity by listing nodes using the `kubectl get` command.
```bash
kubectl get nodes
```
## Create storage class for Kafka
- Create a storage class for Premium SSD v2 disks using the `kubectl apply` command.
```bash
kubectl apply -f - <<EOF
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: kafka-premium-ssd-v2
provisioner: disk.csi.azure.com
parameters:
skuName: PremiumV2_LRS
diskIOPSReadWrite: "5000"
diskMBpsReadWrite: "200"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
EOF
```
> [!IMPORTANT]
> The storage configuration above represents a starting point. For production deployments, adjust the `diskIOPSReadWrite` and `diskMBpsReadWrite` values based on your expected Kafka cluster size and workload requirements.
## Next step
> [!div class="nextstepaction"]
> [Deploy Strimzi and Kafka on Azure Kubernetes Service (AKS)](./kafka-deploy.md)
## Contributors
_Microsoft maintains this article. The following contributors originally wrote it:_
- Sergio Navar | Senior Customer Engineer
- Erin Schaffer | Content Developer 2