diff --git a/azurerm/resource_arm_postgresql_virtual_network_rule.go b/azurerm/resource_arm_postgresql_virtual_network_rule.go index 5e632987c573a..b459194254acc 100644 --- a/azurerm/resource_arm_postgresql_virtual_network_rule.go +++ b/azurerm/resource_arm_postgresql_virtual_network_rule.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "regexp" + "strings" "time" "github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-12-01/postgresql" @@ -59,16 +60,53 @@ func resourceArmPostgreSQLVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, name := d.Get("name").(string) serverName := d.Get("server_name").(string) resourceGroup := d.Get("resource_group_name").(string) - virtualNetworkSubnetId := d.Get("subnet_id").(string) + subnetId := d.Get("subnet_id").(string) + + // due to a bug in the API we have to ensure the Subnet's configured correctly or the API call will timeout + // BUG: https://github.com/Azure/azure-rest-api-specs/issues/3719 + subnetsClient := meta.(*ArmClient).subnetClient + subnetParsedId, err := parseAzureResourceID(subnetId) + + subnetResourceGroup := subnetParsedId.ResourceGroup + virtualNetwork := subnetParsedId.Path["virtualNetworks"] + subnetName := subnetParsedId.Path["subnets"] + resp, err := subnetsClient.Get(ctx, subnetResourceGroup, virtualNetwork, subnetName, "") + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Subnet with ID %q was not found: %+v", subnetId, err) + } + + return fmt.Errorf("Error obtaining Subnet %q (Virtual Network %q / Resource Group %q: %+v", subnetName, virtualNetwork, subnetResourceGroup, err) + } + + containsEndpoint := false + if props := resp.SubnetPropertiesFormat; props != nil { + if endpoints := props.ServiceEndpoints; endpoints != nil { + for _, e := range *endpoints { + if e.Service == nil { + continue + } + + if strings.EqualFold(*e.Service, "Microsoft.Sql") { + containsEndpoint = true + break + } + } + } + } + + if !containsEndpoint { + return fmt.Errorf("Error creating PostgreSQL Virtual Network Rule: Subnet %q (Virtual Network %q / Resource Group %q) must contain a Service Endpoint for `Microsoft.Sql`", subnetName, virtualNetwork, subnetResourceGroup) + } parameters := postgresql.VirtualNetworkRule{ VirtualNetworkRuleProperties: &postgresql.VirtualNetworkRuleProperties{ - VirtualNetworkSubnetID: utils.String(virtualNetworkSubnetId), + VirtualNetworkSubnetID: utils.String(subnetId), IgnoreMissingVnetServiceEndpoint: utils.Bool(false), }, } - _, err := client.CreateOrUpdate(ctx, resourceGroup, serverName, name, parameters) + _, err = client.CreateOrUpdate(ctx, resourceGroup, serverName, name, parameters) if err != nil { return fmt.Errorf("Error creating PostgreSQL Virtual Network Rule %q (PostgreSQL Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) } diff --git a/website/docs/r/postgresql_virtual_network_rule.html.markdown b/website/docs/r/postgresql_virtual_network_rule.html.markdown index 8987e46c8011f..380da49644745 100644 --- a/website/docs/r/postgresql_virtual_network_rule.html.markdown +++ b/website/docs/r/postgresql_virtual_network_rule.html.markdown @@ -82,7 +82,7 @@ The following arguments are supported: * `subnet_id` - (Required) The ID of the subnet that the PostgreSQL server will be connected to. -~> **NOTE:** The resource is configured with `ignore_missing_vnet_service_endpoint` set to `true`, meaning the deployment will succeed even if the target subnet does not contain the `Microsoft.Sql` endpoint in the `service_endpoints` array. This attribute will be introduced once the API behaviour is consistent. +~> **NOTE:** Due to [a bug in the Azure API](https://github.com/Azure/azure-rest-api-specs/issues/3719) this resource currently doesn't expose the `ignore_missing_vnet_service_endpoint` field and defaults this to `false`. Terraform will check during the provisioning of the Virtual Network Rule that the Subnet contains the Service Rule to verify that the Virtual Network Rule can be created. ## Attributes Reference @@ -92,7 +92,7 @@ The following attributes are exported: ## Import -SQL Virtual Network Rules can be imported using the `resource id`, e.g. +PostgreSQL Virtual Network Rules can be imported using the `resource id`, e.g. ```shell terraform import azurerm_postgresql_virtual_network_rule.rule1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresourcegroup/providers/Microsoft.DBforPostgreSQL/servers/myserver/virtualNetworkRules/vnetrulename