From 357ed8e774ed7dc569c281c11649d726a72d8789 Mon Sep 17 00:00:00 2001 From: aznashwan Date: Wed, 17 Jun 2015 08:04:10 +0300 Subject: [PATCH] Added Azure SQL server and service support. --- builtin/providers/azure/config.go | 5 + builtin/providers/azure/provider.go | 2 + .../resource_azure_sql_database_server.go | 118 +++++++++ ...resource_azure_sql_database_server_test.go | 119 +++++++++ .../resource_azure_sql_database_service.go | 234 ++++++++++++++++++ ...esource_azure_sql_database_service_test.go | 189 ++++++++++++++ .../azure/r/sql_database_server.html.markdown | 50 ++++ .../r/sql_database_service.html.markdown | 53 ++++ website/source/layouts/azure.erb | 8 + 9 files changed, 778 insertions(+) create mode 100644 builtin/providers/azure/resource_azure_sql_database_server.go create mode 100644 builtin/providers/azure/resource_azure_sql_database_server_test.go create mode 100644 builtin/providers/azure/resource_azure_sql_database_service.go create mode 100644 builtin/providers/azure/resource_azure_sql_database_service_test.go create mode 100644 website/source/docs/providers/azure/r/sql_database_server.html.markdown create mode 100644 website/source/docs/providers/azure/r/sql_database_service.html.markdown diff --git a/builtin/providers/azure/config.go b/builtin/providers/azure/config.go index cf02bf557..52c69d40c 100644 --- a/builtin/providers/azure/config.go +++ b/builtin/providers/azure/config.go @@ -9,6 +9,7 @@ import ( "github.com/Azure/azure-sdk-for-go/management/hostedservice" "github.com/Azure/azure-sdk-for-go/management/networksecuritygroup" "github.com/Azure/azure-sdk-for-go/management/osimage" + "github.com/Azure/azure-sdk-for-go/management/sql" "github.com/Azure/azure-sdk-for-go/management/storageservice" "github.com/Azure/azure-sdk-for-go/management/virtualmachine" "github.com/Azure/azure-sdk-for-go/management/virtualmachinedisk" @@ -36,6 +37,8 @@ type Client struct { osImageClient osimage.OSImageClient + sqlClient sql.SqlDatabaseClient + storageServiceClient storageservice.StorageServiceClient vmClient virtualmachine.VirtualMachineClient @@ -107,6 +110,7 @@ func (c *Config) NewClientFromSettingsFile() (*Client, error) { hostedServiceClient: hostedservice.NewClient(mc), secGroupClient: networksecuritygroup.NewClient(mc), osImageClient: osimage.NewClient(mc), + sqlClient: sql.NewClient(mc), storageServiceClient: storageservice.NewClient(mc), vmClient: virtualmachine.NewClient(mc), vmDiskClient: virtualmachinedisk.NewClient(mc), @@ -129,6 +133,7 @@ func (c *Config) NewClient() (*Client, error) { hostedServiceClient: hostedservice.NewClient(mc), secGroupClient: networksecuritygroup.NewClient(mc), osImageClient: osimage.NewClient(mc), + sqlClient: sql.NewClient(mc), storageServiceClient: storageservice.NewClient(mc), vmClient: virtualmachine.NewClient(mc), vmDiskClient: virtualmachinedisk.NewClient(mc), diff --git a/builtin/providers/azure/provider.go b/builtin/providers/azure/provider.go index 98a7b2a09..a6be93f5c 100644 --- a/builtin/providers/azure/provider.go +++ b/builtin/providers/azure/provider.go @@ -34,6 +34,8 @@ func Provider() terraform.ResourceProvider { ResourcesMap: map[string]*schema.Resource{ "azure_instance": resourceAzureInstance(), "azure_data_disk": resourceAzureDataDisk(), + "azure_sql_database_server": resourceAzureSqlDatabaseServer(), + "azure_sql_database_service": resourceAzureSqlDatabaseService(), "azure_hosted_service": resourceAzureHostedService(), "azure_storage_service": resourceAzureStorageService(), "azure_storage_container": resourceAzureStorageContainer(), diff --git a/builtin/providers/azure/resource_azure_sql_database_server.go b/builtin/providers/azure/resource_azure_sql_database_server.go new file mode 100644 index 000000000..b3412b7b3 --- /dev/null +++ b/builtin/providers/azure/resource_azure_sql_database_server.go @@ -0,0 +1,118 @@ +package azure + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/management/sql" + "github.com/hashicorp/terraform/helper/schema" +) + +// resourceAzureDatabaseServer returns the *schema.Resource associated +// to a database server on Azure. +func resourceAzureSqlDatabaseServer() *schema.Resource { + return &schema.Resource{ + Create: resourceAzureSqlDatabaseServerCreate, + Read: resourceAzureSqlDatabaseServerRead, + Delete: resourceAzureSqlDatabaseServerDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + ForceNew: true, + }, + "location": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "username": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "password": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "version": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "12.0", + ForceNew: true, + }, + "url": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +// resourceAzureSqlDatabaseServerCreate does all the necessary API calls to +// create an SQL database server off Azure. +func resourceAzureSqlDatabaseServerCreate(d *schema.ResourceData, meta interface{}) error { + sqlClient := meta.(*Client).sqlClient + + log.Println("[INFO] Began constructing SQL Server creation request.") + params := sql.DatabaseServerCreateParams{ + Location: d.Get("location").(string), + AdministratorLogin: d.Get("username").(string), + AdministratorLoginPassword: d.Get("password").(string), + Version: d.Get("version").(string), + } + + log.Println("[INFO] Issuing SQL Server creation request to Azure.") + name, err := sqlClient.CreateServer(params) + if err != nil { + return fmt.Errorf("Error creating SQL Server on Azure: %s", err) + } + + d.Set("name", name) + + d.SetId(name) + return resourceAzureSqlDatabaseServerRead(d, meta) +} + +// resourceAzureSqlDatabaseServerRead does all the necessary API calls to +// read the state of the SQL database server off Azure. +func resourceAzureSqlDatabaseServerRead(d *schema.ResourceData, meta interface{}) error { + sqlClient := meta.(*Client).sqlClient + + log.Println("[INFO] Sending SQL Servers list query to Azure.") + srvList, err := sqlClient.ListServers() + if err != nil { + return fmt.Errorf("Error issuing SQL Servers list query to Azure: %s", err) + } + + // search for our particular server: + name := d.Get("name") + for _, srv := range srvList.DatabaseServers { + if srv.Name == name { + d.Set("url", srv.FullyQualifiedDomainName) + d.Set("state", srv.State) + return nil + } + } + + // if reached here; it means out server doesn't exist, so we must untrack it: + d.SetId("") + return nil +} + +// resourceAzureSqlDatabaseServerDelete does all the necessary API calls to +// delete the SQL database server off Azure. +func resourceAzureSqlDatabaseServerDelete(d *schema.ResourceData, meta interface{}) error { + sqlClient := meta.(*Client).sqlClient + + log.Println("[INFO] Sending SQL Server deletion request to Azure.") + name := d.Get("name").(string) + err := sqlClient.DeleteServer(name) + if err != nil { + return fmt.Errorf("Error while issuing SQL Server deletion request to Azure: %s", err) + } + + return nil +} diff --git a/builtin/providers/azure/resource_azure_sql_database_server_test.go b/builtin/providers/azure/resource_azure_sql_database_server_test.go new file mode 100644 index 000000000..8f65b3992 --- /dev/null +++ b/builtin/providers/azure/resource_azure_sql_database_server_test.go @@ -0,0 +1,119 @@ +package azure + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +// testAccAzureSqlServerName is a helper variable in which to store +// the randomly-generated name of the SQL Server after it is created. +// The anonymous function is there because go is too good to &"" directly. +var testAccAzureSqlServerName *string = func(s string) *string { return &s }("") + +func TestAccAzureSqlDatabaseServer(t *testing.T) { + name := "azure_sql_database_server.foo" + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAzureSqlDatabaseServerDeleted, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAzureSqlDatabaseServerConfig, + Check: resource.ComposeTestCheckFunc( + testAccAzureSqlDatabaseServerGetName, + testAccCheckAzureSqlDatabaseServerExists(name), + resource.TestCheckResourceAttrPtr(name, "name", testAccAzureSqlServerName), + resource.TestCheckResourceAttr(name, "username", "SuperUser"), + resource.TestCheckResourceAttr(name, "password", "SuperSEKR3T"), + resource.TestCheckResourceAttr(name, "version", "2.0"), + ), + }, + }, + }) +} + +func testAccCheckAzureSqlDatabaseServerExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + resource, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("SQL Server %s doesn't exist.", name) + } + + if resource.Primary.ID == "" { + return fmt.Errorf("SQL Server %s resource ID not set.", name) + } + + sqlClient := testAccProvider.Meta().(*Client).sqlClient + servers, err := sqlClient.ListServers() + if err != nil { + return fmt.Errorf("Error issuing Azure SQL Server list request: %s", err) + } + + for _, srv := range servers.DatabaseServers { + if srv.Name == resource.Primary.ID { + return nil + } + } + + return fmt.Errorf("SQL Server %s doesn't exist.", name) + } +} + +func testAccCheckAzureSqlDatabaseServerDeleted(s *terraform.State) error { + for _, resource := range s.RootModule().Resources { + if resource.Type != "azure_sql_database_server" { + continue + } + + if resource.Primary.ID == "" { + return fmt.Errorf("SQL Server resource ID not set.") + } + + sqlClient := testAccProvider.Meta().(*Client).sqlClient + servers, err := sqlClient.ListServers() + if err != nil { + return fmt.Errorf("Error issuing Azure SQL Server list request: %s", err) + } + + for _, srv := range servers.DatabaseServers { + if srv.Name == resource.Primary.ID { + fmt.Errorf("SQL Server %s still exists.", resource.Primary.ID) + } + } + } + return nil +} + +// testAccAzureSqlDatabaseServerGetName is ahelper function which reads the current +// state form Terraform and sets the testAccAzureSqlServerName variable +// to the ID (which is actually the name) of the newly created server. +// It is modeled as a resource.TestCheckFunc so as to be easily-embeddable in +// test cases and run live. +func testAccAzureSqlDatabaseServerGetName(s *terraform.State) error { + for _, resource := range s.RootModule().Resources { + if resource.Type != "azure_sql_database_server" { + continue + } + + if resource.Primary.ID == "" { + return fmt.Errorf("Azure SQL Server resource ID not set.") + } + + *testAccAzureSqlServerName = resource.Primary.ID + return nil + } + + return fmt.Errorf("No Azure SQL Servers found.") +} + +const testAccAzureSqlDatabaseServerConfig = ` +resource "azure_sql_database_server" "foo" { + location = "West US" + username = "SuperUser" + password = "SuperSEKR3T" + version = "2.0" +} +` diff --git a/builtin/providers/azure/resource_azure_sql_database_service.go b/builtin/providers/azure/resource_azure_sql_database_service.go new file mode 100644 index 000000000..29824d743 --- /dev/null +++ b/builtin/providers/azure/resource_azure_sql_database_service.go @@ -0,0 +1,234 @@ +package azure + +import ( + "fmt" + "log" + "strconv" + "strings" + + "github.com/Azure/azure-sdk-for-go/management/sql" + "github.com/hashicorp/terraform/helper/schema" +) + +// resourceAzureSqlDatabaseService returns the *schema.Resource +// associated to an SQL Database Service on Azure. +func resourceAzureSqlDatabaseService() *schema.Resource { + return &schema.Resource{ + Create: resourceAzureSqlDatabaseServiceCreate, + Read: resourceAzureSqlDatabaseServiceRead, + Update: resourceAzureSqlDatabaseServiceUpdate, + Exists: resourceAzureSqlDatabaseServiceExists, + Delete: resourceAzureSqlDatabaseServiceDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "database_server_name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "collation": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "edition": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "max_size_bytes": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "service_level_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + } +} + +// resourceAzureSqlDatabaseServiceCreate does all the necessary API calls to +// create an SQL Database Service on Azure. +func resourceAzureSqlDatabaseServiceCreate(d *schema.ResourceData, meta interface{}) error { + sqlClient := meta.(*Client).sqlClient + + log.Println("[INFO] Creating Azure SQL Database service creation request.") + name := d.Get("name").(string) + serverName := d.Get("database_server_name").(string) + params := sql.DatabaseCreateParams{ + Name: name, + Edition: d.Get("edition").(string), + CollationName: d.Get("collation").(string), + ServiceObjectiveID: d.Get("service_level_id").(string), + } + + if maxSize, ok := d.GetOk("max_size_bytes"); ok { + val, err := strconv.ParseInt(maxSize.(string), 10, 64) + if err != nil { + return fmt.Errorf("Provided max_size_bytes is not an integer: %s", err) + } + params.MaxSizeBytes = val + } + + log.Println("[INFO] Sending SQL Database Service creation request to Azure.") + err := sqlClient.CreateDatabase(serverName, params) + if err != nil { + return fmt.Errorf("Error issuing Azure SQL Database Service creation: %s", err) + } + + log.Println("[INFO] Beginning wait for Azure SQL Database Service creation.") + err = sqlClient.WaitForDatabaseCreation(serverName, name, nil) + if err != nil { + return fmt.Errorf("Error whilst waiting for Azure SQL Database Service creation: %s", err) + } + + d.SetId(name) + + return resourceAzureSqlDatabaseServiceRead(d, meta) +} + +// resourceAzureSqlDatabaseServiceRead does all the necessary API calls to +// read the state of the SQL Database Service off Azure. +func resourceAzureSqlDatabaseServiceRead(d *schema.ResourceData, meta interface{}) error { + sqlClient := meta.(*Client).sqlClient + + log.Println("[INFO] Issuing Azure SQL Database Services list operation.") + serverName := d.Get("database_server_name").(string) + dbs, err := sqlClient.ListDatabases(serverName) + if err != nil { + return fmt.Errorf("Error whilst listing Database Services off Azure: %s", err) + } + + // search for our database: + var found bool + name := d.Get("name").(string) + for _, db := range dbs.ServiceResources { + if db.Name == name { + found = true + d.Set("edition", db.Edition) + d.Set("collation", db.CollationName) + d.Set("max_size_bytes", strconv.FormatInt(db.MaxSizeBytes, 10)) + d.Set("service_level_id", db.ServiceObjectiveID) + break + } + } + + // if not found; we must untrack the resource: + if !found { + d.SetId("") + } + + return nil +} + +// resourceAzureSqlDatabaseServiceUpdate does all the necessary API calls to +// update the state of the SQL Database Service off Azure. +func resourceAzureSqlDatabaseServiceUpdate(d *schema.ResourceData, meta interface{}) error { + azureClient := meta.(*Client) + mgmtClient := azureClient.mgmtClient + sqlClient := azureClient.sqlClient + serverName := d.Get("database_server_name").(string) + + // changes to the name must occur seperately from changes to the attributes: + if d.HasChange("name") { + oldv, newv := d.GetChange("name") + + // issue the update request: + log.Println("[INFO] Issuing Azure Database Service name change.") + reqID, err := sqlClient.UpdateDatabase(serverName, oldv.(string), + sql.ServiceResourceUpdateParams{ + Name: newv.(string), + }) + + // wait for the update to occur: + log.Println("[INFO] Waiting for Azure SQL Database Service name change.") + err = mgmtClient.WaitForOperation(reqID, nil) + if err != nil { + return fmt.Errorf("Error waiting for Azure SQL Database Service name update: %s", err) + } + + // set the new name as the ID: + d.SetId(newv.(string)) + } + + name := d.Get("name").(string) + cedition := d.HasChange("edition") + cmaxsize := d.HasChange("max_size_bytes") + clevel := d.HasChange("service_level_id") + if cedition || cmaxsize || clevel { + updateParams := sql.ServiceResourceUpdateParams{ + // we still have to stick the name in here for good measure: + Name: name, + } + + // build the update request: + if cedition { + updateParams.Edition = d.Get("edition").(string) + } + if maxSize, ok := d.GetOk("max_size_bytes"); cmaxsize && ok && maxSize.(string) != "" { + val, err := strconv.ParseInt(maxSize.(string), 10, 64) + if err != nil { + return fmt.Errorf("Provided max_size_bytes is not an integer: %s", err) + } + updateParams.MaxSizeBytes = val + } + if clevel { + updateParams.ServiceObjectiveID = d.Get("service_level_id").(string) + } + + // issue the update: + log.Println("[INFO] Issuing Azure Database Service parameter update.") + reqID, err := sqlClient.UpdateDatabase(serverName, name, updateParams) + if err != nil { + return fmt.Errorf("Failed issuing Azure SQL Service paramater update: %s", err) + } + + log.Println("[INFO] Waiting for Azure SQL Database Service parameter update.") + err = mgmtClient.WaitForOperation(reqID, nil) + if err != nil { + return fmt.Errorf("Error waiting for Azure SQL Database Service parameter update: %s", err) + } + } + + return nil +} + +// resourceAzureSqlDatabaseServiceExists does all the necessary API calls to +// check for the existence of the SQL Database Service off Azure. +func resourceAzureSqlDatabaseServiceExists(d *schema.ResourceData, meta interface{}) (bool, error) { + sqlClient := meta.(*Client).sqlClient + + log.Println("[INFO] Issuing Azure SQL Database Service get request.") + name := d.Get("name").(string) + serverName := d.Get("database_server_name").(string) + _, err := sqlClient.GetDatabase(serverName, name) + if err != nil { + if strings.Contains(err.Error(), "does not exist") { + d.SetId("") + return false, nil + } else { + return false, fmt.Errorf("Error whilst getting Azure SQL Database Service info: %s", err) + } + } + + return true, nil +} + +// resourceAzureSqlDatabaseServiceDelete does all the necessary API calls to +// delete the SQL Database Service off Azure. +func resourceAzureSqlDatabaseServiceDelete(d *schema.ResourceData, meta interface{}) error { + sqlClient := meta.(*Client).sqlClient + + log.Println("[INFO] Issuing Azure SQL Database deletion request.") + name := d.Get("name").(string) + serverName := d.Get("database_server_name").(string) + return sqlClient.DeleteDatabase(serverName, name) +} diff --git a/builtin/providers/azure/resource_azure_sql_database_service_test.go b/builtin/providers/azure/resource_azure_sql_database_service_test.go new file mode 100644 index 000000000..bc93fdb62 --- /dev/null +++ b/builtin/providers/azure/resource_azure_sql_database_service_test.go @@ -0,0 +1,189 @@ +package azure + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureSqlDatabaseServiceBasic(t *testing.T) { + name := "azure_sql_database_service.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAzureSqlDatabaseServiceDeleted, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAzureSqlDatabaseServiceConfigBasic, + Check: resource.ComposeTestCheckFunc( + testAccAzureSqlDatabaseServerGetName, + testAccCheckAzureSqlDatabaseServiceExists(name), + resource.TestCheckResourceAttr(name, "name", "terraform-testing-db"), + resource.TestCheckResourceAttrPtr(name, "database_server_name", + testAccAzureSqlServerName), + resource.TestCheckResourceAttr(name, "collation", + "SQL_Latin1_General_CP1_CI_AS"), + resource.TestCheckResourceAttr(name, "edition", "Standard"), + ), + }, + }, + }) +} + +func TestAccAzureSqlDatabaseServiceAdvanced(t *testing.T) { + name := "azure_sql_database_service.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAzureSqlDatabaseServiceDeleted, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAzureSqlDatabaseServiceConfigAdvanced, + Check: resource.ComposeTestCheckFunc( + testAccAzureSqlDatabaseServerGetName, + testAccCheckAzureSqlDatabaseServiceExists(name), + resource.TestCheckResourceAttr(name, "name", "terraform-testing-db"), + resource.TestCheckResourceAttrPtr(name, "database_server_name", + testAccAzureSqlServerName), + resource.TestCheckResourceAttr(name, "edition", "Premium"), + resource.TestCheckResourceAttr(name, "collation", + "Arabic_BIN"), + resource.TestCheckResourceAttr(name, "max_size_bytes", "10737418240"), + resource.TestCheckResourceAttr(name, "service_level_id", + "7203483a-c4fb-4304-9e9f-17c71c904f5d"), + ), + }, + }, + }) +} + +func TestAccAzureSqlDatabaseServiceUpdate(t *testing.T) { + name := "azure_sql_database_service.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAzureSqlDatabaseServiceDeleted, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAzureSqlDatabaseServiceConfigAdvanced, + Check: resource.ComposeTestCheckFunc( + testAccAzureSqlDatabaseServerGetName, + testAccCheckAzureSqlDatabaseServiceExists(name), + resource.TestCheckResourceAttr(name, "name", "terraform-testing-db"), + resource.TestCheckResourceAttrPtr(name, "database_server_name", + testAccAzureSqlServerName), + resource.TestCheckResourceAttr(name, "edition", "Premium"), + resource.TestCheckResourceAttr(name, "collation", + "Arabic_BIN"), + resource.TestCheckResourceAttr(name, "max_size_bytes", "10737418240"), + resource.TestCheckResourceAttr(name, "service_level_id", + "7203483a-c4fb-4304-9e9f-17c71c904f5d"), + ), + }, + resource.TestStep{ + Config: testAccAzureSqlDatabaseServiceConfigUpdate, + Check: resource.ComposeTestCheckFunc( + testAccAzureSqlDatabaseServerGetName, + testAccCheckAzureSqlDatabaseServiceExists(name), + resource.TestCheckResourceAttr(name, "name", + "terraform-testing-db-renamed"), + resource.TestCheckResourceAttrPtr(name, "database_server_name", + testAccAzureSqlServerName), + resource.TestCheckResourceAttr(name, "edition", "Standard"), + resource.TestCheckResourceAttr(name, "collation", + "SQL_Latin1_General_CP1_CI_AS"), + resource.TestCheckResourceAttr(name, "max_size_bytes", "5368709120"), + resource.TestCheckResourceAttr(name, "service_level_id", + "f1173c43-91bd-4aaa-973c-54e79e15235b"), + ), + }, + }, + }) +} + +func testAccCheckAzureSqlDatabaseServiceExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + resource, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("SQL Service %s doesn't exist.", name) + } + + if resource.Primary.ID == "" { + return fmt.Errorf("SQL Service %s resource ID not set.", name) + } + + sqlClient := testAccProvider.Meta().(*Client).sqlClient + dbs, err := sqlClient.ListDatabases(*testAccAzureSqlServerName) + if err != nil { + return fmt.Errorf("Error issuing Azure SQL Service list request: %s", err) + } + + for _, srv := range dbs.ServiceResources { + if srv.Name == resource.Primary.ID { + return nil + } + } + + return fmt.Errorf("SQL Service %s doesn't exist.", name) + } +} + +func testAccCheckAzureSqlDatabaseServiceDeleted(s *terraform.State) error { + for _, resource := range s.RootModule().Resources { + if resource.Type != "azure_sql_database_server" { + continue + } + + if resource.Primary.ID == "" { + return fmt.Errorf("SQL Service resource ID not set.") + } + + sqlClient := testAccProvider.Meta().(*Client).sqlClient + dbs, err := sqlClient.ListDatabases(*testAccAzureSqlServerName) + if err != nil { + return fmt.Errorf("Error issuing Azure SQL Service list request: %s", err) + } + + for _, srv := range dbs.ServiceResources { + if srv.Name == resource.Primary.ID { + fmt.Errorf("SQL Service %s still exists.", resource.Primary.ID) + } + } + } + return nil +} + +const testAccAzureSqlDatabaseServiceConfigBasic = testAccAzureSqlDatabaseServerConfig + ` +resource "azure_sql_database_service" "foo" { + name = "terraform-testing-db" + database_server_name = "${azure_sql_database_server.foo.name}" + edition = "Standard" +} +` + +const testAccAzureSqlDatabaseServiceConfigAdvanced = testAccAzureSqlDatabaseServerConfig + ` +resource "azure_sql_database_service" "foo" { + name = "terraform-testing-db" + database_server_name = "${azure_sql_database_server.foo.name}" + edition = "Premium" + collation = "Arabic_BIN" + max_size_bytes = "10737418240" + service_level_id = "7203483a-c4fb-4304-9e9f-17c71c904f5d" +} +` + +const testAccAzureSqlDatabaseServiceConfigUpdate = testAccAzureSqlDatabaseServerConfig + ` +resource "azure_sql_database_service" "foo" { + name = "terraform-testing-db-renamed" + database_server_name = "${azure_sql_database_server.foo.name}" + edition = "Standard" + collation = "SQL_Latin1_General_CP1_CI_AS" + max_size_bytes = "5368709120" + service_level_id = "f1173c43-91bd-4aaa-973c-54e79e15235b" +} +` diff --git a/website/source/docs/providers/azure/r/sql_database_server.html.markdown b/website/source/docs/providers/azure/r/sql_database_server.html.markdown new file mode 100644 index 000000000..c03873181 --- /dev/null +++ b/website/source/docs/providers/azure/r/sql_database_server.html.markdown @@ -0,0 +1,50 @@ +--- +layout: "azure" +page_title: "Azure: azure_sql_database_server" +sidebar_current: "docs-azure-sql-database-server" +description: |- + Allocates a new SQL Database Server on Azure. +--- + +# azure\_sql\_database\_server + +Allocates a new SQL Database Server on Azure. + +## Example Usage + +``` +resource "azure_sql_database_server" "sql-serv" { + name = "" + location = "West US" + username = "SuperUser" + password = "SuperSEKR3T" + version = "2.0" + url = "" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Computed) The name of the database server. It is determined upon + creation as it is randomly-generated per server. + +* `location` - (Required) The location where the database server should be created. + For a list of all Azure locations, please consult [this link](http://azure.microsoft.com/en-us/regions/). + +* `username` - (Required) The username for the administrator of the database server. + +* `password` - (Required) The password for the administrator of the database server. + +* `version` - (Optional) The version of the database server to be used. Can be any + one of `2.0` or `12.0`. + +* `url` - (Computed) The fully qualified domain name of the database server. + Will be of the form `.database.windows.net`. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The database server ID. Coincides with the randomly-generated `name`. diff --git a/website/source/docs/providers/azure/r/sql_database_service.html.markdown b/website/source/docs/providers/azure/r/sql_database_service.html.markdown new file mode 100644 index 000000000..aeabda52b --- /dev/null +++ b/website/source/docs/providers/azure/r/sql_database_service.html.markdown @@ -0,0 +1,53 @@ +--- +layout: "azure" +page_title: "Azure: azure_sql_database_service" +sidebar_current: "docs-azure-sql-database-service" +description: |- + Creates a new SQL Database Service on an Azure Database Server. +--- + +# azure\_sql\_database\_service + +Creates a new SQL database service on an Azure database server. + +## Example Usage + +``` +resource "azure_sql_database_service" "sql-server" { + name = "terraform-testing-db-renamed" + database_server_name = "flibberflabber" + edition = "Standard" + collation = "SQL_Latin1_General_CP1_CI_AS" + max_size_bytes = "5368709120" + service_level_id = "f1173c43-91bd-4aaa-973c-54e79e15235b" +} + +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the database service. + +* `database_server_name` - (Required) The name of the database server this service + should run on. Changes here force the creation of a new resource. + +* `edition` - (Optional) The edition of the database service. For more information + on each variant, please view [this](https://msdn.microsoft.com/library/azure/dn741340.aspx) link. + +* `collation` - (Optional) The collation to be used within the database service. + Defaults to the standard Latin charset. + +* `max_size_bytes` - (Optional) The maximum size in bytes the database service + should be allowed to expand to. Range depends on the database `edition` + selected above. + +* `service_level_id` - (Optional) The ID corresponding to the service level per + edition. Please refer to [this](https://msdn.microsoft.com/en-us/library/azure/dn505701.aspx) link for more details. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The database service ID. Coincides with the given `name`. diff --git a/website/source/layouts/azure.erb b/website/source/layouts/azure.erb index f01048285..4fc096f0e 100644 --- a/website/source/layouts/azure.erb +++ b/website/source/layouts/azure.erb @@ -41,6 +41,14 @@ azure_security_group_rule + > + azure_sql_database_server + + + > + azure_sql_database_service + + > azure_storage_blob