diff --git a/README.md b/README.md index 7afda9fb..983121c1 100644 --- a/README.md +++ b/README.md @@ -319,6 +319,7 @@ No modules. | [create\_role\_assignments\_for\_application\_gateway](#input\_create\_role\_assignments\_for\_application\_gateway) | (Optional) Whether to create the corresponding role assignments for application gateway or not. Defaults to `true`. | `bool` | `true` | no | | [default\_node\_pool\_fips\_enabled](#input\_default\_node\_pool\_fips\_enabled) | (Optional) Should the nodes in this Node Pool have Federal Information Processing Standard enabled? Changing this forces a new resource to be created. | `bool` | `null` | no | | [disk\_encryption\_set\_id](#input\_disk\_encryption\_set\_id) | (Optional) The ID of the Disk Encryption Set which should be used for the Nodes and Volumes. More information [can be found in the documentation](https://docs.microsoft.com/azure/aks/azure-disk-customer-managed-keys). Changing this forces a new resource to be created. | `string` | `null` | no | +| [dns\_prefix\_private\_cluster](#input\_dns\_prefix\_private\_cluster) | (Optional) Specifies the DNS prefix to use with private clusters. Only one of `var.prefix,var.dns_prefix_private_cluster` can be specified. Changing this forces a new resource to be created. | `string` | `null` | no | | [ebpf\_data\_plane](#input\_ebpf\_data\_plane) | (Optional) Specifies the eBPF data plane used for building the Kubernetes network. Possible value is `cilium`. Changing this forces a new resource to be created. | `string` | `null` | no | | [enable\_auto\_scaling](#input\_enable\_auto\_scaling) | Enable node pool autoscaling | `bool` | `false` | no | | [enable\_host\_encryption](#input\_enable\_host\_encryption) | Enable Host Encryption for default node pool. Encryption at host feature must be enabled on the subscription: https://docs.microsoft.com/azure/virtual-machines/linux/disks-enable-host-based-encryption-cli | `bool` | `false` | no | @@ -386,7 +387,7 @@ No modules. | [os\_disk\_type](#input\_os\_disk\_type) | The type of disk which should be used for the Operating System. Possible values are `Ephemeral` and `Managed`. Defaults to `Managed`. Changing this forces a new resource to be created. | `string` | `"Managed"` | no | | [os\_sku](#input\_os\_sku) | (Optional) Specifies the OS SKU used by the agent pool. Possible values include: `Ubuntu`, `CBLMariner`, `Mariner`, `Windows2019`, `Windows2022`. If not specified, the default is `Ubuntu` if OSType=Linux or `Windows2019` if OSType=Windows. And the default Windows OSSKU will be changed to `Windows2022` after Windows2019 is deprecated. Changing this forces a new resource to be created. | `string` | `null` | no | | [pod\_subnet\_id](#input\_pod\_subnet\_id) | (Optional) The ID of the Subnet where the pods in the default Node Pool should exist. Changing this forces a new resource to be created. | `string` | `null` | no | -| [prefix](#input\_prefix) | (Optional) The prefix for the resources created in the specified Azure Resource Group. Omitting this variable requires both `var.cluster_log_analytics_workspace_name` and `var.cluster_name` have been set. | `string` | `""` | no | +| [prefix](#input\_prefix) | (Optional) The prefix for the resources created in the specified Azure Resource Group. Omitting this variable requires both `var.cluster_log_analytics_workspace_name` and `var.cluster_name` have been set. Only one of `var.prefix,var.dns_prefix_private_cluster` can be specified. | `string` | `""` | no | | [private\_cluster\_enabled](#input\_private\_cluster\_enabled) | If true cluster API server will be exposed only on internal IP address and available only in cluster vnet. | `bool` | `false` | no | | [private\_cluster\_public\_fqdn\_enabled](#input\_private\_cluster\_public\_fqdn\_enabled) | (Optional) Specifies whether a Public FQDN for this Private Cluster should be added. Defaults to `false`. | `bool` | `false` | no | | [private\_dns\_zone\_id](#input\_private\_dns\_zone\_id) | (Optional) Either the ID of Private DNS Zone which should be delegated to this Cluster, `System` to have AKS manage this or `None`. In case of `None` you will need to bring your own DNS server and set up resolving, otherwise cluster will have issues after provisioning. Changing this forces a new resource to be created. | `string` | `null` | no | diff --git a/locals.tf b/locals.tf index 2f4d1c3f..d1c0c4e5 100644 --- a/locals.tf +++ b/locals.tf @@ -9,7 +9,7 @@ locals { (contains(["patch"], var.automatic_channel_upgrade) && can(regex("^[0-9]{1,}\\.[0-9]{1,}$", var.kubernetes_version)) && (can(regex("^[0-9]{1,}\\.[0-9]{1,}$", var.orchestrator_version)) || var.orchestrator_version == null)) || (contains(["rapid", "stable", "node-image"], var.automatic_channel_upgrade) && var.kubernetes_version == null && var.orchestrator_version == null) ) - cluster_name = coalesce(var.cluster_name, trim("${var.prefix}-aks", "-")) + cluster_name = try(coalesce(var.cluster_name, trim("${var.prefix}-aks", "-")), "aks") # Abstract the decision whether to create an Analytics Workspace or not. create_analytics_solution = var.log_analytics_workspace_enabled && var.log_analytics_solution == null create_analytics_workspace = var.log_analytics_workspace_enabled && var.log_analytics_workspace == null @@ -54,8 +54,15 @@ locals { pool.pod_subnet_id ] ], [var.vnet_subnet_id])) + private_dns_zone_name = try(reverse(split("/", var.private_dns_zone_id))[0], null) query_datasource_for_log_analytics_workspace_location = var.log_analytics_workspace_enabled && (var.log_analytics_workspace != null ? var.log_analytics_workspace.location == null : false) subnet_ids = toset([for id in local.potential_subnet_ids : id if id != null]) use_brown_field_gw_for_ingress = var.brown_field_application_gateway_for_ingress != null use_green_field_gw_for_ingress = var.green_field_application_gateway_for_ingress != 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", + ] } diff --git a/log_analytics.tf b/log_analytics.tf index b791ecdd..e85036f9 100644 --- a/log_analytics.tf +++ b/log_analytics.tf @@ -2,7 +2,7 @@ resource "azurerm_log_analytics_workspace" "main" { count = local.create_analytics_workspace ? 1 : 0 location = coalesce(var.location, data.azurerm_resource_group.main.location) - name = coalesce(var.cluster_log_analytics_workspace_name, trim("${var.prefix}-workspace", "-")) + name = try(coalesce(var.cluster_log_analytics_workspace_name, trim("${var.prefix}-workspace", "-")), "aks-workspace") resource_group_name = coalesce(var.log_analytics_workspace_resource_group_name, var.resource_group_name) allow_resource_only_permissions = var.log_analytics_workspace_allow_resource_only_permissions cmk_for_query_forced = var.log_analytics_workspace_cmk_for_query_forced diff --git a/main.tf b/main.tf index c4dc98cc..6e7588ec 100644 --- a/main.tf +++ b/main.tf @@ -22,6 +22,7 @@ resource "azurerm_kubernetes_cluster" "main" { azure_policy_enabled = var.azure_policy_enabled disk_encryption_set_id = var.disk_encryption_set_id dns_prefix = var.prefix + dns_prefix_private_cluster = var.dns_prefix_private_cluster image_cleaner_enabled = var.image_cleaner_enabled image_cleaner_interval_hours = var.image_cleaner_interval_hours kubernetes_version = var.kubernetes_version @@ -603,8 +604,8 @@ resource "azurerm_kubernetes_cluster" "main" { error_message = "When ebpf_data_plane is set to cilium, one of either network_plugin_mode = `overlay` or pod_subnet_id must be specified." } precondition { - condition = can(coalesce(var.cluster_name, var.prefix)) - error_message = "You must set one of `var.cluster_name` and `var.prefix` to create `azurerm_kubernetes_cluster.main`." + condition = can(coalesce(var.cluster_name, var.prefix, var.dns_prefix_private_cluster)) + error_message = "You must set one of `var.cluster_name`,`var.prefix`,`var.dns_prefix_private_cluster` to create `azurerm_kubernetes_cluster.main`." } precondition { condition = var.automatic_channel_upgrade != "node-image" || var.node_os_channel_upgrade == "NodeImage" @@ -623,6 +624,22 @@ resource "azurerm_kubernetes_cluster" "main" { condition = var.brown_field_application_gateway_for_ingress == null || var.green_field_application_gateway_for_ingress == null error_message = "Either one of `var.brown_field_application_gateway_for_ingress` or `var.green_field_application_gateway_for_ingress` must be `null`." } + precondition { + condition = var.prefix == null || var.dns_prefix_private_cluster == null + error_message = "Only one of `var.prefix,var.dns_prefix_private_cluster` can be specified." + } + precondition { + condition = var.dns_prefix_private_cluster == null || var.private_cluster_enabled + error_message = "When `dns_prefix_private_cluster` is set, `private_cluster_enabled` must be set to `true`." + } + precondition { + condition = var.dns_prefix_private_cluster != null || var.identity_type == "UserAssigned" || var.client_id != "" + error_message = "A user assigned identity or a service principal must be used when using a custom private dns zone" + } + 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`" + } } } diff --git a/variables.tf b/variables.tf index 5f304b2f..519d7491 100644 --- a/variables.tf +++ b/variables.tf @@ -454,6 +454,12 @@ variable "disk_encryption_set_id" { description = "(Optional) The ID of the Disk Encryption Set which should be used for the Nodes and Volumes. More information [can be found in the documentation](https://docs.microsoft.com/azure/aks/azure-disk-customer-managed-keys). Changing this forces a new resource to be created." } +variable "dns_prefix_private_cluster" { + type = string + default = null + description = "(Optional) Specifies the DNS prefix to use with private clusters. Only one of `var.prefix,var.dns_prefix_private_cluster` can be specified. Changing this forces a new resource to be created." +} + variable "ebpf_data_plane" { type = string default = null @@ -1217,8 +1223,7 @@ variable "pod_subnet_id" { variable "prefix" { type = string default = "" - description = "(Optional) The prefix for the resources created in the specified Azure Resource Group. Omitting this variable requires both `var.cluster_log_analytics_workspace_name` and `var.cluster_name` have been set." - nullable = false + description = "(Optional) The prefix for the resources created in the specified Azure Resource Group. Omitting this variable requires both `var.cluster_log_analytics_workspace_name` and `var.cluster_name` have been set. Only one of `var.prefix,var.dns_prefix_private_cluster` can be specified." } variable "private_cluster_enabled" {