hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.6k stars 4.64k forks source link

azurerm_linux_web_app_slot can't be associated to private endpoint #25866

Closed fjalcarazp closed 6 months ago

fjalcarazp commented 6 months ago

Is there an existing issue for this?

Community Note

Terraform Version

1.8.2

AzureRM Provider Version

3.102.0

Affected Resource(s)/Data Source(s)

azurerm_linux_web_app_slot; azurerm_private_endpoint; azurerm_windows_web_app_slot

Terraform Configuration Files

resource "azurerm_linux_web_app_slot" "app_01_slot_01" {
  # Application: API
  name                          = "slot${local.name}01"
  app_service_id                = azurerm_linux_web_app.app_01.id
  https_only                    = true
  virtual_network_subnet_id     = azurerm_subnet.vnet_01_snet_02.id
  public_network_access_enabled = false
  tags                          = data.azurerm_resource_group.rg_01.tags

  identity {
    type = "SystemAssigned"
  }

  site_config {
    always_on              = "true"
    health_check_path      = "/hc/live"
    http2_enabled          = true
    minimum_tls_version    = "1.2"
    ftps_state             = "Disabled"
    vnet_route_all_enabled = true

    cors {
      allowed_origins = [
        "https://app${local.name}02.azurewebsites.net",
        "https://app${local.name}03.azurewebsites.net"
      ]
    }

    application_stack {
      dotnet_version = "6.0"
    }
  }

  app_settings = {
    "WEBSITE_ENABLE_SYNC_UPDATE_SITE" = "true"
    "WEBSITE_RUN_FROM_PACKAGE"        = "1"
  }

  connection_string {
    name  = "Default"
    type  = "SQLAzure"
    value = local.connection_string_db
  }

  connection_string {
    name  = "Storage"
    type  = "Custom"
    value = azurerm_storage_account.st_03.primary_connection_string
  }

  connection_string {
    name  = "APPLICATIONINSIGHTS_CONNECTION_STRING"
    type  = "Custom"
    value = data.azurerm_application_insights.appi_01.connection_string
  }

  connection_string {
    name  = "Hashids__salt"
    type  = "Custom"
    value = random_password.hashids_salt.result
  }

  lifecycle {
    ignore_changes = [
      tags["Creation Date"],
      tags["Request Ticket"],
      tags["Support time window"]
    ]
  }
}

resource "azurerm_private_endpoint" "pe_03" {
  name                          = "pep${local.name}03"
  location                      = data.azurerm_resource_group.rg_01.location
  resource_group_name           = data.azurerm_resource_group.rg_01.name
  subnet_id                     = data.azurerm_subnet.vnet_01_snet_01.id
  custom_network_interface_name = "nic${local.name}03"
  tags                          = data.azurerm_resource_group.rg_01.tags

  private_service_connection {
    name                           = "default"
    private_connection_resource_id = azurerm_linux_web_app_slot.app_01_slot_01.id
    is_manual_connection           = false
    subresource_names              = ["sites"]
  }

  lifecycle {
    ignore_changes = [
      tags["Creation Date"],
      tags["Request Ticket"],
      tags["Support time window"],
      private_dns_zone_group
    ]
  }
}

Debug Output/Panic Output

