diff --git a/azurerm/resource_arm_sql_database.go b/azurerm/resource_arm_sql_database.go index 30f2b03a184f..0483646ac8db 100644 --- a/azurerm/resource_arm_sql_database.go +++ b/azurerm/resource_arm_sql_database.go @@ -3,6 +3,7 @@ package azurerm import ( "fmt" "log" + "strings" "time" "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" @@ -57,6 +58,61 @@ func resourceArmSqlDatabase() *schema.Resource { DiffSuppressFunc: ignoreCaseDiffSuppressFunc, }, + "import": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "storage_uri": { + Type: schema.TypeString, + Required: true, + }, + "storage_key": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "storage_key_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "StorageAccessKey", + "SharedAccessKey", + }, true), + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + }, + "administrator_login": { + Type: schema.TypeString, + Required: true, + }, + "administrator_login_password": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "authentication_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "ADPassword", + "SQL", + }, true), + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + }, + "operation_mode": { + Type: schema.TypeString, + Optional: true, + Default: "Import", + ValidateFunc: validation.StringInSlice([]string{ + "Import", + }, true), + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, + }, + }, + }, + }, + "source_database_id": { Type: schema.TypeString, Optional: true, @@ -238,6 +294,27 @@ func resourceArmSqlDatabaseCreateUpdate(d *schema.ResourceData, meta interface{} return err } + if _, ok := d.GetOk("import"); ok { + if !strings.EqualFold(createMode, "default") { + return fmt.Errorf("import can only be used when create_mode is Default") + } + importParameters := expandAzureRmSqlDatabaseImport(d) + importFuture, err := client.CreateImportOperation(ctx, resourceGroup, serverName, name, importParameters) + if err != nil { + return err + } + + // this is set in config.go, but something sets + // it back to 15 minutes, which isn't long enough + // for most imports + client.Client.PollingDuration = 60 * time.Minute + + err = importFuture.WaitForCompletion(ctx, client.Client) + if err != nil { + return err + } + } + resp, err := client.Get(ctx, resourceGroup, serverName, name, "") if err != nil { return err @@ -356,3 +433,21 @@ func flattenEncryptionStatus(encryption *[]sql.TransparentDataEncryption) string return "" } + +func expandAzureRmSqlDatabaseImport(d *schema.ResourceData) sql.ImportExtensionRequest { + v := d.Get("import") + dbimportRefs := v.([]interface{}) + dbimportRef := dbimportRefs[0].(map[string]interface{}) + return sql.ImportExtensionRequest{ + Name: utils.String("terraform"), + ImportExtensionProperties: &sql.ImportExtensionProperties{ + StorageKeyType: sql.StorageKeyType(dbimportRef["storage_key_type"].(string)), + StorageKey: utils.String(dbimportRef["storage_key"].(string)), + StorageURI: utils.String(dbimportRef["storage_uri"].(string)), + AdministratorLogin: utils.String(dbimportRef["administrator_login"].(string)), + AdministratorLoginPassword: utils.String(dbimportRef["administrator_login_password"].(string)), + AuthenticationType: sql.AuthenticationType(dbimportRef["authentication_type"].(string)), + OperationMode: utils.String(dbimportRef["operation_mode"].(string)), + }, + } +} diff --git a/azurerm/resource_arm_sql_database_test.go b/azurerm/resource_arm_sql_database_test.go index 964dc6f22a6d..cc8fbfd022d5 100644 --- a/azurerm/resource_arm_sql_database_test.go +++ b/azurerm/resource_arm_sql_database_test.go @@ -265,6 +265,25 @@ func testCheckAzureRMSqlDatabaseDisappears(name string) resource.TestCheckFunc { } } +func TestAccAzureRMSqlDatabase_bacpac(t *testing.T) { + ri := acctest.RandInt() + config := testAccAzureRMSqlDatabase_bacpac(ri, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMSqlDatabaseDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMSqlDatabaseExists("azurerm_sql_database.test"), + ), + }, + }, + }) +} + func testAccAzureRMSqlDatabase_basic(rInt int, location string) string { return fmt.Sprintf(` resource "azurerm_resource_group" "test" { @@ -496,3 +515,73 @@ resource "azurerm_sql_database" "test" { } `, rInt, location, rInt, rInt) } + +func testAccAzureRMSqlDatabase_bacpac(rInt int, location string) string { + return fmt.Sprintf(` + resource "azurerm_resource_group" "test" { + name = "acctestRG_%d" + location = "%s" + } + + resource "azurerm_storage_account" "test" { + name = "accsa%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + account_tier = "Standard" + account_replication_type = "LRS" + } + + resource "azurerm_storage_container" "test" { + name = "bacpac" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + container_access_type = "private" + } + + resource "azurerm_storage_blob" "test" { + name = "test.bacpac" + resource_group_name = "${azurerm_resource_group.test.name}" + storage_account_name = "${azurerm_storage_account.test.name}" + storage_container_name = "${azurerm_storage_container.test.name}" + type = "block" + source = "testdata/sql_import.bacpac" + } + + resource "azurerm_sql_server" "test" { + name = "acctestsqlserver%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + version = "12.0" + administrator_login = "mradministrator" + administrator_login_password = "thisIsDog11" + } + + resource "azurerm_sql_firewall_rule" "test" { + name = "allowazure" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_sql_server.test.name}" + start_ip_address = "0.0.0.0" + end_ip_address = "0.0.0.0" + } + + resource "azurerm_sql_database" "test" { + name = "acctestdb%d" + resource_group_name = "${azurerm_resource_group.test.name}" + server_name = "${azurerm_sql_server.test.name}" + location = "${azurerm_resource_group.test.location}" + edition = "Standard" + collation = "SQL_Latin1_General_CP1_CI_AS" + max_size_bytes = "1073741824" + requested_service_objective_name = "S0" + + import { + storage_uri = "${azurerm_storage_blob.test.url}" + storage_key = "${azurerm_storage_account.test.primary_access_key}" + storage_key_type = "StorageAccessKey" + administrator_login = "${azurerm_sql_server.test.administrator_login}" + administrator_login_password = "${azurerm_sql_server.test.administrator_login_password}" + authentication_type = "SQL" + } + } + `, rInt, location, rInt, rInt, rInt) +} diff --git a/azurerm/testdata/sql_import.bacpac b/azurerm/testdata/sql_import.bacpac new file mode 100644 index 000000000000..98825ab441bb Binary files /dev/null and b/azurerm/testdata/sql_import.bacpac differ diff --git a/website/docs/r/sql_database.html.markdown b/website/docs/r/sql_database.html.markdown index 4d402d27db35..8bfacf83daa9 100644 --- a/website/docs/r/sql_database.html.markdown +++ b/website/docs/r/sql_database.html.markdown @@ -52,6 +52,8 @@ The following arguments are supported: * `create_mode` - (Optional) Specifies the type of database to create. Defaults to `Default`. See below for the accepted values/ +* `import` - (Optional) A Database Import block as documented below. `create_mode` must be set to `Default`. + * `source_database_id` - (Optional) The URI of the source database if `create_mode` value is not `Default`. * `restore_point_in_time` - (Optional) The point in time for the restore. Only applies if `create_mode` is `PointInTimeRestore` e.g. 2013-11-08T22:00:40Z @@ -73,6 +75,16 @@ The following arguments are supported: * `tags` - (Optional) A mapping of tags to assign to the resource. +`import` supports the following: + +* `storage_uri` - (Required) Specifies the blob URI of the .bacpac file. +* `storage_key` - (Required) Specifies the access key for the storage account. +* `storage_key_type` - (Required) Specifies the type of access key for the storage account. Valid values are `StorageAccessKey` or `SharedAccessKey`. +* `administrator_login` - (Required) Specifies the name of the SQL administrator. +* `administrator_login_password` - (Required) Specifies the password of the SQL administrator. +* `authentication_type` - (Required) Specifies the type of authentication used to access the server. Valid values are `SQL` or `ADPassword`. +* `operation_mode` - (Optional) Specifies the type of import operation being performed. The only allowable value is `Import`. + ## Attributes Reference The following attributes are exported: