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

New Data Source: azurerm_sql_database #4210

Merged
merged 11 commits into from
Sep 3, 2019
116 changes: 116 additions & 0 deletions azurerm/data_source_sql_database.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package azurerm

import (
"fmt"

"github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql"
"github.com/hashicorp/terraform/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceSqlDatabase() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmSqlDatabaseRead,

Schema: map[string]*schema.Schema{
"collation": {
Type: schema.TypeString,
Computed: true,
},

"default_secondary_location": {
Type: schema.TypeString,
Computed: true,
},

"edition": {
Type: schema.TypeString,
Computed: true,
},

"elastic_pool_name": {
Type: schema.TypeString,
Computed: true,
},

"failover_group_id": {
Type: schema.TypeString,
Computed: true,
},

"location": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Followed by this

Type: schema.TypeString,
Computed: true,
},

"name": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be at the top & first.

Type: schema.TypeString,
Required: true,
},

"read_scale": {
Type: schema.TypeBool,
Computed: true,
},

"resource_group_name": azure.SchemaResourceGroupNameForDataSource(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the rest should follow the ordering found in the resource file.


"server_name": {
Type: schema.TypeString,
Required: true,
},

"tags": tags.Schema(),
},
}
}

func dataSourceArmSqlDatabaseRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).sql.DatabasesClient
ctx := meta.(*ArmClient).StopContext

name := d.Get("name").(string)
resourceGroup := d.Get("resource_group_name").(string)
serverName := d.Get("server_name").(string)

resp, err := client.Get(ctx, resourceGroup, serverName, name, "")
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("SQL Database %q (server %q / resource group %q) was not found", name, serverName, resourceGroup)
}

return fmt.Errorf("Error retrieving SQL Database %q (server %q / resource group %q): %s", name, serverName, resourceGroup, err)
}

if id := resp.ID; id != nil {
d.SetId(*id)
}

d.Set("collation", resp.Collation)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these properties actually reside in the anonymous property resp.DatabaseProperties that could be nil. Thus we need to nil check it:

if props := respo.DatabaseProperties; props != nil {
    d.Set("collation", props.Collation)


if dsLocation := resp.ElasticPoolName; dsLocation != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this check as d.Set will check for nilness

d.Set("default_secondary_location", dsLocation)
}

d.Set("edition", string(resp.Edition))

if ep := resp.ElasticPoolName; ep != nil {
d.Set("elastic_pool_name", ep)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here:

Suggested change
d.Set("elastic_pool_name", ep)
d.Set("elastic_pool_name", props.ElasticPoolName)

}

if fogID := resp.FailoverGroupID; fogID != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here

d.Set("failover_group_id", fogID)
}

d.Set("location", azure.NormalizeLocation(*resp.Location))

readScale := false
if resp.ReadScale == sql.ReadScaleEnabled {
readScale = true
}
d.Set("read_scale", readScale)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be replaced with:

Suggested change
d.Set("read_scale", readScale)
d.Set("read_scale", props.ReadScale == sql.ReadScaleEnabled)


return tags.FlattenAndSet(d, resp.Tags)
}
126 changes: 126 additions & 0 deletions azurerm/data_source_sql_database_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package azurerm

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/resource"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
)

func TestAccDataSourceAzureRMSqlDatabase_basic(t *testing.T) {
dataSourceName := "data.azurerm_sql_database.test"
ri := tf.AccRandTimeInt()
location := testLocation()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMSqlDatabaseDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMSqlDatabase_basic(ri, location),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMSqlDatabaseExists(dataSourceName),
resource.TestCheckResourceAttrSet(dataSourceName, "collation"),
resource.TestCheckResourceAttrSet(dataSourceName, "edition"),
resource.TestCheckResourceAttrSet(dataSourceName, "location"),
resource.TestCheckResourceAttrSet(dataSourceName, "name"),
resource.TestCheckResourceAttrSet(dataSourceName, "read_scale"),
resource.TestCheckResourceAttrSet(dataSourceName, "resource_group_name"),
resource.TestCheckResourceAttrSet(dataSourceName, "server_name"),
resource.TestCheckResourceAttr(dataSourceName, "tags.%", "0"),
),
},
},
})
}

func TestAccDataSourceAzureRMSqlDatabase_elasticPool(t *testing.T) {
dataSourceName := "data.azurerm_sql_database.test"
ri := tf.AccRandTimeInt()
location := testLocation()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMSqlDatabaseDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMSqlDatabase_elasticPool(ri, location),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMSqlDatabaseExists(dataSourceName),
resource.TestCheckResourceAttrSet(dataSourceName, "elastic_pool_name"),
resource.TestCheckResourceAttrSet(dataSourceName, "location"),
resource.TestCheckResourceAttrSet(dataSourceName, "name"),
resource.TestCheckResourceAttrSet(dataSourceName, "resource_group_name"),
resource.TestCheckResourceAttrSet(dataSourceName, "server_name"),
),
},
},
})
}

