OpenMCF logoOpenMCF

Loading...

Azure AKS Cluster

Deploys an Azure Kubernetes Service cluster with configurable node pools, Azure CNI networking, optional Azure AD RBAC integration, and managed add-ons including Container Insights, Key Vault CSI driver, and Workload Identity. The component uses a system-assigned managed identity and supports both public and private cluster topologies.

What Gets Created

When you deploy an AzureAksCluster resource, OpenMCF provisions:

  • AKS Managed Cluster — a containerservice.ManagedCluster resource with system-assigned managed identity, the specified Kubernetes version, and a DNS prefix derived from metadata.name
  • System Node Pool — a System mode agent pool with autoscaling enabled, placed in the specified availability zones and VNet subnet
  • User Node Pools — created for each entry in userNodePools, each as a separate containerservice.AgentPool resource with independent VM size, autoscaling, and optional Spot instance configuration
  • Network Profile — configures the cluster networking with the selected plugin (Azure CNI or Kubenet), plugin mode (Overlay or Dynamic), a standard SKU load balancer, and service/DNS CIDRs
  • Azure AD RBAC Integration — enabled by default, provides managed Azure AD authentication and Kubernetes RBAC authorization
  • OIDC Issuer + Workload Identity — created only when addons.enableWorkloadIdentity is true, enables pods to authenticate to Azure services via Kubernetes service accounts
  • Add-on Profiles — conditionally enabled: Container Insights (OMS agent), Key Vault CSI secrets provider, and Azure Policy

Prerequisites

  • Azure credentials configured via environment variables or OpenMCF provider config
  • An Azure Resource Group where the cluster will be created (can reference an AzureResourceGroup resource)
  • A VNet subnet for cluster nodes (can reference an AzureVpc resource)
  • A Log Analytics Workspace resource ID if enabling Container Insights

Quick Start

Create a file aks-cluster.yaml:

apiVersion: azure.openmcf.org/v1
kind: AzureAksCluster
metadata:
  name: my-cluster
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: dev.AzureAksCluster.my-cluster
spec:
  region: eastus
  resourceGroup: my-rg
  vnetSubnetId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-rg/providers/Microsoft.Network/virtualNetworks/my-vnet/subnets/nodes
  kubernetesVersion: "1.30"
  systemNodePool:
    vmSize: Standard_D4s_v5
    autoscaling:
      minCount: 1
      maxCount: 3
    availabilityZones:
      - "1"

Deploy:

openmcf apply -f aks-cluster.yaml

This creates a public AKS cluster with a single system node pool running Kubernetes 1.30 on Azure CNI Overlay networking with Standard SKU control plane.

Configuration Reference

Required Fields

FieldTypeDescriptionValidation
regionstringAzure region for the cluster (e.g., eastus).Required
resourceGroupStringValueOrRefAzure Resource Group name. Can reference an AzureResourceGroup resource via valueFrom.Required
vnetSubnetIdStringValueOrRefAzure resource ID of the VNet subnet for cluster nodes. Can reference an AzureVpc resource via valueFrom.Required
systemNodePoolobjectSystem node pool configuration. See nested fields below.Required
systemNodePool.vmSizestringAzure VM size for system nodes (e.g., Standard_D4s_v5).Required. Recommended default: Standard_D4s_v5
systemNodePool.autoscalingobjectAutoscaling configuration for the system node pool.Required
systemNodePool.autoscaling.minCountintMinimum number of nodes.>= 1
systemNodePool.autoscaling.maxCountintMaximum number of nodes.>= 1
systemNodePool.availabilityZonesstring[]Availability zones for the system node pool (e.g., ["1", "2", "3"]).Minimum 1 item

Optional Fields

