<p>I am trying to provision a <strong>private AKS cluster</strong> using terraform. I want to connect my private AKS cluster to <strong>an existing VNET</strong> that I have created using the Azure portal.</p>
<p>The Virtual network option is available in the Azure portal. Please find the below image.</p>
<p><a href="https://i.stack.imgur.com/9sueQ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/9sueQ.png" alt="enter image description here" /></a></p>
<p>However, the terraform documentation on <a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster" rel="nofollow noreferrer">azurerm_kubernetes_cluster</a> has very limited information on how to achieve that.</p>
<p>Please find my <code>main.tf</code> below</p>
<pre><code>resource &quot;azurerm_kubernetes_cluster&quot; &quot;kubernetes_cluster&quot; {                                                                
  name                    = var.cluster_name                                                                                
  location                = var.location                                                                                    
  resource_group_name     = var.resource_group_name                                                                         
  private_cluster_enabled = true                                                                                            
                                                                                                                            
  default_node_pool {                                                                                                       
    name           = &quot;default&quot;                                                                                              
    node_count     = var.node_count                                                                                         
    vm_size        = var.vm_size                                                                                            
    max_pods       = var.max_pods_count                                                                                     
  }                                                                                                                         
                                                                                                                            
  kube_dashboard {                                                                                                          
    enabled = true                                                                                                          
  }                                                                                                                         
                                                                                                                            
  network_profile {                                                                                                         
    network_plugin = &quot;azure&quot;   
  }                                                                                             
} 
</code></pre>
<p><strong>Please note that the VNET and the cluster that is to be created share the same location and resource group.</strong></p>
<p>Any help on how to provision a private AKS cluster to an existing VNET using Terraform would be much appreciated.</p>

<p>I used an existing code from Github with some changes as we already have vnet so instead of resource block I have used data block to get the details of the existing Vnet and instead of using the default subnet I created a subnet for aks and other one for firewall.</p>
<pre><code>terraform {
  required_version = &quot;&gt;= 0.14&quot;
  required_providers {
    azurerm = {
      source  = &quot;hashicorp/azurerm&quot;
      version = &quot;&gt;=2.50.0&quot;
    }
  }
}

provider &quot;azurerm&quot; {
  features {}
}

#local vars

locals {
  environment     = &quot;test&quot;
  resource_group = &quot;AKS-test&quot;
  resource_group_location = &quot;East US&quot;
  name_prefix     = &quot;private-aks&quot;
  aks_node_prefix = [&quot;10.3.1.0/24&quot;]
  firewall_prefix = [&quot;10.3.2.0/24&quot;]
}

#Existing vnet with address space &quot;10.3.0.0/16&quot;
data &quot;azurerm_virtual_network&quot; &quot;base&quot; {
  name                = &quot;existing-vnet&quot;
  resource_group_name = &quot;AKS-test&quot;
}

#subnets

resource &quot;azurerm_subnet&quot; &quot;aks&quot; {
  name                 = &quot;snet-${local.name_prefix}-${local.environment}&quot;
  resource_group_name  = local.resource_group
  address_prefixes     = local.aks_node_prefix
  virtual_network_name = data.azurerm_virtual_network.base.name
}

resource &quot;azurerm_subnet&quot; &quot;firewall&quot; {
  name                 = &quot;AzureFirewallSubnet&quot;
  resource_group_name  = local.resource_group
  virtual_network_name = data.azurerm_virtual_network.base.name
  address_prefixes     = local.firewall_prefix
}

#user assigned identity

resource &quot;azurerm_user_assigned_identity&quot; &quot;base&quot; {
  resource_group_name = local.resource_group
  location            = local.resource_group_location
  name                = &quot;mi-${local.name_prefix}-${local.environment}&quot;
}

#role assignment

resource &quot;azurerm_role_assignment&quot; &quot;base&quot; {
  scope                = &quot;/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/AKS-test&quot;
  role_definition_name = &quot;Network Contributor&quot;
  principal_id         = azurerm_user_assigned_identity.base.principal_id
}

#route table

resource &quot;azurerm_route_table&quot; &quot;base&quot; {
  name                = &quot;rt-${local.name_prefix}-${local.environment}&quot;
  location            = data.azurerm_virtual_network.base.location
  resource_group_name = local.resource_group
}

#route 

resource &quot;azurerm_route&quot; &quot;base&quot; {
  name                   = &quot;dg-${local.environment}&quot;
  resource_group_name    = local.resource_group
  route_table_name       = azurerm_route_table.base.name
  address_prefix         = &quot;0.0.0.0/0&quot;
  next_hop_type          = &quot;VirtualAppliance&quot;
  next_hop_in_ip_address = azurerm_firewall.base.ip_configuration.0.private_ip_address
}

#route table association

resource &quot;azurerm_subnet_route_table_association&quot; &quot;base&quot; {
  subnet_id      = azurerm_subnet.aks.id
  route_table_id = azurerm_route_table.base.id
}

#firewall

resource &quot;azurerm_public_ip&quot; &quot;base&quot; {
  name                = &quot;pip-firewall&quot;
  location            = data.azurerm_virtual_network.base.location
  resource_group_name = local.resource_group
  allocation_method   = &quot;Static&quot;
  sku                 = &quot;Standard&quot;
}

resource &quot;azurerm_firewall&quot; &quot;base&quot; {
  name                = &quot;fw-${local.name_prefix}-${local.environment}&quot;
  location            = data.azurerm_virtual_network.base.location
  resource_group_name = local.resource_group

  ip_configuration {
    name                 = &quot;ip-${local.name_prefix}-${local.environment}&quot;
    subnet_id            = azurerm_subnet.firewall.id
    public_ip_address_id = azurerm_public_ip.base.id
  }
}

#kubernetes_cluster

resource &quot;azurerm_kubernetes_cluster&quot; &quot;base&quot; {
  name                    = &quot;${local.name_prefix}-${local.environment}&quot;
  location                = local.resource_group_location
  resource_group_name     = local.resource_group
  dns_prefix              = &quot;dns-${local.name_prefix}-${local.environment}&quot;
  private_cluster_enabled = true

  network_profile {
    network_plugin = &quot;azure&quot;
    outbound_type  = &quot;userDefinedRouting&quot;
  }

  default_node_pool {
    name           = &quot;default&quot;
    node_count     = 1
    vm_size        = &quot;Standard_D2_v2&quot;
    vnet_subnet_id = azurerm_subnet.aks.id
  }

  identity {
    type                      = &quot;UserAssigned&quot;
    user_assigned_identity_id = azurerm_user_assigned_identity.base.id
  }
  depends_on = [
      azurerm_route.base,
      azurerm_role_assignment.base
    ]
}
</code></pre>
<p><strong>Reference:</strong> <a href="https://github.com/kuhlman-labs/terraform_azurerm_aks_private_cluster" rel="nofollow noreferrer">Github</a></p>
<p><strong>Before Test:</strong></p>
<p><a href="https://i.stack.imgur.com/6RboM.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/6RboM.png" alt="enter image description here" /></a></p>
<p><strong>Doing a terraform Plan on the above code:</strong></p>
<p><a href="https://i.stack.imgur.com/FoTBv.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FoTBv.png" alt="enter image description here" /></a></p>
<p><strong>After applying the code:</strong></p>
<p><a href="https://i.stack.imgur.com/U0DGX.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/U0DGX.png" alt="enter image description here" /></a></p>
<p><strong>After the deployment :</strong></p>
<p><a href="https://i.stack.imgur.com/oNYXq.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/oNYXq.png" alt="enter image description here" /></a></p>