func TestAccDataSourceAzureRMSqlDatabase_readScale(t *testing.T) {
dataSourceName := "data.azurerm_sql_database.test"
ri := tf.AccRandTimeInt()
location := testLocation()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMSqlDatabaseDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMSqlDatabase_readScale(ri, location, true),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMSqlDatabaseExists(dataSourceName),
resource.TestCheckResourceAttrSet(dataSourceName, "location"),
resource.TestCheckResourceAttrSet(dataSourceName, "name"),
resource.TestCheckResourceAttrSet(dataSourceName, "resource_group_name"),
resource.TestCheckResourceAttr(dataSourceName, "read_scale", "true"),
resource.TestCheckResourceAttrSet(dataSourceName, "server_name"),
),
},
},
})
}

func testAccDataSourceAzureRMSqlDatabase_basic(rInt int, location string) string {
template := testAccAzureRMSqlDatabase_basic(rInt, location)
return fmt.Sprintf(`
%s

data "azurerm_sql_database" "test" {
name = "${azurerm_sql_database.test.name}"
server_name = "${azurerm_sql_database.test.server_name}"
resource_group_name = "${azurerm_resource_group.test.name}"
}
`, template)
}

func testAccDataSourceAzureRMSqlDatabase_elasticPool(rInt int, location string) string {
template := testAccAzureRMSqlDatabase_elasticPool(rInt, location)
return fmt.Sprintf(`
%s

data "azurerm_sql_database" "test" {
name = "${azurerm_sql_database.test.name}"
server_name = "${azurerm_sql_database.test.server_name}"
resource_group_name = "${azurerm_resource_group.test.name}"
}
`, template)
}

func testAccDataSourceAzureRMSqlDatabase_readScale(rInt int, location string, readScale bool) string {
template := testAccAzureRMSqlDatabase_readScale(rInt, location, readScale)
return fmt.Sprintf(`
%s

data "azurerm_sql_database" "test" {
name = "${azurerm_sql_database.test.name}"
server_name = "${azurerm_sql_database.test.server_name}"
resource_group_name = "${azurerm_resource_group.test.name}"
}
`, template)
}
1 change: 1 addition & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_shared_image": dataSourceArmSharedImage(),
"azurerm_snapshot": dataSourceArmSnapshot(),
"azurerm_sql_server": dataSourceSqlServer(),
"azurerm_sql_database": dataSourceSqlDatabase(),
"azurerm_stream_analytics_job": dataSourceArmStreamAnalyticsJob(),
"azurerm_storage_account_sas": dataSourceArmStorageAccountSharedAccessSignature(),
"azurerm_storage_account": dataSourceArmStorageAccount(),
Expand Down
65 changes: 65 additions & 0 deletions website/docs/d/sql_database.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
layout: "azurerm"
page_title: "Azure Resource Manager: azurerm_sql_database"
sidebar_current: "docs-azurerm-datasource-sql-database"
description: |-
Gets information about an existing SQL Azure Database.
---

# Data Source: azurerm_sql_database

Use this data source to access information about an existing SQL Azure Database.

## Example Usage

```hcl
data "azurerm_sql_database" "example" {
name = "example_db"
server_name = "example_db_server"
resource_group_name = "example-resources"
}

output "sql_database_id" {
value = data.azurerm_sql_database.example.id
}
```

## Argument Reference

* `name` - (Required) The name of the SQL Database.

* `server_name` - (Required) The name of the SQL Server.

* `resource_group_name` - (Required) Specifies the name of the Resource Group where the Azure SQL Database exists.

## Attributes Reference

* `id` - The SQL Database ID.

* `collation` - The name of the collation.

* `creation_date` - The creation date of the SQL Database.

* `default_secondary_location` - The default secondary location of the SQL Database.

* `edition` - The edition of the database.

* `elastic_pool_name` - The name of the elastic database pool the database belongs to.

* `failover_group_id` - The ID of the failover group the database belongs to.

* `location` - The location of the Resource Group in which the SQL Server exists.

* `name` - The name of the database.

* `read_scale` - Indicate if read-only connections will be redirected to a high-available replica.

* `requested_service_objective_id` - The ID pertaining to the performance level of the database.

* `requested_service_objective_name` - The name pertaining to the performance level of the database. requested_service_objective_name = data.azurerm_sql_database.database.requested_service_objective_name

* `resource_group_name` - The name of the resource group in which the database resides. This will always be the same resource group as the Database Server.

* `server_name` - The name of the SQL Server on which to create the database.

* `tags` - A mapping of tags assigned to the resource.