FieldTypeDefaultDescription
kubernetesVersionstring—Kubernetes version for the control plane (e.g., 1.30). Recommended default: 1.30.
controlPlaneSkuenumSTANDARDControl plane SKU tier. Values: STANDARD (99.95% SLA, ~$73/month), FREE (no SLA, dev/test only).
networkPluginenumAZURE_CNINetworking plugin. Values: AZURE_CNI (recommended), KUBENET (deprecated, retiring March 2028).
networkPluginModeenumOVERLAYAzure CNI mode. Only applies when networkPlugin is AZURE_CNI. Values: OVERLAY (pods use private CIDR), DYNAMIC (pods use real VNet IPs).
privateClusterEnabledboolfalseWhen true, the API server endpoint is private and accessible only from within the VNet.
authorizedIpRangesstring[][]CIDR blocks allowed to access the API server. Only applies to public clusters. Must match pattern x.x.x.x/y.
disableAzureAdRbacboolfalseWhen true, disables Azure AD integration for Kubernetes RBAC.
userNodePoolsobject[][]User node pools for application workloads. See nested fields below.
userNodePools[].namestring—Node pool name. Must be lowercase alphanumeric, max 12 characters. Pattern: ^[a-z0-9]{1,12}$.
userNodePools[].vmSizestring—Azure VM size for this pool. Required per pool.
userNodePools[].autoscaling.minCountint—Minimum node count. >= 1. Required per pool.
userNodePools[].autoscaling.maxCountint—Maximum node count. >= 1. Required per pool.
userNodePools[].availabilityZonesstring[]—Availability zones for the pool. Minimum 1 item. Required per pool.
userNodePools[].spotEnabledboolfalseEnables Azure Spot instances. Eviction policy is Delete with max price set to on-demand rate.
addons.enableContainerInsightsboolfalseEnables Azure Monitor Container Insights. Requires addons.logAnalyticsWorkspaceId.
addons.enableKeyVaultCsiDriverboolfalseEnables the Azure Key Vault CSI driver for mounting secrets as volumes.
addons.enableAzurePolicyboolfalseEnables the Azure Policy add-on for governance.
addons.enableWorkloadIdentityboolfalseEnables Azure AD Workload Identity and OIDC issuer for secret-less pod authentication.
addons.logAnalyticsWorkspaceIdstring—Azure resource ID of the Log Analytics Workspace. Required when enableContainerInsights is true.
advancedNetworking.podCidrstring10.244.0.0/16Pod CIDR for Overlay mode. Only applies when networkPluginMode is OVERLAY. Must be valid CIDR.
advancedNetworking.serviceCidrstring10.0.0.0/16Service CIDR for Kubernetes services. Must not overlap with VNet or pod CIDR.
advancedNetworking.dnsServiceIpstring10.0.0.10DNS service IP. Must be within serviceCidr range.
advancedNetworking.customDnsServersstring[][]Custom DNS servers for the VNet. Leave empty for Azure-provided DNS.

Examples

Dev/Test Cluster with Free Tier

A minimal cluster for development with free control plane SKU and a single availability zone:

apiVersion: azure.openmcf.org/v1
kind: AzureAksCluster
metadata:
  name: dev-cluster
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: dev.AzureAksCluster.dev-cluster
spec:
  region: eastus
  resourceGroup: dev-rg
  vnetSubnetId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/dev-rg/providers/Microsoft.Network/virtualNetworks/dev-vnet/subnets/nodes
  kubernetesVersion: "1.30"
  controlPlaneSku: FREE
  systemNodePool:
    vmSize: Standard_D2s_v3
    autoscaling:
      minCount: 1
      maxCount: 3
    availabilityZones:
      - "1"

Production Cluster with User Node Pools

A production cluster with Standard SKU, multi-AZ system pool, a general-purpose user pool, and Azure AD RBAC:

apiVersion: azure.openmcf.org/v1
kind: AzureAksCluster
metadata:
  name: prod-cluster
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: prod.AzureAksCluster.prod-cluster
spec:
  region: eastus
  resourceGroup: prod-rg
  vnetSubnetId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/prod-rg/providers/Microsoft.Network/virtualNetworks/prod-vnet/subnets/nodes
  kubernetesVersion: "1.30"
  systemNodePool:
    vmSize: Standard_D4s_v5
    autoscaling:
      minCount: 3
      maxCount: 5
    availabilityZones:
      - "1"
      - "2"
      - "3"
  userNodePools:
    - name: general
      vmSize: Standard_D8s_v5
      autoscaling:
        minCount: 3
        maxCount: 10
      availabilityZones:
        - "1"
        - "2"
        - "3"

