Not possible to configure static ip for private endpoints
bryansan-msft opened this issue · 5 comments
Is there an existing issue for this?
- I have searched the existing issues
Greenfield/Brownfield provisioning
greenfield
Terraform Version
1.7.5
Module Version
0.1.1
AzureRM Provider Version
3.102.0
Affected Resource(s)/Data Source(s)
azurerm_private_endpoint
Terraform Configuration Files
terraform {
required_version = ">= 1.0.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.7.0, < 4.0.0"
}
random = {
source = "hashicorp/random"
version = ">= 3.5.0, < 4.0.0"
}
}
}
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
skip_provider_registration = true
storage_use_azuread = true
}
locals {
test_regions = ["eastus", "eastus2", "westu2", "westus3"]
}
# This allows us to randomize the region for the resource group.
resource "random_integer" "region_index" {
max = length(local.test_regions) - 1
min = 0
}
# This allow use to randomize the name of resources
resource "random_string" "this" {
length = 6
special = false
upper = false
}
# This ensures we have unique CAF compliant names for our resources.
module "naming" {
source = "Azure/naming/azurerm"
version = "0.4.0"
}
resource "azurerm_resource_group" "this" {
location = local.test_regions[random_integer.region_index.result]
name = module.naming.resource_group.name_unique
}
resource "azurerm_virtual_network" "vnet" {
address_space = ["192.168.0.0/16"]
location = azurerm_resource_group.this.location
name = module.naming.virtual_network.name_unique
resource_group_name = azurerm_resource_group.this.name
}
resource "azurerm_subnet" "private" {
address_prefixes = ["192.168.0.0/24"]
name = module.naming.subnet.name_unique
resource_group_name = azurerm_resource_group.this.name
virtual_network_name = azurerm_virtual_network.vnet.name
service_endpoints = ["Microsoft.Storage"]
}
resource "azurerm_network_security_group" "nsg" {
location = azurerm_resource_group.this.location
name = module.naming.network_security_group.name_unique
resource_group_name = azurerm_resource_group.this.name
}
resource "azurerm_subnet_network_security_group_association" "private" {
network_security_group_id = azurerm_network_security_group.nsg.id
subnet_id = azurerm_subnet.private.id
}
resource "azurerm_network_security_rule" "no_internet" {
access = "Deny"
direction = "Outbound"
name = module.naming.network_security_rule.name_unique
network_security_group_name = azurerm_network_security_group.nsg.name
priority = 100
protocol = "*"
resource_group_name = azurerm_resource_group.this.name
destination_address_prefix = "Internet"
destination_port_range = "*"
source_address_prefix = azurerm_subnet.private.address_prefixes[0]
source_port_range = "*"
}
locals {
endpoints = toset(["blob"])
}
module "public_ip" {
count = var.bypass_ip_cidr == null ? 1 : 0
source = "lonegunmanb/public-ip/lonegunmanb"
version = "0.1.0"
}
resource "azurerm_private_dns_zone" "this" {
for_each = local.endpoints
name = "privatelink.${each.value}.core.windows.net"
resource_group_name = azurerm_resource_group.this.name
tags = {
env = "Dev"
}
}
resource "azurerm_private_dns_zone_virtual_network_link" "private_links" {
for_each = azurerm_private_dns_zone.this
name = "${each.key}_${azurerm_virtual_network.vnet.name}-link"
private_dns_zone_name = azurerm_private_dns_zone.this[each.key].name
resource_group_name = azurerm_resource_group.this.name
virtual_network_id = azurerm_virtual_network.vnet.id
}
data "azurerm_client_config" "current" {}
resource "azurerm_user_assigned_identity" "example_identity" {
location = azurerm_resource_group.this.location
name = module.naming.user_assigned_identity.name_unique
resource_group_name = azurerm_resource_group.this.name
}
data "azurerm_role_definition" "example" {
name = "Contributor"
}
#create azure storage account
module "this" {
source = "../.."
account_replication_type = "ZRS"
account_tier = "Standard"
account_kind = "StorageV2"
location = azurerm_resource_group.this.location
name = module.naming.storage_account.name_unique
resource_group_name = azurerm_resource_group.this.name
min_tls_version = "TLS1_2"
shared_access_key_enabled = true
public_network_access_enabled = true
use_nested_nacl = false
#use_nested_nacl = true
managed_identities = {
system_assigned = true
user_assigned_resource_ids = [azurerm_user_assigned_identity.example_identity.id]
}
tags = {
env = "Dev"
owner = "John Doe"
dept = "IT"
}
/*lock = {
name = "lock"
kind = "None"
} */
role_assignments = {
role_assignment_1 = {
role_definition_id_or_name = data.azurerm_role_definition.example.id
principal_id = data.azurerm_client_config.current.object_id
skip_service_principal_aad_check = false
},
role_assignment_2 = {
role_definition_id_or_name = "Owner"
principal_id = data.azurerm_client_config.current.object_id
skip_service_principal_aad_check = false
},
}
network_rules = {
bypass = ["AzureServices"]
default_action = "Deny"
ip_rules = [try(module.public_ip[0].public_ip, var.bypass_ip_cidr)]
virtual_network_subnet_ids = toset([azurerm_subnet.private.id])
}
containers = {
blob_container0 = {
name = "blob-container-${random_string.this.result}-0"
container_access_type = "private"
}
blob_container1 = {
name = "blob-container-${random_string.this.result}-1"
container_access_type = "private"
}
}
queues = {
queue0 = {
name = "queue-${random_string.this.result}-0"
}
queue1 = {
name = "queue-${random_string.this.result}-1"
}
}
tables = {
table0 = {
name = "table${random_string.this.result}0"
}
table1 = {
name = "table${random_string.this.result}1"
}
}
shares = {
share0 = {
name = "share-${random_string.this.result}-0"
quota = 10
}
share1 = {
name = "share-${random_string.this.result}-1"
quota = 10
}
}
#create a private endpoint for each endpoint type
private_endpoints = {
for endpoint in local.endpoints :
endpoint => {
# the name must be set to avoid conflicting resources.
name = "pe-${endpoint}-${module.naming.storage_account.name_unique}"
subnet_resource_id = azurerm_subnet.private.id
subresource_name = [endpoint]
private_dns_zone_resource_ids = [azurerm_private_dns_zone.this[endpoint].id]
# these are optional but illustrate making well-aligned service connection & NIC names.
private_service_connection_name = "psc-${endpoint}-${module.naming.storage_account.name_unique}"
network_interface_name = "nic-pe-${endpoint}-${module.naming.storage_account.name_unique}"
inherit_tags = false
inherit_lock = false
ip_configurations = {
staticIpConfig = {
name = "staticIpConfig"
private_ip_address = "192.168.0.7"
}
}
tags = {
env = "Prod"
owner = "Matt "
dept = "IT"
}
role_assignments = {
role_assignment_1 = {
role_definition_id_or_name = data.azurerm_role_definition.example.id
principal_id = data.azurerm_client_config.current.object_id
}
}
}
}
}
tfvars variables values
Nothing at all
Debug Output/Panic Output
│ Error: Incorrect attribute value type
│
│ on ..\..\main.privateendpoint.tf line 25, in resource "azurerm_private_endpoint" "this":
│ 25: subresource_name = each.value.subresource_name
│ ├────────────────
│ │ each.value.subresource_name is list of string with 1 element
│
│ Inappropriate value for attribute "subresource_name": string required.
╵
Expected Behaviour
Deploy correctly the storage account with static ips
Actual Behaviour
Run just fails
Steps to Reproduce
just terraform apply. The code I used to reproduce the issue is the same you have in your examples for private-endpoint
Important Factoids
Nothing
References
Nothing at all
Reviewing the azurerm provider, the subresource_name
property within the ip_configuration
block is a string.
The subresource_names
property within the private_service_connection
is a list(string)
.
It looks like the module reuses the same variable for both, hence why we are seeing an error.
Warning
Tagging the AVM Core Team (@Azure/avm-core-team-technical-terraform) due to a module owner or contributor having not responded to this issue within 3 business days. The AVM Core Team will attempt to contact the module owners/contributors directly.
Tip
- To prevent further actions to take effect, the "Status: Response Overdue 🚩" label must be removed, once this issue has been responded to.
- To avoid this rule being (re)triggered, the ""Needs: Triage 🔍" label must be removed as part of the triage process (when the issue is first responded to)!
Note
This message was posted as per ITA01TF.
Warning
Tagging the AVM Core Team (@Azure/avm-core-team-technical-terraform) due to a module owner or contributor having not responded to this issue within 3 business days. The AVM Core Team will attempt to contact the module owners/contributors directly.
Tip
- To prevent further actions to take effect, the "Status: Response Overdue 🚩" label must be removed, once this issue has been responded to.
- To avoid this rule being (re)triggered, the ""Needs: Triage 🔍" label must be removed as part of the triage process (when the issue is first responded to)!
Note
This message was posted as per ITA01TF.
Caution
**This issue requires the AVM Core Team's (@Azure/avm-core-team-technical-terraform) immediate attention as it hasn't been responded to within 6 business days. **
Tip
- To avoid this rule being (re)triggered, the "Needs: Triage 🔍" and "Status: Response Overdue 🚩" labels must be removed when the issue is first responded to!
- Remove the "Needs: Immediate Attention
‼️ " label once the issue has been responded to.
Note
This message was posted as per ITA02TF.
It seems it was magically fixed as it is not possible to reproduce as per today