Menu

Virtual Geek

Tales from real IT system administrators world and non-production environment

Creating a Private Endpoint for Azure Storage Account with Terraform example 2

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.

Microsoft Azure Private Endpoint blob table file share queue resource group terraform tf configuration file Storage Account automation IAC infrastructure as a code location network interface private dns zone subnet virtual network id.png

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

Go Back

Comment

Blog Search

Page Views

12167560

Follow me on Blogarama