Skip to content

Commit

Permalink
Exposed ignore_missing_vnet_service_endpoint attribute (#2056)
Browse files Browse the repository at this point in the history
* Exposed the ignore_missing_vnet_service_endpoint attribute

* Updated documentation

* Updated test cases

* Moved optional attribute to bottom of schema definition

* Add nil check and attribute validation in _IgnoreEndpointValid test case

* fixed value check func

* Removed nil check for VirtualNetworkRuleProperties

* CnP Shenanigans

* Updated language in documentation.

* Removed is
  • Loading branch information
WodansSon authored and tombuildsstuff committed Oct 12, 2018
1 parent 6e2223a commit e39ecc1
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 82 deletions.
31 changes: 0 additions & 31 deletions azurerm/import_arm_postgresql_virtual_network_rule_test.go

This file was deleted.

54 changes: 14 additions & 40 deletions azurerm/resource_arm_postgresql_virtual_network_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"
"log"
"strings"
"time"

"github.com/Azure/azure-sdk-for-go/services/postgresql/mgmt/2017-12-01/postgresql"
Expand Down Expand Up @@ -49,6 +48,11 @@ func resourceArmPostgreSQLVirtualNetworkRule() *schema.Resource {
Required: true,
ValidateFunc: azure.ValidateResourceID,
},

"ignore_missing_vnet_service_endpoint": {
Type: schema.TypeBool,
Optional: true,
},
},
}
}
Expand All @@ -61,52 +65,21 @@ func resourceArmPostgreSQLVirtualNetworkRuleCreateUpdate(d *schema.ResourceData,
serverName := d.Get("server_name").(string)
resourceGroup := d.Get("resource_group_name").(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"]
subnet, err := subnetsClient.Get(ctx, subnetResourceGroup, virtualNetwork, subnetName, "")
if err != nil {
if utils.ResponseWasNotFound(subnet.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 := subnet.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)
}
ignoreMissingVnetServiceEndpoint := d.Get("ignore_missing_vnet_service_endpoint").(bool)

parameters := postgresql.VirtualNetworkRule{
VirtualNetworkRuleProperties: &postgresql.VirtualNetworkRuleProperties{
VirtualNetworkSubnetID: utils.String(subnetId),
IgnoreMissingVnetServiceEndpoint: utils.Bool(false),
IgnoreMissingVnetServiceEndpoint: utils.Bool(ignoreMissingVnetServiceEndpoint),
},
}

_, err = client.CreateOrUpdate(ctx, resourceGroup, serverName, name, parameters)
future, err := client.CreateOrUpdate(ctx, resourceGroup, serverName, name, parameters)
if err != nil {
return fmt.Errorf("Error submitting PostgreSQL Virtual Network Rule %q (PostgreSQL Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err)
}

err = future.WaitForCompletionRef(ctx, client.Client)
if err != nil {
return fmt.Errorf("Error creating PostgreSQL Virtual Network Rule %q (PostgreSQL Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err)
}
Expand Down Expand Up @@ -166,6 +139,7 @@ func resourceArmPostgreSQLVirtualNetworkRuleRead(d *schema.ResourceData, meta in

if props := resp.VirtualNetworkRuleProperties; props != nil {
d.Set("subnet_id", props.VirtualNetworkSubnetID)
d.Set("ignore_missing_vnet_service_endpoint", props.IgnoreMissingVnetServiceEndpoint)
}

return nil
Expand Down
93 changes: 90 additions & 3 deletions azurerm/resource_arm_postgresql_virtual_network_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,24 @@ func TestAccAzureRMPostgreSQLVirtualNetworkRule_basic(t *testing.T) {
resourceName := "azurerm_postgresql_virtual_network_rule.test"
ri := acctest.RandInt()

config := testAccAzureRMPostgreSQLVirtualNetworkRule_basic(ri, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMPostgreSQLVirtualNetworkRuleDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMPostgreSQLVirtualNetworkRule_basic(ri, testLocation()),
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMPostgreSQLVirtualNetworkRuleExists(resourceName),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
Expand Down Expand Up @@ -111,6 +118,27 @@ func TestAccAzureRMPostgreSQLVirtualNetworkRule_multipleSubnets(t *testing.T) {
})
}

func TestAccAzureRMPostgreSQLVirtualNetworkRule_IgnoreEndpointValid(t *testing.T) {
resourceName := "azurerm_postgresql_virtual_network_rule.test"
ri := acctest.RandInt()
config := testAccAzureRMPostgreSQLVirtualNetworkRule_ignoreEndpointValid(ri, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMPostgreSQLVirtualNetworkRuleDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMPostgreSQLVirtualNetworkRuleExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "ignore_missing_vnet_service_endpoint", "true"),
),
},
},
})
}

