From f1f991fcca64f859eb491855432cfc7d98d9c301 Mon Sep 17 00:00:00 2001 From: Daniel Intskirveli Date: Fri, 9 Aug 2019 14:08:55 -0400 Subject: [PATCH 1/4] Add resource for setup up vnet rules on MariaDB servers --- azurerm/internal/services/mariadb/client.go | 10 +- azurerm/provider.go | 1 + ...source_arm_mariadb_virtual_network_rule.go | 242 ++++++++++++++++++ 3 files changed, 250 insertions(+), 3 deletions(-) create mode 100644 azurerm/resource_arm_mariadb_virtual_network_rule.go diff --git a/azurerm/internal/services/mariadb/client.go b/azurerm/internal/services/mariadb/client.go index a0d961df4cb6..f8ea21506227 100644 --- a/azurerm/internal/services/mariadb/client.go +++ b/azurerm/internal/services/mariadb/client.go @@ -6,9 +6,10 @@ import ( ) type Client struct { - DatabasesClient mariadb.DatabasesClient - FirewallRulesClient mariadb.FirewallRulesClient - ServersClient mariadb.ServersClient + DatabasesClient mariadb.DatabasesClient + FirewallRulesClient mariadb.FirewallRulesClient + ServersClient mariadb.ServersClient + VirtualNetworkRulesClient mariadb.VirtualNetworkRulesClient } func BuildClient(o *common.ClientOptions) *Client { @@ -23,5 +24,8 @@ func BuildClient(o *common.ClientOptions) *Client { c.ServersClient = mariadb.NewServersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&c.ServersClient.Client, o.ResourceManagerAuthorizer) + c.VirtualNetworkRulesClient = mariadb.NewVirtualNetworkRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&c.VirtualNetworkRulesClient.Client, o.ResourceManagerAuthorizer) + return &c } diff --git a/azurerm/provider.go b/azurerm/provider.go index c78d0f805295..1558f72f5316 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -280,6 +280,7 @@ func Provider() terraform.ResourceProvider { "azurerm_mariadb_database": resourceArmMariaDbDatabase(), "azurerm_mariadb_firewall_rule": resourceArmMariaDBFirewallRule(), "azurerm_mariadb_server": resourceArmMariaDbServer(), + "azurerm_mariadb_virtual_network_rule": resourceArmMariaDbVirtualNetworkRule(), "azurerm_media_services_account": resourceArmMediaServicesAccount(), "azurerm_metric_alertrule": resourceArmMetricAlertRule(), "azurerm_monitor_autoscale_setting": resourceArmMonitorAutoScaleSetting(), diff --git a/azurerm/resource_arm_mariadb_virtual_network_rule.go b/azurerm/resource_arm_mariadb_virtual_network_rule.go new file mode 100644 index 000000000000..687175866d54 --- /dev/null +++ b/azurerm/resource_arm_mariadb_virtual_network_rule.go @@ -0,0 +1,242 @@ +package azurerm + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/services/mariadb/mgmt/2018-06-01/mariadb" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmMariaDbVirtualNetworkRule() *schema.Resource { + return &schema.Resource{ + Create: resourceArmMariaDbVirtualNetworkRuleCreateUpdate, + Read: resourceArmMariaDbVirtualNetworkRuleRead, + Update: resourceArmMariaDbVirtualNetworkRuleCreateUpdate, + Delete: resourceArmMariaDbVirtualNetworkRuleDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.VirtualNetworkRuleName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "server_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "subnet_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: azure.ValidateResourceID, + }, + }, + } +} + +func resourceArmMariaDbVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + serverName := d.Get("server_name").(string) + resourceGroup := d.Get("resource_group_name").(string) + subnetId := d.Get("subnet_id").(string) + + if requireResourcesToBeImported && d.IsNewResource() { + existing, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_mariadb_virtual_network_rule", *existing.ID) + } + } + + // 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) + if err != nil { + return err + } + + 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 MariaDb Virtual Network Rule: Subnet %q (Virtual Network %q / Resource Group %q) must contain a Service Endpoint for `Microsoft.Sql`", subnetName, virtualNetwork, subnetResourceGroup) + } + + parameters := mariadb.VirtualNetworkRule{ + VirtualNetworkRuleProperties: &mariadb.VirtualNetworkRuleProperties{ + VirtualNetworkSubnetID: utils.String(subnetId), + IgnoreMissingVnetServiceEndpoint: utils.Bool(false), + }, + } + + if _, err = client.CreateOrUpdate(ctx, resourceGroup, serverName, name, parameters); err != nil { + return fmt.Errorf("Error creating MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + + //Wait for the provisioning state to become ready + log.Printf("[DEBUG] Waiting for MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q) to become ready: %+v", name, serverName, resourceGroup, err) + stateConf := &resource.StateChangeConf{ + Pending: []string{"Initializing", "InProgress", "Unknown", "ResponseNotFound"}, + Target: []string{"Ready"}, + Refresh: MariaDbVirtualNetworkStateStatusCodeRefreshFunc(ctx, client, resourceGroup, serverName, name), + Timeout: 30 * time.Minute, + MinTimeout: 1 * time.Minute, + ContinuousTargetOccurence: 5, + } + + if _, err = stateConf.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q) to be created or updated: %+v", name, serverName, resourceGroup, err) + } + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + return fmt.Errorf("Error retrieving MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + + d.SetId(*resp.ID) + + return resourceArmMariaDbVirtualNetworkRuleRead(d, meta) +} + +func resourceArmMariaDbVirtualNetworkRuleRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serverName := id.Path["servers"] + name := id.Path["virtualNetworkRules"] + + resp, err := client.Get(ctx, resourceGroup, serverName, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Error reading MariaDb Virtual Network Rule %q - removing from state", d.Id()) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading MariaDb Virtual Network Rule: %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resourceGroup) + d.Set("server_name", serverName) + + if props := resp.VirtualNetworkRuleProperties; props != nil { + d.Set("subnet_id", props.VirtualNetworkSubnetID) + } + + return nil +} + +func resourceArmMariaDbVirtualNetworkRuleDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := meta.(*ArmClient).StopContext + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + + resourceGroup := id.ResourceGroup + serverName := id.Path["servers"] + name := id.Path["virtualNetworkRules"] + + future, err := client.Delete(ctx, resourceGroup, serverName, name) + if err != nil { + if response.WasNotFound(future.Response()) { + return nil + } + + return fmt.Errorf("Error deleting MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error waiting for deletion of MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + } + + return nil +} + +func MariaDbVirtualNetworkStateStatusCodeRefreshFunc(ctx context.Context, client mariadb.VirtualNetworkRulesClient, resourceGroup string, serverName string, name string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + resp, err := client.Get(ctx, resourceGroup, serverName, name) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[DEBUG] Retrieving MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q) returned 404.", resourceGroup, serverName, name) + return nil, "ResponseNotFound", nil + } + + return nil, "", fmt.Errorf("Error polling for the state of the MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err) + } + + if props := resp.VirtualNetworkRuleProperties; props != nil { + log.Printf("[DEBUG] Retrieving MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q) returned Status %s", resourceGroup, serverName, name, props.State) + return resp, string(props.State), nil + } + + //Valid response was returned but VirtualNetworkRuleProperties was nil. Basically the rule exists, but with no properties for some reason. Assume Unknown instead of returning error. + log.Printf("[DEBUG] Retrieving MariaDb Virtual Network Rule %q (MariaDb Server: %q, Resource Group: %q) returned empty VirtualNetworkRuleProperties", resourceGroup, serverName, name) + return resp, "Unknown", nil + } +} From c2725a4a51597e00d715c37b69ff999493c62b29 Mon Sep 17 00:00:00 2001 From: Daniel Intskirveli Date: Wed, 14 Aug 2019 14:18:51 -0400 Subject: [PATCH 2/4] Added test for resource_arm_mariadb_virtual_network_rule --- ...e_arm_mariadb_virtual_network_rule_test.go | 516 ++++++++++++++++++ 1 file changed, 516 insertions(+) create mode 100644 azurerm/resource_arm_mariadb_virtual_network_rule_test.go diff --git a/azurerm/resource_arm_mariadb_virtual_network_rule_test.go b/azurerm/resource_arm_mariadb_virtual_network_rule_test.go new file mode 100644 index 000000000000..03781c6ab624 --- /dev/null +++ b/azurerm/resource_arm_mariadb_virtual_network_rule_test.go @@ -0,0 +1,516 @@ +package azurerm + +import ( + "fmt" + "regexp" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMMariaDBVirtualNetworkRule_basic(t *testing.T) { + resourceName := "azurerm_mariadb_virtual_network_rule.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBVirtualNetworkRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMariaDBVirtualNetworkRule_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName), + ), + }, + }, + }) +} + +func TestAccAzureRMMariaDBVirtualNetworkRule_requiresImport(t *testing.T) { + if !requireResourcesToBeImported { + t.Skip("Skipping since resources aren't required to be imported") + return + } + + resourceName := "azurerm_mariadb_virtual_network_rule.test" + ri := tf.AccRandTimeInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBVirtualNetworkRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMMariaDBVirtualNetworkRule_basic(ri, testLocation()), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName), + ), + }, + { + Config: testAccAzureRMMariaDBVirtualNetworkRule_requiresImport(ri, testLocation()), + ExpectError: testRequiresImportError("azurerm_mariadb_virtual_network_rule"), + }, + }, + }) +} + +func TestAccAzureRMMariaDBVirtualNetworkRule_switchSubnets(t *testing.T) { + resourceName := "azurerm_mariadb_virtual_network_rule.test" + ri := tf.AccRandTimeInt() + + preConfig := testAccAzureRMMariaDBVirtualNetworkRule_subnetSwitchPre(ri, testLocation()) + postConfig := testAccAzureRMMariaDBVirtualNetworkRule_subnetSwitchPost(ri, testLocation()) + + // Create regex strings that will ensure that one subnet name exists, but not the other + preConfigRegex := regexp.MustCompile(fmt.Sprintf("(subnet1%d)$|(subnet[^2]%d)$", ri, ri)) //subnet 1 but not 2 + postConfigRegex := regexp.MustCompile(fmt.Sprintf("(subnet2%d)$|(subnet[^1]%d)$", ri, ri)) //subnet 2 but not 1 + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBVirtualNetworkRuleDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName), + resource.TestMatchResourceAttr(resourceName, "subnet_id", preConfigRegex), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName), + resource.TestMatchResourceAttr(resourceName, "subnet_id", postConfigRegex), + ), + }, + }, + }) +} + +func TestAccAzureRMMariaDBVirtualNetworkRule_disappears(t *testing.T) { + resourceName := "azurerm_mariadb_virtual_network_rule.test" + ri := tf.AccRandTimeInt() + config := testAccAzureRMMariaDBVirtualNetworkRule_basic(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBVirtualNetworkRuleDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName), + testCheckAzureRMMariaDBVirtualNetworkRuleDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAzureRMMariaDBVirtualNetworkRule_multipleSubnets(t *testing.T) { + resourceName1 := "azurerm_mariadb_virtual_network_rule.rule1" + resourceName2 := "azurerm_mariadb_virtual_network_rule.rule2" + resourceName3 := "azurerm_mariadb_virtual_network_rule.rule3" + ri := tf.AccRandTimeInt() + config := testAccAzureRMMariaDBVirtualNetworkRule_multipleSubnets(ri, testLocation()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMMariaDBVirtualNetworkRuleDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName1), + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName2), + testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName3), + ), + }, + }, + }) +} + +func testCheckAzureRMMariaDBVirtualNetworkRuleExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serverName := rs.Primary.Attributes["server_name"] + ruleName := rs.Primary.Attributes["name"] + + client := testAccProvider.Meta().(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: MariaDB Virtual Network Rule %q (Server %q / Resource Group %q) was not found", ruleName, serverName, resourceGroup) + } + + return err + } + + return nil + } +} + +func testCheckAzureRMMariaDBVirtualNetworkRuleDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_mariadb_virtual_network_rule" { + continue + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serverName := rs.Primary.Attributes["server_name"] + ruleName := rs.Primary.Attributes["name"] + + client := testAccProvider.Meta().(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + resp, err := client.Get(ctx, resourceGroup, serverName, ruleName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return nil + } + + return err + } + + return fmt.Errorf("Bad: MariaDB Firewall Rule %q (Server %q / Resource Group %q) still exists: %+v", ruleName, serverName, resourceGroup, resp) + } + + return nil +} + +func testCheckAzureRMMariaDBVirtualNetworkRuleDisappears(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + resourceGroup := rs.Primary.Attributes["resource_group_name"] + serverName := rs.Primary.Attributes["server_name"] + ruleName := rs.Primary.Attributes["name"] + + client := testAccProvider.Meta().(*ArmClient).mariadb.VirtualNetworkRulesClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + future, err := client.Delete(ctx, resourceGroup, serverName, ruleName) + if err != nil { + //If the error is that the resource we want to delete does not exist in the first + //place (404), then just return with no error. + if response.WasNotFound(future.Response()) { + return nil + } + + return fmt.Errorf("Error deleting MariaDB Virtual Network Rule: %+v", err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + //Same deal as before. Just in case. + if response.WasNotFound(future.Response()) { + return nil + } + + return fmt.Errorf("Error deleting MariaDB Virtual Network Rule: %+v", err) + } + + return nil + } +} + +func testAccAzureRMMariaDBVirtualNetworkRule_basic(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.Sql"] +} + +resource "azurerm_mariadb_server" "test" { + name = "acctestmariadbsvr-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + administrator_login = "acctestun" + administrator_login_password = "H@Sh1CoR3!" + version = "5.6" + ssl_enforcement = "Enabled" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 51200 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } +} + +resource "azurerm_mariadb_virtual_network_rule" "test" { + name = "acctestmariadbvnetrule%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.test.id}" +} +`, rInt, location, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMMariaDBVirtualNetworkRule_requiresImport(rInt int, location string) string { + return fmt.Sprintf(` +%s + +resource "azurerm_mariadb_virtual_network_rule" "import" { + name = "${azurerm_mariadb_virtual_network_rule.test.name}" + resource_group_name = "${azurerm_mariadb_virtual_network_rule.test.resource_group_name}" + server_name = "${azurerm_mariadb_virtual_network_rule.test.server_name}" + subnet_id = "${azurerm_mariadb_virtual_network_rule.test.subnet_id}" +} +`, testAccAzureRMMariaDBVirtualNetworkRule_basic(rInt, location)) +} + +func testAccAzureRMMariaDBVirtualNetworkRule_subnetSwitchPre(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/24"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test1" { + name = "subnet1%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.7.29.0/25" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_subnet" "test2" { + name = "subnet2%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.7.29.128/25" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_mariadb_server" "test" { + name = "acctestmariadbsvr-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + administrator_login = "acctestun" + administrator_login_password = "H@Sh1CoR3!" + version = "5.6" + ssl_enforcement = "Enabled" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 51200 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } +} + +resource "azurerm_mariadb_virtual_network_rule" "test" { + name = "acctestmariadbvnetrule%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.test1.id}" +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMMariaDBVirtualNetworkRule_subnetSwitchPost(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/24"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "test1" { + name = "subnet1%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.7.29.0/25" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_subnet" "test2" { + name = "subnet2%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.test.name}" + address_prefix = "10.7.29.128/25" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_mariadb_server" "test" { + name = "acctestmariadbsvr-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + administrator_login = "acctestun" + administrator_login_password = "H@Sh1CoR3!" + version = "5.6" + ssl_enforcement = "Enabled" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 51200 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } +} + +resource "azurerm_mariadb_virtual_network_rule" "test" { + name = "acctestmariadbvnetrule%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.test2.id}" +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt) +} + +func testAccAzureRMMariaDBVirtualNetworkRule_multipleSubnets(rInt int, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "vnet1" { + name = "acctestvnet1%d" + address_space = ["10.7.29.0/24"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_virtual_network" "vnet2" { + name = "acctestvnet2%d" + address_space = ["10.1.29.0/29"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "vnet1_subnet1" { + name = "acctestsubnet1%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.vnet1.name}" + address_prefix = "10.7.29.0/29" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_subnet" "vnet1_subnet2" { + name = "acctestsubnet2%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.vnet1.name}" + address_prefix = "10.7.29.128/29" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_subnet" "vnet2_subnet1" { + name = "acctestsubnet3%d" + resource_group_name = "${azurerm_resource_group.test.name}" + virtual_network_name = "${azurerm_virtual_network.vnet2.name}" + address_prefix = "10.1.29.0/29" + service_endpoints = ["Microsoft.Sql"] +} + +resource "azurerm_mariadb_server" "test" { + name = "acctestmariadbsvr-%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + administrator_login = "acctestun" + administrator_login_password = "H@Sh1CoR3!" + version = "5.6" + ssl_enforcement = "Enabled" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 51200 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } +} + +resource "azurerm_mariadb_virtual_network_rule" "rule1" { + name = "acctestmariadbvnetrule1%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.vnet1_subnet1.id}" +} + +resource "azurerm_mariadb_virtual_network_rule" "rule2" { + name = "acctestmariadbvnetrule2%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.vnet1_subnet2.id}" +} + +resource "azurerm_mariadb_virtual_network_rule" "rule3" { + name = "acctestmariadbvnetrule3%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.vnet2_subnet1.id}" +} +`, rInt, location, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt, rInt) +} From b24253d9e4526c695d95641d56215de3ef0fc02f Mon Sep 17 00:00:00 2001 From: Daniel Intskirveli Date: Sat, 17 Aug 2019 12:45:32 -0400 Subject: [PATCH 3/4] Add documentation for resource_arm_mariadb_virtual_network_rule --- ...mariadb_virtual_network_rule.html.markdown | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 website/docs/r/mariadb_virtual_network_rule.html.markdown diff --git a/website/docs/r/mariadb_virtual_network_rule.html.markdown b/website/docs/r/mariadb_virtual_network_rule.html.markdown new file mode 100644 index 000000000000..563e171545f6 --- /dev/null +++ b/website/docs/r/mariadb_virtual_network_rule.html.markdown @@ -0,0 +1,100 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_mariadb_virtual_network_rule" +sidebar_current: "docs-azurerm-resource-database-mariadb-virtual-network-rule" +description: |- + Manages a MariaDB Virtual Network Rule. +--- + +# azurerm_mariadb_virtual_network_rule + +Manages a MariaDB Virtual Network Rule. + +-> **NOTE:** MariaDB Virtual Network Rules [can only be used with SKU Tiers of `GeneralPurpose` or `MemoryOptimized`](https://docs.microsoft.com/en-us/azure/mariadb/concepts-data-access-security-vnet) + +## Example Usage + +```hcl +resource "azurerm_resource_group" "test" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_virtual_network" "test" { + name = "example-vnet" + address_space = ["10.7.29.0/29"] + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_subnet" "internal" { + name = "internal" + 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"] +} + +resource "azurerm_mariadb_server" "test" { + name = "mariadb-server-1" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + administrator_login = "mariadbadminun" + administrator_login_password = "H@Sh1CoR3!" + version = "5.7" + ssl_enforcement = "Enabled" + + sku { + name = "GP_Gen5_2" + capacity = 2 + tier = "GeneralPurpose" + family = "Gen5" + } + + storage_profile { + storage_mb = 5120 + backup_retention_days = 7 + geo_redundant_backup = "Disabled" + } +} + +resource "azurerm_mariadb_virtual_network_rule" "test" { + name = "mariadb-vnet-rule" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_mariadb_server.test.name}" + subnet_id = "${azurerm_subnet.internal.id}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the MariaDB Virtual Network Rule. Cannot be empty and must only contain alphanumeric characters and hyphens. Cannot start with a number, and cannot start or end with a hyphen. Changing this forces a new resource to be created. + +~> **NOTE:** `name` must be between 1-128 characters long and must satisfy all of the requirements below: +1. Contains only alphanumeric and hyphen characters +2. Cannot start with a number or hyphen +3. Cannot end with a hyphen + +* `resource_group_name` - (Required) The name of the resource group where the MariaDB server resides. Changing this forces a new resource to be created. + +* `server_name` - (Required) The name of the SQL Server to which this MariaDB virtual network rule will be applied to. Changing this forces a new resource to be created. + +* `subnet_id` - (Required) The ID of the subnet that the MariaDB 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. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the MariaDB Virtual Network Rule. + +## Import + +MariaDB Virtual Network Rules can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_mariadb_virtual_network_rule.rule1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresourcegroup/MariaDB/servers/myserver/virtualNetworkRules/vnetrulename +``` From 01eb88e4ccccc903fa2d5000ca2d17b50a9d6ffc Mon Sep 17 00:00:00 2001 From: kt Date: Sun, 18 Aug 2019 08:14:16 -0700 Subject: [PATCH 4/4] Update resource_arm_mariadb_virtual_network_rule_test.go --- azurerm/resource_arm_mariadb_virtual_network_rule_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/azurerm/resource_arm_mariadb_virtual_network_rule_test.go b/azurerm/resource_arm_mariadb_virtual_network_rule_test.go index 03781c6ab624..0a5b7b07e2e1 100644 --- a/azurerm/resource_arm_mariadb_virtual_network_rule_test.go +++ b/azurerm/resource_arm_mariadb_virtual_network_rule_test.go @@ -261,7 +261,7 @@ resource "azurerm_mariadb_server" "test" { resource_group_name = "${azurerm_resource_group.test.name}" administrator_login = "acctestun" administrator_login_password = "H@Sh1CoR3!" - version = "5.6" + version = "10.2" ssl_enforcement = "Enabled" sku { @@ -336,7 +336,7 @@ resource "azurerm_mariadb_server" "test" { resource_group_name = "${azurerm_resource_group.test.name}" administrator_login = "acctestun" administrator_login_password = "H@Sh1CoR3!" - version = "5.6" + version = "10.2" ssl_enforcement = "Enabled" sku { @@ -398,7 +398,7 @@ resource "azurerm_mariadb_server" "test" { resource_group_name = "${azurerm_resource_group.test.name}" administrator_login = "acctestun" administrator_login_password = "H@Sh1CoR3!" - version = "5.6" + version = "10.2" ssl_enforcement = "Enabled" sku { @@ -475,7 +475,7 @@ resource "azurerm_mariadb_server" "test" { resource_group_name = "${azurerm_resource_group.test.name}" administrator_login = "acctestun" administrator_login_password = "H@Sh1CoR3!" - version = "5.6" + version = "10.2" ssl_enforcement = "Enabled" sku {