This part is a revised earlier article of Terraform Azure Create Private Endpoint to existing Storage Account with Custom Private DNS zone record link. when I raised PR (Pull Request) for this configuration, Reviewer asked me to make some changes such way that while creating Private Endpoint, name of the sub resources should reflect on the header like shown in the below screenshot. Earlier it was showing only for_each loop iteration numbers. And another change was I wanted to deploy Private Endpoint resources according to Storage account kind, tier and replication mode. As sub resources are available based on the combination of these 3 items - kind, tier and replication mode type values.
Here in this configuration script, I have defined map in private service connections variable. Next in the locals variable I am using lookup() function using combination of storage account replication type, tier and kind to find the appropriate list in Private Service Connection variable. Local variable is converted to toset() function and used in for_each loop and accordingly created Private Endpoints.
Download this configuration script file Terraform Azure Storage Account_Private Endpoint.zip or also available on github.com.
#variables.tf variable "resource_group_name" { type = string default = "vcloud-lab.com" description = "value" } variable "virtual_network_name" { type = string default = "vcloud_lab_global_vnet01" description = "value" } variable "subnet_name" { type = string default = "default" description = "value" } variable "storage_account_name" { type = string default = "vcloudlabsademo01" description = "value" } variable "storage_account_tier" { type = string default = "Standard" #Standard,Premium | (For Premium only BlockBlobStorage And FileStorage) description = "value" } variable "storage_account_kind" { type = string default = "StorageV2" #BlobStorage,BlockBlobStorage,FileStorage,Storage,StorageV2 | (default: StorageV2) description = "value" } variable "storage_account_replication_type" { type = string default = "LRS" #"LRS" "ZRS" "GRS" "RAGRS" "GZRS" "RAGZRS" | Default: description = "value" } variable "private_endpoint_name" { type = string default = "vcloud-lab-endpoint" description = "value" } variable "private_service_connection_name" { type = string default = "privateendpointserviceconnection" description = "value" } variable "private_dns_zone_group_name" { type = string default = "privateendpointdnzzonegroup" description = "value" } variable "private_service_connections" { description = "A map of DNS records to create based on the storage account kind" type = map(any) default = { standardlrsstoragev2 = ["blob", "file"] premiumlrsstoragev2 = ["file"] blobstorage = ["blob"] } } #main.tf terraform { required_providers { azurerm = { source = "hashicorp/azurerm" #version = "=2.91.0" } } } # Configure the Microsoft Azure Provider provider "azurerm" { features {} } data "azurerm_subscription" "subscriptioninfo" {} data "azurerm_resource_group" "rginfo" { name = var.resource_group_name } data "azurerm_virtual_network" "vnetinfo" { name = var.virtual_network_name resource_group_name = data.azurerm_resource_group.rginfo.name } data "azurerm_subnet" "subnetinfo" { name = var.subnet_name resource_group_name = data.azurerm_resource_group.rginfo.name virtual_network_name = data.azurerm_virtual_network.vnetinfo.name } resource "azurerm_storage_account" "storageaccount" { name = var.storage_account_name resource_group_name = data.azurerm_resource_group.rginfo.name location = data.azurerm_resource_group.rginfo.location account_kind = var.storage_account_kind account_tier = var.storage_account_tier account_replication_type = var.storage_account_replication_type public_network_access_enabled = false } locals { selected_private_endpoint = lookup(var.private_service_connections, lower("${var.storage_account_tier}${var.storage_account_replication_type}${var.storage_account_kind}"), []) } resource "azurerm_private_endpoint" "privateendpoint" { for_each = toset(local.selected_private_endpoint) #{ for ep, connection in local.selected_private_endpoint : ep => ep } # ep => connection name = "${var.private_endpoint_name}-${each.key}" resource_group_name = data.azurerm_resource_group.rginfo.name location = data.azurerm_resource_group.rginfo.location subnet_id = data.azurerm_subnet.subnetinfo.id custom_network_interface_name = "${var.private_endpoint_name}-${each.value}-nic" private_service_connection { name = "${var.private_service_connection_name}-${each.value}" private_connection_resource_id = resource.azurerm_storage_account.storageaccount.id subresource_names = [each.value] is_manual_connection = false } private_dns_zone_group { name = var.private_dns_zone_group_name private_dns_zone_ids = ["/subscriptions/${data.azurerm_subscription.subscriptioninfo.subscription_id}/resourceGroups/${data.azurerm_resource_group.rginfo.name}/providers/Microsoft.Network/privateDnsZones/privatelink.${each.value}.core.windows.net"] } }
Below is the output, although result is same, but still some improvements from earlier script Terraform Azure Create Private Endpoint to existing Storage Account with Custom Private DNS zone record link.
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 |
terraform apply --auto-approve data.azurerm_subscription.subscriptioninfo: Reading... data.azurerm_resource_group.rginfo: Reading... data.azurerm_subscription.subscriptioninfo: Read complete after 0s [id=/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx] data.azurerm_resource_group.rginfo: Read complete after 1s [id=/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/vcloud-lab.com] data.azurerm_virtual_network.vnetinfo: Reading... data.azurerm_virtual_network.vnetinfo: Read complete after 0s [id=/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/virtualNetworks/vcloud_lab_global_vnet01] data.azurerm_subnet.subnetinfo: Reading... data.azurerm_subnet.subnetinfo: Read complete after 1s [id=/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/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_endpoint.privateendpoint["blob"] will be created + resource "azurerm_private_endpoint" "privateendpoint" { + custom_dns_configs = (known after apply) + custom_network_interface_name = "vcloud-lab-endpoint-blob-nic" + id = (known after apply) + location = "eastus" + name = "vcloud-lab-endpoint-blob" + network_interface = (known after apply) + private_dns_zone_configs = (known after apply) + resource_group_name = "vcloud-lab.com" + subnet_id = "/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/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/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net", ] } + private_service_connection { + is_manual_connection = false + name = "privateendpointserviceconnection-blob" + private_connection_resource_id = (known after apply) + private_ip_address = (known after apply) + subresource_names = [ + "blob", ] } } # azurerm_private_endpoint.privateendpoint["file"] will be created + resource "azurerm_private_endpoint" "privateendpoint" { + custom_dns_configs = (known after apply) + custom_network_interface_name = "vcloud-lab-endpoint-file-nic" + id = (known after apply) + location = "eastus" + name = "vcloud-lab-endpoint-file" + network_interface = (known after apply) + private_dns_zone_configs = (known after apply) + resource_group_name = "vcloud-lab.com" + subnet_id = "/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/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/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/privateDnsZones/privatelink.file.core.windows.net", ] } + private_service_connection { + is_manual_connection = false + name = "privateendpointserviceconnection-file" + private_connection_resource_id = (known after apply) + private_ip_address = (known after apply) + subresource_names = [ + "file", ] } } # azurerm_storage_account.storageaccount will be created + resource "azurerm_storage_account" "storageaccount" { + access_tier = (known after apply) + account_kind = "StorageV2" + account_replication_type = "LRS" + account_tier = "Standard" + allow_nested_items_to_be_public = true + cross_tenant_replication_enabled = true + default_to_oauth_authentication = false + dns_endpoint_type = "Standard" + enable_https_traffic_only = true + id = (known after apply) + infrastructure_encryption_enabled = false + is_hns_enabled = false + large_file_share_enabled = (known after apply) + local_user_enabled = true + location = "eastus" + min_tls_version = "TLS1_2" + name = "vcloudlabsademo01" + nfsv3_enabled = false + primary_access_key = (sensitive value) + primary_blob_connection_string = (sensitive value) + primary_blob_endpoint = (known after apply) + primary_blob_host = (known after apply) + primary_blob_internet_endpoint = (known after apply) + primary_blob_internet_host = (known after apply) + primary_blob_microsoft_endpoint = (known after apply) + primary_blob_microsoft_host = (known after apply) + primary_connection_string = (sensitive value) + primary_dfs_endpoint = (known after apply) + primary_dfs_host = (known after apply) + primary_dfs_internet_endpoint = (known after apply) + primary_dfs_internet_host = (known after apply) + primary_dfs_microsoft_endpoint = (known after apply) + primary_dfs_microsoft_host = (known after apply) + primary_file_endpoint = (known after apply) + primary_file_host = (known after apply) + primary_file_internet_endpoint = (known after apply) + primary_file_internet_host = (known after apply) + primary_file_microsoft_endpoint = (known after apply) + primary_file_microsoft_host = (known after apply) + primary_location = (known after apply) + primary_queue_endpoint = (known after apply) + primary_queue_host = (known after apply) + primary_queue_microsoft_endpoint = (known after apply) + primary_queue_microsoft_host = (known after apply) + primary_table_endpoint = (known after apply) + primary_table_host = (known after apply) + primary_table_microsoft_endpoint = (known after apply) + primary_table_microsoft_host = (known after apply) + primary_web_endpoint = (known after apply) + primary_web_host = (known after apply) + primary_web_internet_endpoint = (known after apply) + primary_web_internet_host = (known after apply) + primary_web_microsoft_endpoint = (known after apply) + primary_web_microsoft_host = (known after apply) + public_network_access_enabled = false + queue_encryption_key_type = "Service" + resource_group_name = "vcloud-lab.com" + secondary_access_key = (sensitive value) + secondary_blob_connection_string = (sensitive value) + secondary_blob_endpoint = (known after apply) + secondary_blob_host = (known after apply) + secondary_blob_internet_endpoint = (known after apply) + secondary_blob_internet_host = (known after apply) + secondary_blob_microsoft_endpoint = (known after apply) + secondary_blob_microsoft_host = (known after apply) + secondary_connection_string = (sensitive value) + secondary_dfs_endpoint = (known after apply) + secondary_dfs_host = (known after apply) + secondary_dfs_internet_endpoint = (known after apply) + secondary_dfs_internet_host = (known after apply) + secondary_dfs_microsoft_endpoint = (known after apply) + secondary_dfs_microsoft_host = (known after apply) + secondary_file_endpoint = (known after apply) + secondary_file_host = (known after apply) + secondary_file_internet_endpoint = (known after apply) + secondary_file_internet_host = (known after apply) + secondary_file_microsoft_endpoint = (known after apply) + secondary_file_microsoft_host = (known after apply) + secondary_location = (known after apply) + secondary_queue_endpoint = (known after apply) + secondary_queue_host = (known after apply) + secondary_queue_microsoft_endpoint = (known after apply) + secondary_queue_microsoft_host = (known after apply) + secondary_table_endpoint = (known after apply) + secondary_table_host = (known after apply) + secondary_table_microsoft_endpoint = (known after apply) + secondary_table_microsoft_host = (known after apply) + secondary_web_endpoint = (known after apply) + secondary_web_host = (known after apply) + secondary_web_internet_endpoint = (known after apply) + secondary_web_internet_host = (known after apply) + secondary_web_microsoft_endpoint = (known after apply) + secondary_web_microsoft_host = (known after apply) + sftp_enabled = false + shared_access_key_enabled = true + table_encryption_key_type = "Service" } Plan: 3 to add, 0 to change, 0 to destroy. azurerm_storage_account.storageaccount: Creating... azurerm_storage_account.storageaccount: Still creating... [10s elapsed] azurerm_storage_account.storageaccount: Still creating... [20s elapsed] azurerm_storage_account.storageaccount: Still creating... [30s elapsed] azurerm_storage_account.storageaccount: Creation complete after 38s [id=/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.Storage/storageAccounts/vcloudlabsademo01] azurerm_private_endpoint.privateendpoint["file"]: Creating... azurerm_private_endpoint.privateendpoint["blob"]: Creating... azurerm_private_endpoint.privateendpoint["file"]: Still creating... [10s elapsed] azurerm_private_endpoint.privateendpoint["blob"]: Still creating... [10s elapsed] azurerm_private_endpoint.privateendpoint["file"]: Still creating... [20s elapsed] azurerm_private_endpoint.privateendpoint["blob"]: Still creating... [20s elapsed] azurerm_private_endpoint.privateendpoint["file"]: Still creating... [30s elapsed] azurerm_private_endpoint.privateendpoint["blob"]: Still creating... [30s elapsed] azurerm_private_endpoint.privateendpoint["file"]: Still creating... [40s elapsed] azurerm_private_endpoint.privateendpoint["blob"]: Still creating... [40s elapsed] azurerm_private_endpoint.privateendpoint["file"]: Still creating... [50s elapsed] azurerm_private_endpoint.privateendpoint["blob"]: Still creating... [50s elapsed] azurerm_private_endpoint.privateendpoint["blob"]: Creation complete after 59s [id=/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/privateEndpoints/vcloud-lab-endpoint-blob] azurerm_private_endpoint.privateendpoint["file"]: Still creating... [1m0s elapsed] azurerm_private_endpoint.privateendpoint["file"]: Creation complete after 1m0s [id=/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/vcloud-lab.com/providers/Microsoft.Network/privateEndpoints/vcloud-lab-endpoint-file] Apply complete! Resources: 3 added, 0 changed, 0 destroyed. |
Useful Articles
Terraform clone virtual machine template in VMware vSphere vCenter from CSV file
Terraform error retrieving storage account failure responding to request StatusCode 404 StorageAccountNotFound The storage account was not found
Terraform testing local variables and output csv file without resource Part 1
Terraform testing variable map object values without resource configuration part 2
Terraform foreach module output to show only required results
Terraform deploy create A Private DNS Record in Microsoft Azure from list of objects
Terraform clone virtual machine template in VMware vSphere vCenter Dynamic Content Part 2
Creating a Private Endpoint for Azure Storage Account with required sub services using Terraform
Terraform Azure Create Private Endpoint to existing Storage Account with Custom Private DNS zone record link
Using terraform to clone a virtual machine on VMware vSphere infrastructure
Terraform module clone VMware vSphere Linux and Windows virtual machine
Terraform VMware vSphere Virtual Machine customization clone failed on Windows
Terraform VMware vSphere Virtual Machine cloning Operating system not found