│ Error: creating Private Endpoint (Subscription: "*******"
│ Resource Group Name: "resourceGroupName"
│ Private Endpoint Name: "privateEndpointName"): performing CreateOrUpdate: unexpected status 400 (400 Bad Request) with error: InvalidPrivateLinkServiceIdType: Private link service Id /subscriptions/{subscriptionID}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{appServiceName}/slots/{deploymentSlotName} has an invalid resource type. Permitted type(s): Microsoft.DocumentDB/databaseAccounts, Microsoft.Sql/servers, Microsoft.Network/privateLinkServices, Microsoft.Web/sites, Microsoft.Web/hostingEnvironments, Microsoft.Storage/storageAccounts, Microsoft.DBforPostgreSQL/servers, Microsoft.DBforMySQL/servers, Microsoft.DBforMariaDB/servers, Microsoft.KeyVault/vaults, Microsoft.Synapse/workspaces, Microsoft.AppConfiguration/configurationStores, Microsoft.Search/searchServices, Microsoft.ContainerService/managedClusters, Microsoft.Attestation/attestationProviders, Microsoft.Devices/IotHubs, Microsoft.Cache/Redis, Microsoft.SignalRService/SignalR, Microsoft.MachineLearningServices/workspaces, Microsoft.Batch/batchAccounts, Microsoft.ContainerRegistry/registries, Microsoft.RecoveryServices/vaults, Microsoft.EventGrid/topics, Microsoft.EventGrid/domains, Microsoft.EventHub/namespaces, Microsoft.ServiceBus/namespaces, Microsoft.Relay/namespaces, Microsoft.StorageSync/storageSyncServices, Microsoft.HealthcareApis/services, Microsoft.Automation/automationAccounts, Microsoft.Insights/privateLinkScopes, Microsoft.CognitiveServices/accounts, Microsoft.Compute/diskAccesses, Microsoft.Network/applicationgateways, Microsoft.Media/mediaservices, Microsoft.Databricks/workspaces, Microsoft.Sql/managedInstances, Microsoft.Migrate/assessmentProjects, Microsoft.Migrate/migrateProjects, Microsoft.DataFactory/factories, Microsoft.Authorization/resourceManagementPrivateLinks, Microsoft.Devices/ProvisioningServices, Microsoft.Synapse/privateLinkHubs, Microsoft.PowerBI/privateLinkServicesForPowerBI, Microsoft.Cache/redisEnterprise, Microsoft.HybridCompute/privateLinkScopes, Microsoft.OffAzure/mastersites, Microsoft.TimeSeriesInsights/environments, Microsoft.DigitalTwins/digitalTwinsInstances, Microsoft.Keyvault/managedHSMs, Microsoft.Kusto/clusters, Microsoft.Purview/accounts, Microsoft.Web/staticSites, Microsoft.SignalRService/webPubSub, Microsoft.DeviceUpdate/accounts, Microsoft.DBforPostgreSQL/serverGroupsv2, Microsoft.HealthcareApis/workspaces, Microsoft.ApiManagement/service, Microsoft.HDInsight/clusters, Microsoft.DesktopVirtualization/hostpools, Microsoft.DesktopVirtualization/workspaces, Microsoft.Media/videoanalyzers, Microsoft.IoTCentral/IoTApps, Microsoft.EventGrid/partnerNamespaces, Microsoft.BotService/botServices, Microsoft.AgFoodPlatform/farmBeats, Microsoft.NotificationHubs/namespaces, Microsoft.OpenEnergyPlatform/energyServices, Microsoft.Dashboard/grafana, Microsoft.DBforMySQL/flexibleServers, Microsoft.MachineLearningServices/registries, Microsoft.DBforPostgreSQL/flexibleServers, Microsoft.HardwareSecurityModules/cloudHsmClusters, Microsoft.Monitor/accounts, Microsoft.EventGrid/namespaces, Microsoft.ElasticSan/elasticSans, Microsoft.DocumentDB/mongoClusters, Microsoft.Chaos/privateAccesses.
│ 
│   with azurerm_private_endpoint.pe_03,
│   on main.tf line 354, in resource "azurerm_private_endpoint" "pe_03":
│  354: resource "azurerm_private_endpoint" "pe_03" {

Expected Behaviour

The private endpoint is created and linked to the deployment slot.

Actual Behaviour

The private endpoint is not created and is not linked to the deployment slot.

Steps to Reproduce

terraform apply

Important Factoids

No response

References

No response

4865783a5d commented 6 months ago

subresource_names for staging slots are for example "sites-staging" . In your case "sites-slot${local.name}01".

fjalcarazp commented 6 months ago

You are right. I had two issues in my code:

  1. According to the documentation the subresource_name is 'sites-{slot-name}' (https://learn.microsoft.com/en-us/azure/app-service/overview-private-endpoint#conceptual-overview).
  2. If you want to link a private endpoint with a deployment slot in the private_connection_resource_id is necessary to specify the app service id.

The fixed code is:

resource "azurerm_linux_web_app_slot" "app_01_slot_01" {
  # Application: API
  name                          = "slot${local.name}01"
  app_service_id                = azurerm_linux_web_app.app_01.id
  https_only                    = true
  virtual_network_subnet_id     = azurerm_subnet.vnet_01_snet_02.id
  public_network_access_enabled = false
  tags                          = data.azurerm_resource_group.rg_01.tags

  identity {
    type = "SystemAssigned"
  }

  site_config {
    always_on              = "true"
    health_check_path      = "/hc/live"
    http2_enabled          = true
    minimum_tls_version    = "1.2"
    ftps_state             = "Disabled"
    vnet_route_all_enabled = true

    cors {
      allowed_origins = [
        "https://app${local.name}02.azurewebsites.net",
        "https://app${local.name}03.azurewebsites.net"
      ]
    }

    application_stack {
      dotnet_version = "6.0"
    }
  }

  app_settings = {
    "WEBSITE_ENABLE_SYNC_UPDATE_SITE" = "true"
    "WEBSITE_RUN_FROM_PACKAGE"        = "1"
  }

  connection_string {
    name  = "Default"
    type  = "SQLAzure"
    value = local.connection_string_db
  }

  connection_string {
    name  = "Storage"
    type  = "Custom"
    value = azurerm_storage_account.st_03.primary_connection_string
  }

  connection_string {
    name  = "APPLICATIONINSIGHTS_CONNECTION_STRING"
    type  = "Custom"
    value = data.azurerm_application_insights.appi_01.connection_string
  }

  connection_string {
    name  = "Hashids__salt"
    type  = "Custom"
    value = random_password.hashids_salt.result
  }

  lifecycle {
    ignore_changes = [
      tags["Creation Date"],
      tags["Request Ticket"],
      tags["Support time window"]
    ]
  }
}

resource "azurerm_private_endpoint" "pe_03" {
  name                          = "pep${local.name}03"
  location                      = data.azurerm_resource_group.rg_01.location
  resource_group_name           = data.azurerm_resource_group.rg_01.name
  subnet_id                     = data.azurerm_subnet.vnet_01_snet_01.id
  custom_network_interface_name = "nic${local.name}03"
  tags                          = data.azurerm_resource_group.rg_01.tags

  private_service_connection {
    name                           = "default"
    private_connection_resource_id = azurerm_linux_web_app.app_01.id
    is_manual_connection           = false
    subresource_names              = ["sites-slot${local.name}01"]
  }

  lifecycle {
    ignore_changes = [
      tags["Creation Date"],
      tags["Request Ticket"],
      tags["Support time window"],
      private_dns_zone_group
    ]
  }
}
github-actions[bot] commented 4 months ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.