I had a task to create Private Endpoint in Microsoft Azure and was requirement to automate this job using HashiCorp Terraform automation tf configuration files. This Private endpoint will be linked to existing Storage Account and Virtual Network. Other required sub resources Virtual Network Links and other connection and Private DNS zone A record will be created in custom Private DNS zone.
Related Articles - Creating a Private Endpoint for Azure Storage Account with required sub resources using Terraform
This is the output after applying terraform configuration. It fetches and register data of existing Resource Group, Private DNS zone, Virtual Network, Subnet, Storage Account. These resource are already present on Azure cloud. After using data it configures new environment Private Endpoint and related resources.
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 |
terraform apply --auto-approve data.azurerm_resource_group.rginfo: Reading... data.azurerm_resource_group.rginfo: Read complete after 0s [id=/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vcloud-lab.com] data.azurerm_private_dns_zone.privatednszoneinfo: Reading... data.azurerm_virtual_network.vnetinfo: Reading... data.azurerm_storage_account.storageaccountinfo: Reading... data.azurerm_private_dns_zone.privatednszoneinfo: Read complete after 0s [id=/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/privateDnsZones/vcloud-lab.com] data.azurerm_virtual_network.vnetinfo: Read complete after 1s [id=/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/virtualNetworks/vcloud_lab_global_vnet01] data.azurerm_subnet.subnetinfo: Reading... data.azurerm_storage_account.storageaccountinfo: Read complete after 1s [id=/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vcloud-lab.com/providers/Microsoft.Storage/storageAccounts/vcloudlabdemo01] data.azurerm_subnet.subnetinfo: Read complete after 0s [id=/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/virtualNetworks/vcloud_lab_global_vnet01/subnets/default] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # azurerm_private_dns_a_record.private_dns_a_record will be created + resource "azurerm_private_dns_a_record" "private_dns_a_record" { + fqdn = (known after apply) + id = (known after apply) + name = "vcloudlabdemo01" + records = (known after apply) + resource_group_name = "vcloud-lab.com" + ttl = 300 + zone_name = "vcloud-lab.com" } # azurerm_private_dns_zone_virtual_network_link.networklink will be created + resource "azurerm_private_dns_zone_virtual_network_link" "networklink" { + id = (known after apply) + name = "privatednsnetworklink" + private_dns_zone_name = "vcloud-lab.com" + registration_enabled = false + resource_group_name = "vcloud-lab.com" + virtual_network_id = "/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/virtualNetworks/vcloud_lab_global_vnet01" } # azurerm_private_endpoint.privateendpoint will be created + resource "azurerm_private_endpoint" "privateendpoint" { + custom_dns_configs = (known after apply) + id = (known after apply) + location = "eastus" + name = "vcloud-lab-endpoint" + network_interface = (known after apply) + private_dns_zone_configs = (known after apply) + resource_group_name = "vcloud-lab.com" + subnet_id = "/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/virtualNetworks/vcloud_lab_global_vnet01/subnets/default" + private_dns_zone_group { + id = (known after apply) + name = "privateendpointdnzzonegroup" + private_dns_zone_ids = [ + "/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/privateDnsZones/vcloud-lab.com", ] } + private_service_connection { + is_manual_connection = false + name = "privateendpointserviceconnection" + "blob", ] } } Plan: 3 to add, 0 to change, 0 to destroy. Changes to Outputs: + name = (known after apply) azurerm_private_dns_zone_virtual_network_link.networklink: Creating... azurerm_private_endpoint.privateendpoint: Creating... azurerm_private_endpoint.privateendpoint: Still creating... [10s elapsed] azurerm_private_dns_zone_virtual_network_link.networklink: Still creating... [10s elapsed] azurerm_private_endpoint.privateendpoint: Still creating... [20s elapsed] azurerm_private_dns_zone_virtual_network_link.networklink: Still creating... [20s elapsed] azurerm_private_dns_zone_virtual_network_link.networklink: Still creating... [30s elapsed] azurerm_private_endpoint.privateendpoint: Still creating... [30s elapsed] azurerm_private_dns_zone_virtual_network_link.networklink: Still creating... [40s elapsed] azurerm_private_endpoint.privateendpoint: Still creating... [40s elapsed] azurerm_private_endpoint.privateendpoint: Still creating... [50s elapsed] azurerm_private_dns_zone_virtual_network_link.networklink: Still creating... [50s elapsed] azurerm_private_endpoint.privateendpoint: Creation complete after 59s [id=/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/privateEndpoints/vcloud-lab-endpoint] azurerm_private_dns_a_record.private_dns_a_record: Creating... azurerm_private_dns_zone_virtual_network_link.networklink: Still creating... [1m0s elapsed] azurerm_private_dns_a_record.private_dns_a_record: Creation complete after 3s [id=/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/privateDnsZones/vcloud-lab.com/A/vcloudlabdemo01] azurerm_private_dns_zone_virtual_network_link.networklink: Creation complete after 1m6s [id=/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/privateDnsZones/vcloud-lab.com/virtualNetworkLinks/privatednsnetworklink] Apply complete! Resources: 3 added, 0 changed, 0 destroyed. Outputs: name = "10.0.0.4" |
Once Terraform Apply is completed successfully, I can confirm and verify, resources are deployed successfully in the Resource Group with Private Endpoint and its associated network interface.
Next if I deep dive into Private Endpoint DNS configuration, I see Custom DNS zone group and Customer Visible FQDNs are integrated and created successfully
In the existing Storage Account section Private endpoint connections, I can see connection state is approved and created with connected Virtual Network.
Next in the Private DNS zone service, under DNS Management >> Recordsets required DNS A record is created and Virtual Network Links is created with selected vNet.
Download this terraform configuration file main.tf or it is also available on github.com.
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 |
terraform { required_providers { azurerm = { source = "hashicorp/azurerm" #version = "=2.91.0" } } } # Configure the Microsoft Azure Provider provider "azurerm" { features {} } data "azurerm_resource_group" "rginfo" { name = "vcloud-lab.com" } data "azurerm_virtual_network" "vnetinfo" { name = "vcloud_lab_global_vnet01" resource_group_name = data.azurerm_resource_group.rginfo.name } data "azurerm_subnet" "subnetinfo" { name = "default" resource_group_name = data.azurerm_resource_group.rginfo.name virtual_network_name = data.azurerm_virtual_network.vnetinfo.name } data "azurerm_private_dns_zone" "privatednszoneinfo" { name = "vcloud-lab.com" resource_group_name = data.azurerm_resource_group.rginfo.name } data "azurerm_storage_account" "storageaccountinfo" { name = "vcloudlabdemo01" resource_group_name = data.azurerm_resource_group.rginfo.name } resource "azurerm_private_endpoint" "privateendpoint" { name = "vcloud-lab-endpoint" resource_group_name = data.azurerm_resource_group.rginfo.name location = data.azurerm_resource_group.rginfo.location subnet_id = data.azurerm_subnet.subnetinfo.id private_service_connection { name = "privateendpointserviceconnection" private_connection_resource_id = data.azurerm_storage_account.storageaccountinfo.id subresource_names = ["blob"] is_manual_connection = false } private_dns_zone_group { name = "privateendpointdnzzonegroup" private_dns_zone_ids = [data.azurerm_private_dns_zone.privatednszoneinfo.id] } } resource "azurerm_private_dns_zone_virtual_network_link" "networklink" { name = "privatednsnetworklink" resource_group_name = data.azurerm_resource_group.rginfo.name private_dns_zone_name = data.azurerm_private_dns_zone.privatednszoneinfo.name virtual_network_id = data.azurerm_virtual_network.vnetinfo.id } resource "azurerm_private_dns_a_record" "private_dns_a_record" { name = data.azurerm_storage_account.storageaccountinfo.name zone_name = data.azurerm_private_dns_zone.privatednszoneinfo.name resource_group_name = data.azurerm_resource_group.rginfo.name ttl = 300 records = [resource.azurerm_private_endpoint.privateendpoint.private_service_connection[0].private_ip_address] } output "name" { value = resource.azurerm_private_endpoint.privateendpoint.private_service_connection[0].private_ip_address } |
Useful Articles
Hashicorp Terraform map and object inside module and variable example
Terraform one module deploy null or multiple resources based on input
Terraform A reference to a resource type must be followed by at least one attribute access, specifying the resource name
Terraform fore_each for loop filter with if condition example
Terraform remote-exec provisioner with ssh connection in null_resource
Terraform count vs for_each for examples with map of objects
Terraform one module deploy null or multiple resources based on input (nested for loop) Example of flatten and coalesce
Using element function with count meta argument example Terraform Azure subnets