Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposed ignore_missing_vnet_service_endpoint attribute #2056

Merged
merged 10 commits into from
Oct 12, 2018
31 changes: 0 additions & 31 deletions azurerm/import_arm_postgresql_virtual_network_rule_test.go

This file was deleted.

62 changes: 21 additions & 41 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)
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -165,7 +138,14 @@ func resourceArmPostgreSQLVirtualNetworkRuleRead(d *schema.ResourceData, meta in
d.Set("server_name", serverName)

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

if virtualNetworkSubnetId := props.VirtualNetworkSubnetID; virtualNetworkSubnetId != nil {
d.Set("subnet_id", virtualNetworkSubnetId)
}

if ignoreMissingVnetServiceEndpoint := props.IgnoreMissingVnetServiceEndpoint; ignoreMissingVnetServiceEndpoint != nil {
d.Set("ignore_missing_vnet_service_endpoint", ignoreMissingVnetServiceEndpoint)
}
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
}

return nil
Expand Down
89 changes: 88 additions & 1 deletion 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 := testAccAzureRMPostgreSQLFirewallRule_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"),
),
},
},
WodansSon marked this conversation as resolved.
Show resolved Hide resolved
})
}

func testCheckAzureRMPostgreSQLVirtualNetworkRuleExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
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)
}
21 changes: 11 additions & 10 deletions website/docs/r/postgresql_virtual_network_rule.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ resource "azurerm_virtual_network" "test" {

resource "azurerm_subnet" "internal" {
name = "internal"
resource_group_name = "${azurerm_resource_group.example.name}"
virtual_network_name = "${azurerm_virtual_network.vnet.name}"
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.Sql"]
}
Expand All @@ -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) Create firewall rule before the virtual network has vnet service endpoint enabled.

## Attributes Reference

Expand Down