Hello Everyone,
This blog post is going to be a rather lengthy one. Recently I have been researching the use of Azure Kubernetes Service (AKS). Now there are plenty of blogs posts on how to set this up using the Azure portal, but very little or working examples of using AKS with Private endpoints, User assigned managed identities, Azure Vnet, Application Gateway with SSL, Nginx SSL ingress, Deploy using ARM templates (I know this is an old way of doing things but it’s what we use where I work for now) and Entra ID for authentication when using the management plane (kubectl). I’ve spent weeks using whole host of sites and troubleshooting errors. Now that I have a working POC version I’ve complied all my notes to write this blog post. hopefully this will help someone and save you hours of research time.
Prerequisites
Before we continue, as this is going to be an advanced blog post. I expect you to know how to deploy ARM templates via Azure DevOps, Know how to use and navigate around the Azure portal and to have the Azure CLI installed.
Deploy Needed Resources
Now I have used ARM templates to deploy the Application Gateway and AKS cluster instance, but I cheated when I deployed the Key Vault, SSH Public Key, User assigned Identity and Networking, I used the portal to do this. So before continuing make sure you have a VNET in place, Key Vault and User assigned Identity.
I’ve included the end result of the deployed resources that my AKS cluster resource group contained.
Demo Image
The above image shows the outcome of what we are going to achieve in this blog post. I have two resource groups one for my application gateway and the other for my AKS cluster. Entra ID is used to provide RBAC access and to allows users who are in the admin group access to control the cluster that is being able to use the kubectl command. The cluster is completely private using private endpoints, the control pane can only be accessed by a user who is on the corporate network or by connecting to an Azure VPN. If you don’t have this you can create a VM that’s within the same VNET as the cluster. Key Vault is used for the SSL certificates and or secrets.
I have an Nginx ingress pod that will forward the requests from the application gateway over to the sample app running in the backend.
Configuring Permissions for User Assigned Managed Identity
with the needed resources deployed you need to configure some permissions on the user assigned managed identity, I have shown an image of the permissions that I needed to assign to my Managed ID called “mid-aks-dev-uks-1”.
The ARM Templates
GitHub
I have uploaded the code (ARM templates and Yaml Files) at this location: Github Repo
At the above link you will find two folders “Aks” and “Application-gateway”. You will need to deploy the Application gateway first. within the “Application Gateway” folder you will see two more folders “parameters” and “templates”. The parameters folder contains the files: “application-gateway.parameters.json” and “waf-policies.parameters.json”.
The templates folder contains the following files “application-gateway.template.json” and “waf-policy.template.json”. You will need to update the parameters file to match your resource names.
Application Gateway Template/Parameters
parameters
This is the parameters file that I used.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "appGatewayName": { "value": "agw-lza-waf-sbx-uks-1" }, "location": { "value": "uksouth" }, "resourceTags": { "value": { "Environment": "Sandbox", "Application": "Landing Zone A", "Tier": "3", "Department": "PBC", "Cost Centre": "N/A" } }, "identityType": { "value": "UserAssigned" }, "userAssignedIdentities": { "value": { "/subscriptions/SUBSCRIPTON_KEY/resourceGroups/rg-aks-lza-radbase-sbx-uks-1/providers/Microsoft.ManagedIdentity/userAssignedIdentities/mid-aks-dev-uks-1": {} } }, "zones": { "value": [ "1" ] }, "appGatewaySkuName": { "value": "WAF_v2" }, "appGatewaySkuTier": { "value": "WAF_v2" }, "autoScaleMax": { "value": 2 }, "autoScaleMin": { "value": 0 }, "frontendIPConfigurations": { "value": [ { "name": "agw-pub-feip", "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { "id": "/subscriptions/SUBSCRIPTON_KEY/resourceGroups/rg-aks-lza-radbase-sbx-uks-1/providers/Microsoft.Network/publicIPAddresses/agw-pub-feip" } } } ] }, "frontendPorts": { "value": [ { "name": "agw-fep-80", "properties": { "port": 80 } }, { "name": "agw-fep-443", "properties": { "port": 443 } } ] }, "gatewayIPConfigurationName": { "value": "agw-ipc" }, "gatewayIPConfigurationSubnetID": { "value": "/subscriptions/SUBSCRIPTON_KEY/resourceGroups/rg-vnw-lza-dev-uks-1/providers/Microsoft.Network/virtualNetworks/vnw-lza-dev-uks-1/subnets/snw-vnw-lza-dev-uks-1-waf-1" }, "sslPolicyType": { "value": "Custom" }, "minProtocolVersion": { "value": "TLSv1_2" }, "cipherSuites": { "value": [ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" ] }, "webapplicationfirewallConfigurationProperties": { "value": { "enabled": true, "firewallMode": "Detection", "ruleSetType": "OWASP", "ruleSetVersion": "3.2", "disabledRuleGroups": [], "maxRequestBodySizeInKb": 128, "fileUploadLimitInMb": 100 } } } } |
Template
The Application gateway template.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "appGatewayName": { "type": "string", "metadata": { "description": "Name of Application Gateway" } }, "location": { "type": "string", "metadata": { "description": "Location of Application Gateway" } }, "resourceTags": { "type": "object", "metadata": { "description": "Resource tags for deployed resources." } }, "identityType": { "type": "string", "allowedValues": [ "None", "SystemAssigned", "SystemAssigned, UserAssigned", "UserAssigned" ], "metadata": { "description": "Type of Managed Identity Assigned" } }, "userAssignedIdentities": { "type": "object", "metadata": { "description": "List of User Assigned Managed Identities" } }, "zones": { "type": "array", "metadata": { "description": "Availability Zones" } }, "appGatewaySkuName": { "type": "string", "defaultValue": "WAF_v2", "allowedValues": [ "Standard_Large", "Standard_Medium", "Standard_Small", "Standard_v2", "WAF_Large", "WAF_Medium", "WAF_v2" ], "metadata": { "description": "Name of Application Gateway SKU" } }, "appGatewaySkuTier": { "type": "string", "defaultValue": "WAF_v2", "allowedValues": [ "Standard", "Standard_v2", "WAF", "WAF_v2" ], "metadata": { "description": "Tier of Application Gateway" } }, "autoScaleMax": { "type": "int", "metadata": { "description": "Maximum number of Application Gateway instances" } }, "autoScaleMin": { "type": "int", "metadata": { "description": "Minimum number of Application Gateway instances" } }, "frontendIPConfigurations": { "type": "array", "metadata": { "description": "Properties of Frontend IP Configurations" } }, "frontendPorts": { "type": "array", "metadata": { "description": "Properties of Front End ports" } }, "gatewayIPConfigurationName": { "type": "string", "metadata": { "description": "Name of Gateway IP Configuration" } }, "gatewayIPConfigurationSubnetID": { "type": "string", "metadata": { "description": "Resource ID of the Gateway IP Configuration subnet" } }, "sslPolicyType": { "type": "string", "allowedValues": [ "Custom", "CustomV2", "Predefined" ], "defaultValue": "Custom", "metadata": { "description": "SSL Policy Type" } }, "minProtocolVersion": { "type": "string", "allowedValues": [ "TLSv1_2", "TLSv1_3" ], "defaultValue": "TLSv1_2", "metadata": { "description": "Minimum Protocol Version Required" } }, "cipherSuites": { "type": "array", "metadata": { "description": "Allowed Cipher Suites" } }, "webapplicationfirewallConfigurationProperties": { "type": "object", "metadata": { "description": "Properties of the Web Application Firewall Configuration" } } }, "variables": {}, "resources": [ { "type": "Microsoft.Network/applicationGateways", "apiVersion": "2022-07-01", "name": "[parameters('appGatewayName')]", "location": "[parameters('location')]", "tags": "[parameters('resourceTags')]", "identity": { "type": "[parameters('identityType')]", "userAssignedIdentities": "[parameters('userAssignedIdentities')]" }, "zones": "[parameters('zones')]", "properties": { "sku": { "name": "[parameters('appGatewaySkuName')]", "tier": "[parameters('appGatewaySkuTier')]" }, "autoscaleConfiguration": { "maxCapacity": "[parameters('autoScaleMax')]", "minCapacity": "[parameters('autoScaleMin')]" }, "copy": [ { "name": "frontendIPConfigurations", "count": "[length(parameters('frontendIPConfigurations'))]", "input": "[parameters('frontendIPConfigurations')[copyIndex('frontendIPConfigurations')]]" }, { "name": "frontendPorts", "count": "[length(parameters('frontendPorts'))]", "input": "[parameters('frontendPorts')[copyIndex('frontendPorts')]]" } ], "sslPolicy": { "policyType": "[parameters('sslPolicyType')]", "minProtocolVersion": "[parameters('minProtocolVersion')]", "cipherSuites": "[parameters('cipherSuites')]" }, "gatewayIPConfigurations": [ { "name": "[parameters('gatewayIPConfigurationName')]", "properties": { "subnet": { "id": "[parameters('gatewayIPConfigurationSubnetID')]" } } } ], "webApplicationFirewallConfiguration": "[parameters('webapplicationfirewallConfigurationProperties')]" } } ] } |
AKS Template/Parameters
I’ve been lazy when doing the AKS template in that I’ve kept the parameters within the same template file. I just wanted to show you that you don’t have to have a separate parameters file. although it makes sense when deploying to different environments.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 |
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "managedClusterName": { "defaultValue": "aksmbosbxuks1", "type": "String" }, "clusterRGName": { "defaultValue": "rg-aks-lza-radbase-sbx-uks-1", "type": "String" }, "agentVMSize": { "type": "string", "defaultValue": "Standard_DS2_v2", "allowedValues": [ //https://learn.microsoft.com/en-us/azure/aks/quotas-skus-regions#cluster-configuration-presets-in-the-azure-portal //Production Standard "Standard_D8ds_v5", //Dev/Test "Standard_DS2_v2", //Production Economy "Standard_D8ds_v5", //Production Enterprise "Standard_D16ds_v5" ], "metadata": { "description": "The size of the Virtual Machine." } }, "osDiskSizeGB": { "type": "int", "defaultValue": 0, "maxValue": 1023, "minValue": 0, "metadata": { "description": "Disk size (in GB) to provision for each of the agent pool nodes. This value ranges from 0 to 1023. Specifying 0 will apply the default disk size for that agentVMSize." } }, "agentCount": { "type": "int", "defaultValue": 2, "maxValue": 2, "minValue": 1, "metadata": { "description": "The number of nodes for the cluster." } }, "networkPlugin": { "defaultValue": "azure", "type": "string", "allowedValues": [ "azure", "kubenet" ], "metadata": { "description": "Network plugin used for building Kubernetes network." } }, "clusterTags": { "defaultValue": {}, "type": "object", "metadata": { "description": "Specifies the tags of the AKS cluster." } }, "clusterSku": { "defaultValue": { "name": "Base", "tier": "Standard" //can also have tier set to be 'Free' }, "type": "object", "metadata": { "descirption": "The managed cluster SKU tier." } }, "loadBalancerSku": { "defaultValue": "Standard", "type": "string", "allowedValues": [ "Basic", "Standard" ], "metadata": { "description": "Specifies the sku of the load balancer used by the virtual machine scale sets used by node pools." } }, "networkPolicy": { "defaultValue": "azure", "type": "string", "metadata": { "description": "Network policy used for building Kubernetes network." } }, "serviceCidr": { "defaultValue": "172.16.0.0/22", "type": "string", "metadata": { "description": "A CIDR notation IP range from which to assign service cluster IPs." } }, "dnsServiceIP": { "defaultValue": "172.16.0.10", "type": "string", "metadata": { "description": "Containers DNS server IP address." } }, "vnetResourceGroup": { "defaultValue": "rg-vnw-lza-dev-uks-1", "type": "string", "metadata": { "description": "Resource GB of VNET." } }, "vnetSubscriptionId": { "defaultValue": "VNET_SUBSCRIOTN_ID", "type": "string", "metadata": { "description": "Subscription ID of Vnet RG" } }, "vnetName": { "defaultValue": "vnw-lza-dev-uks-1", "type": "string", "metadata": { "description": "Name Of Vnet for AKS" } }, "outboundType": { "defaultValue": "loadBalancer", "type": "string", "metadata": { "description": "Name Of Vnet for AKS" } }, "userAssignedManagedIdentityName": { "defaultValue": "mid-aks-dev-uks-1", "type": "string", "metadata": { "description": "Name Of Vnet for AKS" } }, "entraIdTenant": { "defaultValue": "ENTRA_ID_TENANT_ID", "type": "string", "metadata": { "description": "Entra ID Tenant ID" } }, "systemNodePoolName": { "defaultValue": "system", "type": "string", "metadata": { "description": "Specifies the unique name of of the system node pool profile in the context of the subscription and resource group." } }, "systemNodePoolNodeLabels": { "defaultValue": {}, "type": "object", "metadata": { "description": "Specifies the Agent pool node labels to be persisted across all nodes in the system node pool." } }, "systemNodePoolNodeTaints": { "defaultValue": [], "type": "array", "metadata": { "description": "Specifies the taints added to new nodes during node pool create and scale. For example, key=value:NoSchedule. - string" } }, "userNodePoolName": { "defaultValue": "user", "type": "string", "metadata": { "description": "Specifies the unique name of of the user node pool profile in the context of the subscription and resource group." } }, "userNodePoolNodeLabels": { "defaultValue": {}, "type": "object", "metadata": { "description": "Specifies the Agent pool node labels to be persisted across all nodes in the user node pool." } }, "userNodePoolNodeTaints": { "defaultValue": [], "type": "array", "metadata": { "description": "Specifies the taints added to new nodes during node pool create and scale. For example, key=value:NoSchedule. - string" } }, "aksClusterAdminUsername": { "defaultValue": "askAdmin", "type": "string", "metadata": { "description": "Specifies the administrator username of Linux virtual machines." } }, "aksClusterSshPublicKey": { "defaultValue": "ssh-rsa PUBLIC KEY", "type": "string", "metadata": { "description": "Specifies the SSH RSA public key string for the Linux nodes." } }, "applicationGatewayName": { "type": "string", "defaultValue": "agw-lza-waf-sbx-uks-1", "metadata": { "description": "Specifies the name of the Application Gateway." } }, "agwRgName": { "type": "string", "defaultValue": "rg-agw-lza-waf-sbx-uks-1", "metadata": { "description": "Rg Name where Application GW is located" } } }, "variables": { "vnetID": "[resourceId(parameters('vnetSubscriptionId'), parameters('vnetResourceGroup'), 'Microsoft.Network/VirtualNetworks', parameters('vnetName'))]", "nodeSubnetID": "[concat(variables('vnetID'), '/subnets/snw-vnw-lza-dev-uks-1-kubnode-1')]", "podSubnetID": "[concat(variables('vnetID'), '/subnets/snw-vnw-lza-dev-uks-1-kubpod-1')]", "applicationGatewayId": "[resourceId(parameters('agwRgName'),'Microsoft.Network/applicationGateways', parameters('applicationGatewayName'))]", "clusterInfrastructureRG": "[concat(parameters('clusterRGName'), '_', parameters('managedClusterName'), '_uksouth')]" }, "resources": [ { "type": "Microsoft.ContainerService/managedClusters", "apiVersion": "2023-08-02-preview", "name": "[parameters('managedClusterName')]", "location": "uksouth", "identity": { "type": "UserAssigned", "userAssignedIdentities": { "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedManagedIdentityName'))]": {} } }, "tags": { "tag1": "testing" }, "sku": "[parameters('clusterSku')]", "properties": { "kubernetesVersion": "1.27.7", "dnsPrefix": "[concat(parameters('managedClusterName'), '-dns')]", "identityProfile": { "kubeletidentity": { "resourceId": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedManagedIdentityName'))]", "clientId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',parameters('userAssignedManagedIdentityName')),'2018-11-30','Full').properties.clientId]", "objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',parameters('userAssignedManagedIdentityName')),'2018-11-30','Full').properties.principalId]" } }, "publicNetworkAccess": "Disabled", "aadProfile": { "adminGroupObjectIds": [ "ADMIN_GROUP_OBJECT_IDS" ], "managed": true, "enableAzureRBAC": true, "tenantID": "[parameters('entraIdTenant')]" }, "agentPoolProfiles": [ { "name": "[tolower(parameters('systemNodePoolName'))]", "max-pods": 250, "count": "[parameters('agentCount')]", "vmSize": "[parameters('agentVMSize')]", "osDiskSizeGB": "[parameters('osDiskSizeGB')]", "orchestratorVersion": "1.27.7", "enableNodePublicIP": false, "tags": "[parameters('clusterTags')]", "mode": "System", "osType": "Linux", "nodeLabels": "[parameters('systemNodePoolNodeLabels')]", "nodeTaints": "[parameters('systemNodePoolNodeTaints')]", "vnetSubnetID": "[variables('nodeSubnetID')]", "podSubnetID": "[variables('podSubnetID')]" }, { "name": "[tolower(parameters('userNodePoolName'))]", "max-pods": 250, "count": "[parameters('agentCount')]", "vmSize": "[parameters('agentVMSize')]", "osDiskSizeGB": "[parameters('osDiskSizeGB')]", "orchestratorVersion": "1.27.7", "enableNodePublicIP": false, "tags": "[parameters('clusterTags')]", "mode": "User", "osType": "Linux", "nodeLabels": "[parameters('userNodePoolNodeLabels')]", "nodeTaints": "[parameters('userNodePoolNodeTaints')]", "vnetSubnetID": "[variables('nodeSubnetID')]", "podSubnetID": "[variables('podSubnetID')]" } ], "servicePrincipalProfile": { "clientId": "msi" }, "addonProfiles": { "azureKeyvaultSecretsProvider": { "config": { "vaultName": "keylzasecsdevbxuks1", "tenantId": "TENANT_ID", "usePodIdentity": "true" }, "enabled": true, "identity": { "resourceId": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedManagedIdentityName'))]", "clientId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',parameters('userAssignedManagedIdentityName')),'2018-11-30','Full').properties.clientId]", "objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',parameters('userAssignedManagedIdentityName')),'2018-11-30','Full').properties.principalId]" } }, "azurepolicy": { "enabled": true }, "httpApplicationRouting": { "enabled": true }, "ingressApplicationGateway": { "config": { "applicationGatewayId": "[variables('applicationGatewayId')]" }, "enabled": true, "identity": { "resourceId": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedManagedIdentityName'))]", "clientId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',parameters('userAssignedManagedIdentityName')),'2018-11-30','Full').properties.clientId]", "objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',parameters('userAssignedManagedIdentityName')),'2018-11-30','Full').properties.principalId]" } } }, "linuxProfile": { "adminUsername": "[parameters('aksClusterAdminUsername')]", "ssh": { "publicKeys": [ { "keyData": "[parameters('aksClusterSshPublicKey')]" } ] } }, "nodeResourceGroup": "[variables('clusterInfrastructureRG')]", "enableRBAC": true, "supportPlan": "KubernetesOfficial", "networkProfile": { "loadBalancerSku": "[parameters('loadBalancerSku')]", "networkPlugin": "[parameters('networkPlugin')]", "networkPolicy": "[parameters('networkPolicy')]", "serviceCidr": "[parameters('serviceCidr')]", "dnsServiceIP": "[parameters('dnsServiceIP')]", "outboundType": "[parameters('outboundType')]", "loadBalancerProfile": "[json('null')]" }, "privateLinkResources": [ { "id": "[concat(resourceId('Microsoft.ContainerService/managedClusters', parameters('managedClusterName')), '/privateLinkResources/management')]", "name": "management", "type": "Microsoft.ContainerService/managedClusters/privateLinkResources", "groupId": "management", "requiredMembers": [ "management" ] } ], "apiServerAccessProfile": { "enablePrivateCluster": true, "privateDNSZone": "/subscriptions/SUBSCRIPTION_ID/resourceGroups/rg-privdnszn-con-sbx-uks-1/providers/Microsoft.Network/privateDnsZones/privatelink.uksouth.azmk8s.io", "enablePrivateClusterPublicFQDN": false }, "autoUpgradeProfile": { "upgradeChannel": "patch", "nodeOSUpgradeChannel": "NodeImage" }, "disableLocalAccounts": true, "securityProfile": {}, "storageProfile": { "diskCSIDriver": { "enabled": true, "version": "v1" }, "fileCSIDriver": { "enabled": true }, "snapshotController": { "enabled": true } }, "oidcIssuerProfile": { "enabled": true }, "workloadAutoScalerProfile": {}, "metricsProfile": { "costAnalysis": { "enabled": false } } } } ] } |
Again before deploying the above templates make sure you have deployed your VNET, User assigned managed identity and Key Vault and SSH public Key.
VNET
The VNET that I have has 3 subnets:
- 1 subnet dedicated to the application gateway
- 1 subnet for AKS Node IP addresses
- 1 Subnet for AKS Pods
The below image shows what My vnet subnets looked like.
The below images shows the AKS cluster using this VNET:
In Part 2 of this blog post I will discuss how I deployed the SSL and more. Part 2 Here