I am trying to create a private endpoint using terraform and am getting the error. What could I be missing? What I find interesting is the same subscription has got private endpoint resources .
Error: creating Private Endpoint (Subscription: "***" performing CreateOrUpdate: unexpected status 400 (400 Bad Request) with error: SubscriptionNotRegisteredForFeature: Subscription /subscriptions//resourceGroups//providers/Microsoft.Network/subscriptions/ is not registered for feature Microsoft.Network/AllowPrivateEndpoints required to carry out the requested operation. │ │ with module.azurerm_private_endpoint.azurerm_private_endpoint.main, │ on ../../factory/private-endpoint/main.tf line 1, in resource "azurerm_private_endpoint" "main": │ 1: resource "azurerm_private_endpoint" "main" {
main.tf
locals {
team_name = "devops"
stack_name = "devops"
location_abbreviations = { # map of location abbreviations according to naming conventions
"southafricanorth" = "san"
"westeurope" = "euw"
}
resource_group_name = "${local.location_abbreviations[var.location]}-${var.environment}-${local.team_name}-rg-001"
tags = { # list of tags
env = var.environment
managed_by = "terraform"
team = local.team_name
}
}
data "azurerm_client_config" "current" {}
data "terraform_remote_state" "platform" {
backend = "azurerm"
config = {
subscription_id = "********"
resource_group_name = "******"
storage_account_name = "******"
container_name = "platform"
key = "${var.environment}.tfstate"
}
}
module "azurerm_resource_group" {
source = "../../factory/resource-group"
resource_group_name = local.resource_group_name
resource_group_location = var.location
}
module "azurerm_application_insights" {
source = "../../factory/application-insights"
app_insights_name = "${local.location_abbreviations[var.location]}-${var.environment}-${local.team_name}-ai-001"
location = var.location
resource_group_name = local.resource_group_name
application_type = "web"
log_analytics_workspace_name = "${local.location_abbreviations[var.location]}-${var.environment}-${local.team_name}-logwkspace-001"
tags = local.tags
# Disable IP masking (captures the actual client IP address)
disable_ip_masking = true
}
module "azurerm_private_endpoint" {
source = "../../factory/private-endpoint"
name = "${local.location_abbreviations[var.location]}-${var.environment}-lulapay-appInsight-endpoint-001"
location = var.location
resource_group_name = local.resource_group_name
subnet_id = data.terraform_remote_state.platform.outputs.private_endpoints_subnet_id
private_service_connection_name = "app-insights-privatelink-dns-zones"
private_service_connection_is_manual_connection = false
private_service_connection_private_connection_resource_id = module.azurerm_application_insights.id
tags = local.tags
private_dns_zone_group_name = "application-insights-private-dns-zones"
private_dns_zone_group_name_private_dns_zone_ids = [data.terraform_remote_state.platform.outputs.app_insights_privatelink_dns_zone_id]
}
# DNS A Record for Application Insights
resource "azurerm_private_dns_a_record" "example" {
name = "lulapay-app-insight-privatelink"
zone_name = split("/", trim(data.terraform_remote_state.platform.outputs.app_insights_privatelink_dns_zone_id, "/"))[7]
resource_group_name = local.resource_group_name
records = [module.azurerm_private_endpoint.private_ip]
ttl = 10
}
Module
resource "azurerm_private_endpoint" "main" {
# define endpoint name based on app service name
name = var.name
resource_group_name = var.resource_group_name
location = var.location
subnet_id = var.subnet_id
tags = var.tags
private_dns_zone_group {
name = var.private_dns_zone_group_name
private_dns_zone_ids = var.private_dns_zone_group_name_private_dns_zone_ids
}
private_service_connection {
name = var.private_service_connection_name
private_connection_resource_id = var.private_service_connection_private_connection_resource_id
is_manual_connection = var.private_service_connection_is_manual_connection
}
}
When a check the feature is still on pending
$ az feature show --namespace Microsoft.Network --name AllowPrivateEndpoints
{
"id": "/subscriptions/*********/providers/Microsoft.Features/providers/Microsoft.Network/features/AllowPrivateEndpoints",
"name": "Microsoft.Network/AllowPrivateEndpoints",
"properties": {
"state": ***"Pending"***
},
"type": "Microsoft.Features/providers/features"
}
For it to work I had to include Azure Monitor Private Link Scope. Then link the private endpoint to that and it worked.
module "azurerm_application_insights" {
source = "../../factory/application-insights"
app_insights_name = "${local.location_abbreviations[var.location]}-${var.environment}-${local.team_name}-ai-001"
location = var.location
resource_group_name = local.resource_group_name
application_type = "web"
log_analytics_workspace_name = "${local.location_abbreviations[var.location]}-${var.environment}-${local.team_name}-logwkspace-001"
tags = local.tags
# Disable IP masking (captures the actual client IP address)
disable_ip_masking = true
}
resource "azurerm_monitor_private_link_scope" "lulapay-ampls" {
name = "${local.location_abbreviations[var.location]}-${var.environment}-${local.team_name}-ampls-endpoint-001"
resource_group_name = local.resource_group_name
}
resource "azurerm_monitor_private_link_scoped_service" "lulapay-ampls-scoped" {
name = "${local.location_abbreviations[var.location]}-${var.environment}-${local.team_name}-amplsservice-001"
resource_group_name = local.resource_group_name
scope_name = azurerm_monitor_private_link_scope.lulapay-ampls.name
linked_resource_id = module.azurerm_application_insights.id
}
module "azurerm_private_endpoint" {
source = "../../factory/private-endpoint"
name = "${local.location_abbreviations[var.location]}-${var.environment}-lulapay-appInsight-endpoint-001"
location = var.location
resource_group_name = local.resource_group_name
subnet_id = data.terraform_remote_state.platform.outputs.private_endpoints_subnet_id
private_service_connection_name = "app-insights-privatelink-dns-zones"
private_service_connection_is_manual_connection = false
private_service_connection_private_connection_resource_id = azurerm_monitor_private_link_scope.lulapay-ampls.id
private_service_connection_subresource_names = ["azuremonitor"]
tags = local.tags
private_dns_zone_group_name = "application-insights-private-dns-zones"
private_dns_zone_group_name_private_dns_zone_ids = [data.terraform_remote_state.platform.outputs.app_insights_privatelink_dns_zone_id]
}
resource "azurerm_private_dns_zone" "example" {
name = "privatelink.applicationinsights.azure.com"
resource_group_name = "san-dev-lulapay-rg-001"
}
# DNS A Record for Application Insights
resource "azurerm_private_dns_a_record" "example" {
name = "lulapay-app-insight-privatelink"
zone_name = split("/", trim(azurerm_private_dns_zone.example.id, "/"))[7]
resource_group_name = local.resource_group_name
records = [module.azurerm_private_endpoint.private_ip]
ttl = 10
}