func testCheckAzureRMPostgreSQLVirtualNetworkRuleExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
Expand All @@ -128,7 +156,7 @@ func testCheckAzureRMPostgreSQLVirtualNetworkRuleExists(name string) resource.Te
resp, err := client.Get(ctx, resourceGroup, serverName, ruleName)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Bad: PostgreSQL Firewall Rule %q (server %q / resource group %q) was not found", ruleName, serverName, resourceGroup)
return fmt.Errorf("Bad: PostgreSQL Virtual Network Rule %q (server %q / resource group %q) was not found", ruleName, serverName, resourceGroup)
}

return err
Expand Down Expand Up @@ -160,7 +188,7 @@ func testCheckAzureRMPostgreSQLVirtualNetworkRuleDestroy(s *terraform.State) err
return err
}

return fmt.Errorf("Bad: PostgreSQL Firewall Rule %q (server %q / resource group %q) still exists: %+v", ruleName, serverName, resourceGroup, resp)
return fmt.Errorf("Bad: PostgreSQL Virtual Network Rule %q (server %q / resource group %q) still exists: %+v", ruleName, serverName, resourceGroup, resp)
}

return nil
Expand Down Expand Up @@ -458,20 +486,79 @@ resource "azurerm_postgresql_virtual_network_rule" "rule1" {
resource_group_name = "${azurerm_resource_group.test.name}"
server_name = "${azurerm_postgresql_server.test.name}"
subnet_id = "${azurerm_subnet.vnet1_subnet1.id}"
ignore_missing_vnet_service_endpoint = false
}
resource "azurerm_postgresql_virtual_network_rule" "rule2" {
name = "acctestpostgresqlvnetrule2%d"
resource_group_name = "${azurerm_resource_group.test.name}"
server_name = "${azurerm_postgresql_server.test.name}"
subnet_id = "${azurerm_subnet.vnet1_subnet2.id}"
ignore_missing_vnet_service_endpoint = false
}
resource "azurerm_postgresql_virtual_network_rule" "rule3" {
name = "acctestpostgresqlvnetrule3%d"
resource_group_name = "${azurerm_resource_group.test.name}"
server_name = "${azurerm_postgresql_server.test.name}"
subnet_id = "${azurerm_subnet.vnet2_subnet1.id}"
ignore_missing_vnet_service_endpoint = false
}
`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt)
}

func testAccAzureRMPostgreSQLVirtualNetworkRule_ignoreEndpointValid(rInt int, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}
resource "azurerm_virtual_network" "test" {
name = "acctestvnet%d"
address_space = ["10.7.29.0/29"]
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
}
resource "azurerm_subnet" "test" {
name = "acctestsubnet%d"
resource_group_name = "${azurerm_resource_group.test.name}"
virtual_network_name = "${azurerm_virtual_network.test.name}"
address_prefix = "10.7.29.0/29"
service_endpoints = ["Microsoft.Storage"]
}
resource "azurerm_postgresql_server" "test" {
name = "acctestpostgresqlsvr-%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
sku {
name = "GP_Gen5_2"
capacity = 2
tier = "GeneralPurpose"
family = "Gen5"
}
storage_profile {
storage_mb = 51200
backup_retention_days = 7
geo_redundant_backup = "Disabled"
}
administrator_login = "acctestun"
administrator_login_password = "H@Sh1CoR3!"
version = "9.5"
ssl_enforcement = "Enabled"
}
resource "azurerm_postgresql_virtual_network_rule" "test" {
name = "acctestpostgresqlvnetrule%d"
resource_group_name = "${azurerm_resource_group.test.name}"
server_name = "${azurerm_postgresql_server.test.name}"
subnet_id = "${azurerm_subnet.test.id}"
ignore_missing_vnet_service_endpoint = true
}
`, rInt, location, rInt, rInt, rInt, rInt)
}
17 changes: 9 additions & 8 deletions website/docs/r/postgresql_virtual_network_rule.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,18 @@ resource "azurerm_postgresql_server" "test" {
geo_redundant_backup = "Disabled"
}
administrator_login = "psqladminun"
administrator_login = "psqladminun"
administrator_login_password = "H@Sh1CoR3!"
version = "9.5"
ssl_enforcement = "Enabled"
version = "9.5"
ssl_enforcement = "Enabled"
}
resource "azurerm_postgresql_virtual_network_rule" "test" {
name = "postgresql-vnet-rule"
resource_group_name = "${azurerm_resource_group.test.name}"
server_name = "${azurerm_postgresql_server.test.name}"
subnet_id = "${azurerm_subnet.internal.id}"
name = "postgresql-vnet-rule"
resource_group_name = "${azurerm_resource_group.test.name}"
server_name = "${azurerm_postgresql_server.test.name}"
subnet_id = "${azurerm_subnet.internal.id}"
ignore_missing_vnet_service_endpoint = true
}
```

Expand All @@ -84,7 +85,7 @@ The following arguments are supported:

* `subnet_id` - (Required) The ID of the subnet that the PostgreSQL server will be connected to.

~> **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.
* `ignore_missing_vnet_service_endpoint` - (Optional) Should the Virtual Network Rule be created before the Subnet has the Virtual Network Service Endpoint enabled? Defaults to `false`.

## Attributes Reference

Expand Down

0 comments on commit e39ecc1

Please sign in to comment.