Private Cluster with Add-ons and Spot Pools

A private cluster with no public API endpoint, full add-on suite, a general user pool, and a cost-optimized Spot pool for batch workloads:

apiVersion: azure.openmcf.org/v1
kind: AzureAksCluster
metadata:
  name: secure-cluster
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: prod.AzureAksCluster.secure-cluster
spec:
  region: westeurope
  resourceGroup: secure-rg
  vnetSubnetId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/secure-rg/providers/Microsoft.Network/virtualNetworks/secure-vnet/subnets/nodes
  kubernetesVersion: "1.30"
  privateClusterEnabled: true
  systemNodePool:
    vmSize: Standard_D4s_v5
    autoscaling:
      minCount: 3
      maxCount: 5
    availabilityZones:
      - "1"
      - "2"
      - "3"
  userNodePools:
    - name: general
      vmSize: Standard_D8s_v5
      autoscaling:
        minCount: 3
        maxCount: 15
      availabilityZones:
        - "1"
        - "2"
        - "3"
    - name: spot
      vmSize: Standard_D8s_v5
      autoscaling:
        minCount: 1
        maxCount: 20
      availabilityZones:
        - "1"
        - "2"
        - "3"
      spotEnabled: true
  addons:
    enableContainerInsights: true
    enableKeyVaultCsiDriver: true
    enableAzurePolicy: true
    enableWorkloadIdentity: true
    logAnalyticsWorkspaceId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/secure-rg/providers/Microsoft.OperationalInsights/workspaces/secure-logs
  advancedNetworking:
    podCidr: "10.244.0.0/16"
    serviceCidr: "10.0.0.0/16"
    dnsServiceIp: "10.0.0.10"

Using Foreign Key References

Reference other OpenMCF-managed resources instead of hardcoding IDs:

apiVersion: azure.openmcf.org/v1
kind: AzureAksCluster
metadata:
  name: ref-cluster
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: prod.AzureAksCluster.ref-cluster
spec:
  region: eastus
  resourceGroup:
    valueFrom:
      kind: AzureResourceGroup
      name: my-rg
      field: status.outputs.resource_group_name
  vnetSubnetId:
    valueFrom:
      kind: AzureVpc
      name: my-vpc
      field: status.outputs.nodes_subnet_id
  kubernetesVersion: "1.30"
  systemNodePool:
    vmSize: Standard_D4s_v5
    autoscaling:
      minCount: 3
      maxCount: 5
    availabilityZones:
      - "1"
      - "2"
      - "3"

Stack Outputs

After deployment, the following outputs are available in status.outputs:

OutputTypeDescription
api_server_endpointstringURL of the Kubernetes API server endpoint for the AKS cluster
cluster_resource_idstringAzure Resource ID of the AKS cluster
cluster_kubeconfigstringBase64-encoded kubeconfig file contents for cluster access
managed_identity_principal_idstringAzure AD principal ID of the cluster's kubelet managed identity

Related Components

  • AzureResourceGroup — provides the resource group for cluster placement
  • AzureVpc — provides the VNet and subnet for cluster nodes
  • AzureKeyVault — stores secrets that pods can mount via the Key Vault CSI driver
  • AzureLogAnalyticsWorkspace — provides the workspace for Container Insights monitoring
  • AzureContainerRegistry — hosts container images for cluster workloads

Next article

Azure AKS Node Pool

Azure AKS Node Pool Deploys a node pool into an existing Azure Kubernetes Service (AKS) cluster with configurable VM size, node count, autoscaling, availability zones, OS type, pool mode, and Spot VM pricing. The component creates a containerservice.AgentPool resource attached to the referenced parent cluster. What Gets Created When you deploy an AzureAksNodePool resource, OpenMCF provisions: Agent Pool — a containerservice.AgentPool resource in the specified resource group and parent AKS...
Read next article
Presets
2 ready-to-deploy configurationsView presets →