diff --git a/README.md b/README.md
index 3eb0c07..fc11a2f 100644
--- a/README.md
+++ b/README.md
@@ -53,6 +53,7 @@ The following resources are used by this module:
- [azurerm_management_lock.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_lock) (resource)
- [azurerm_monitor_diagnostic_setting.aks](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_diagnostic_setting) (resource)
- [azurerm_role_assignment.acr](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) (resource)
+- [azurerm_role_assignment.dns_zone_contributor](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) (resource)
- [azurerm_role_assignment.network_contributor_on_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) (resource)
- [azurerm_user_assigned_identity.aks](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) (resource)
- [modtm_telemetry.telemetry](https://registry.terraform.io/providers/Azure/modtm/latest/docs/resources/telemetry) (resource)
@@ -299,6 +300,22 @@ Type: `string`
Default: `"AzureLinux"`
+### [private\_dns\_zone\_id](#input\_private\_dns\_zone\_id)
+
+Description: (Optional) Either the ID of Private DNS Zone which should be delegated to this Cluster.
+
+Type: `string`
+
+Default: `null`
+
+### [private\_dns\_zone\_id\_enabled](#input\_private\_dns\_zone\_id\_enabled)
+
+Description: (Optional) Enable private DNS zone integration for the AKS cluster.
+
+Type: `bool`
+
+Default: `false`
+
### [rbac\_aad\_admin\_group\_object\_ids](#input\_rbac\_aad\_admin\_group\_object\_ids)
Description: Object ID of groups with admin access.
diff --git a/examples/default/README.md b/examples/default/README.md
index bbcb961..8310cb4 100644
--- a/examples/default/README.md
+++ b/examples/default/README.md
@@ -58,12 +58,14 @@ resource "azurerm_resource_group" "this" {
# Leaving location as `null` will cause the module to use the resource group location
# with a data source.
module "test" {
- source = "../../"
- kubernetes_version = "1.28"
- enable_telemetry = var.enable_telemetry # see variables.tf
- name = module.naming.kubernetes_cluster.name_unique
- resource_group_name = azurerm_resource_group.this.name
- location = azurerm_resource_group.this.location
+ source = "../../"
+ kubernetes_version = "1.28"
+ enable_telemetry = var.enable_telemetry # see variables.tf
+ name = module.naming.kubernetes_cluster.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+ location = azurerm_resource_group.this.location
+ private_dns_zone_id = azurerm_private_dns_zone.mydomain.id
+ private_dns_zone_id_enabled = true
network = {
name = module.avm_res_network_virtualnetwork.name
resource_group_name = azurerm_resource_group.this.name
@@ -82,6 +84,11 @@ resource "azurerm_private_dns_zone" "this" {
resource_group_name = azurerm_resource_group.this.name
}
+resource "azurerm_private_dns_zone" "mydomain" {
+ name = "privatelink.azmk8s.io"
+ resource_group_name = azurerm_resource_group.this.name
+}
+
module "avm_res_network_virtualnetwork" {
source = "Azure/avm-res-network-virtualnetwork/azurerm"
version = "0.2.3"
@@ -118,6 +125,7 @@ The following requirements are needed by this module:
The following resources are used by this module:
+- [azurerm_private_dns_zone.mydomain](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_zone) (resource)
- [azurerm_private_dns_zone.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_zone) (resource)
- [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) (resource)
- [random_integer.region_index](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource)
diff --git a/examples/default/main.tf b/examples/default/main.tf
index dcb123c..e20d7d8 100644
--- a/examples/default/main.tf
+++ b/examples/default/main.tf
@@ -52,12 +52,14 @@ resource "azurerm_resource_group" "this" {
# Leaving location as `null` will cause the module to use the resource group location
# with a data source.
module "test" {
- source = "../../"
- kubernetes_version = "1.28"
- enable_telemetry = var.enable_telemetry # see variables.tf
- name = module.naming.kubernetes_cluster.name_unique
- resource_group_name = azurerm_resource_group.this.name
- location = azurerm_resource_group.this.location
+ source = "../../"
+ kubernetes_version = "1.28"
+ enable_telemetry = var.enable_telemetry # see variables.tf
+ name = module.naming.kubernetes_cluster.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+ location = azurerm_resource_group.this.location
+ private_dns_zone_id = azurerm_private_dns_zone.mydomain.id
+ private_dns_zone_id_enabled = true
network = {
name = module.avm_res_network_virtualnetwork.name
resource_group_name = azurerm_resource_group.this.name
@@ -76,6 +78,11 @@ resource "azurerm_private_dns_zone" "this" {
resource_group_name = azurerm_resource_group.this.name
}
+resource "azurerm_private_dns_zone" "mydomain" {
+ name = "privatelink.azmk8s.io"
+ resource_group_name = azurerm_resource_group.this.name
+}
+
module "avm_res_network_virtualnetwork" {
source = "Azure/avm-res-network-virtualnetwork/azurerm"
version = "0.2.3"
diff --git a/locals.tf b/locals.tf
index 2b1c99c..b05ee6b 100644
--- a/locals.tf
+++ b/locals.tf
@@ -1,4 +1,12 @@
-
+locals {
+ private_dns_zone_name = try(reverse(split("/", var.private_dns_zone_id))[0], null)
+ valid_private_dns_zone_regexs = [
+ "private\\.[a-z]+\\.azmk8s\\.io",
+ "privatelink\\.[a-z]+\\.azmk8s\\.io",
+ "[a-zA-Z0-9\\-]{1,32}\\.private\\.[a-z]+\\.azmk8s\\.io",
+ "[a-zA-Z0-9\\-]{1,32}\\.privatelink\\.[a-z]+\\.azmk8s\\.io",
+ ]
+}
locals {
locations_cached_or_live = data.local_file.locations.content
diff --git a/main.tf b/main.tf
index 9314318..b9d0d2c 100644
--- a/main.tf
+++ b/main.tf
@@ -48,6 +48,14 @@ resource "azurerm_role_assignment" "network_contributor_on_resource_group" {
role_definition_name = "Network Contributor"
}
+resource "azurerm_role_assignment" "dns_zone_contributor" {
+ count = var.private_dns_zone_id_enabled ? 1 : 0
+
+ principal_id = data.azurerm_user_assigned_identity.cluster_identity.principal_id
+ scope = var.private_dns_zone_id
+ role_definition_name = "Private DNS Zone Contributor"
+}
+
resource "azurerm_kubernetes_cluster" "this" {
location = var.location
name = "aks-${var.name}"
@@ -60,6 +68,7 @@ resource "azurerm_kubernetes_cluster" "this" {
node_os_channel_upgrade = "NodeImage"
oidc_issuer_enabled = true
private_cluster_enabled = true
+ private_dns_zone_id = var.private_dns_zone_id
role_based_access_control_enabled = true
sku_tier = "Standard"
tags = var.tags
@@ -135,6 +144,14 @@ resource "azurerm_kubernetes_cluster" "this" {
condition = var.orchestrator_version == null || try(can(regex("^[0-9]+\\.[0-9]+$", var.orchestrator_version)), false)
error_message = "Ensure that orchestrator_version does not specify a patch version"
}
+ precondition {
+ condition = var.private_dns_zone_id == null ? true : (anytrue([for r in local.valid_private_dns_zone_regexs : try(regex(r, local.private_dns_zone_name) == local.private_dns_zone_name, false)]))
+ error_message = "According to the [document](https://learn.microsoft.com/en-us/azure/aks/private-clusters?tabs=azure-portal#configure-a-private-dns-zone), the private DNS zone must be in one of the following format: `privatelink..azmk8s.io`, `.privatelink..azmk8s.io`, `private..azmk8s.io`, `.private..azmk8s.io`"
+ }
+ precondition {
+ condition = (var.private_dns_zone_id == null) && !var.private_dns_zone_id_enabled
+ error_message = "private_dns_zone_id must be set if private_dns_zone_id_enabled is true"
+ }
}
}
diff --git a/variables.tf b/variables.tf
index b83ab55..5cb5091 100644
--- a/variables.tf
+++ b/variables.tf
@@ -207,6 +207,24 @@ variable "os_sku" {
}
}
+variable "private_dns_zone_id" {
+ type = string
+ default = null
+ description = "(Optional) Either the ID of Private DNS Zone which should be delegated to this Cluster."
+
+ validation {
+ condition = var.private_dns_zone_id == null || can(regex("^(/subscriptions/[^/]+/resourceGroups/[^/]+/providers/Microsoft.Network/privateDnsZones/[^/]+)$", var.private_dns_zone_id))
+ error_message = "private_dns_zone_id must be a valid Private DNS Zone ID"
+ }
+}
+
+variable "private_dns_zone_id_enabled" {
+ type = bool
+ default = false
+ description = "(Optional) Enable private DNS zone integration for the AKS cluster."
+ nullable = false
+}
+
variable "rbac_aad_admin_group_object_ids" {
type = list(string)
default = null