Skip to content

Commit

Permalink
Merge pull request #794 from terraform-providers/data-source-storage-…
Browse files Browse the repository at this point in the history
…account

New Data Source: `azurerm_storage_account`
  • Loading branch information
tombuildsstuff authored Feb 6, 2018
2 parents aab2287 + d58562e commit 787f5a0
Show file tree
Hide file tree
Showing 7 changed files with 448 additions and 14 deletions.
275 changes: 275 additions & 0 deletions azurerm/data_source_storage_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
package azurerm

import (
"fmt"
"strings"

"github.com/hashicorp/terraform/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceArmStorageAccount() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmStorageAccountRead,

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

"resource_group_name": resourceGroupNameForDataSourceSchema(),

"location": locationForDataSourceSchema(),

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

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

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

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

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

"custom_domain": {
Type: schema.TypeList,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

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

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

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

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

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

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

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

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

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

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

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

// NOTE: The API does not appear to expose a secondary file endpoint
"primary_file_endpoint": {
Type: schema.TypeString,
Computed: true,
},

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

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

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

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

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

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

"tags": tagsForDataSourceSchema(),
},
}

}

func dataSourceArmStorageAccountRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).storageServiceClient
ctx := meta.(*ArmClient).StopContext
endpointSuffix := meta.(*ArmClient).environment.StorageEndpointSuffix

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

resp, err := client.GetProperties(ctx, resourceGroup, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading the state of AzureRM Storage Account %q: %+v", name, err)
}

d.SetId(*resp.ID)

keys, err := client.ListKeys(ctx, resourceGroup, name)
if err != nil {
return err
}

accessKeys := *keys.Keys
if location := resp.Location; location != nil {
d.Set("location", azureRMNormalizeLocation(*location))
}
d.Set("account_kind", resp.Kind)

if sku := resp.Sku; sku != nil {
d.Set("account_type", sku.Name)
d.Set("account_tier", sku.Tier)
d.Set("account_replication_type", strings.Split(fmt.Sprintf("%v", sku.Name), "_")[1])
}

if props := resp.AccountProperties; props != nil {
d.Set("access_tier", props.AccessTier)
d.Set("enable_https_traffic_only", props.EnableHTTPSTrafficOnly)

if customDomain := props.CustomDomain; customDomain != nil {
if err := d.Set("custom_domain", flattenStorageAccountCustomDomain(customDomain)); err != nil {
return fmt.Errorf("Error flattening `custom_domain`: %+v", err)
}
}

if encryption := props.Encryption; encryption != nil {
if services := encryption.Services; services != nil {
if blob := services.Blob; blob != nil {
d.Set("enable_blob_encryption", blob.Enabled)
}
if file := services.File; file != nil {
d.Set("enable_file_encryption", file.Enabled)
}
}
d.Set("account_encryption_source", string(encryption.KeySource))
}

// Computed
d.Set("primary_location", props.PrimaryLocation)
d.Set("secondary_location", props.SecondaryLocation)

if len(accessKeys) > 0 {
pcs := fmt.Sprintf("DefaultEndpointsProtocol=https;AccountName=%s;AccountKey=%s;EndpointSuffix=%s", *resp.Name, *accessKeys[0].Value, endpointSuffix)
d.Set("primary_connection_string", pcs)
}

if len(accessKeys) > 1 {
scs := fmt.Sprintf("DefaultEndpointsProtocol=https;AccountName=%s;AccountKey=%s;EndpointSuffix=%s", *resp.Name, *accessKeys[1].Value, endpointSuffix)
d.Set("secondary_connection_string", scs)
}

if endpoints := props.PrimaryEndpoints; endpoints != nil {
d.Set("primary_blob_endpoint", endpoints.Blob)
d.Set("primary_queue_endpoint", endpoints.Queue)
d.Set("primary_table_endpoint", endpoints.Table)
d.Set("primary_file_endpoint", endpoints.File)

pscs := fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s",
*endpoints.Blob, *resp.Name, *accessKeys[0].Value)
d.Set("primary_blob_connection_string", pscs)
}

if endpoints := props.SecondaryEndpoints; endpoints != nil {
if blob := endpoints.Blob; blob != nil {
d.Set("secondary_blob_endpoint", blob)
sscs := fmt.Sprintf("DefaultEndpointsProtocol=https;BlobEndpoint=%s;AccountName=%s;AccountKey=%s",
*blob, *resp.Name, *accessKeys[1].Value)
d.Set("secondary_blob_connection_string", sscs)
} else {
d.Set("secondary_blob_endpoint", "")
d.Set("secondary_blob_connection_string", "")
}

if endpoints.Queue != nil {
d.Set("secondary_queue_endpoint", endpoints.Queue)
} else {
d.Set("secondary_queue_endpoint", "")
}

if endpoints.Table != nil {
d.Set("secondary_table_endpoint", endpoints.Table)
} else {
d.Set("secondary_table_endpoint", "")
}
}
}

d.Set("primary_access_key", accessKeys[0].Value)
d.Set("secondary_access_key", accessKeys[1].Value)

flattenAndSetTags(d, resp.Tags)

return nil
}
72 changes: 72 additions & 0 deletions azurerm/data_source_storage_account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package azurerm

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)

func TestAccDataSourceAzureRMStorageAccount_basic(t *testing.T) {
dataSourceName := "data.azurerm_storage_account.test"
ri := acctest.RandInt()
rs := acctest.RandString(4)
location := testLocation()
preConfig := testAccDataSourceAzureRMStorageAccount_basic(ri, rs, location)
config := testAccDataSourceAzureRMStorageAccount_basicWithDataSource(ri, rs, location)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMStorageAccountDestroy,
Steps: []resource.TestStep{
{
Config: preConfig,
},
{
Config: config,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "account_tier", "Standard"),
resource.TestCheckResourceAttr(dataSourceName, "account_replication_type", "LRS"),
resource.TestCheckResourceAttr(dataSourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(dataSourceName, "tags.environment", "production"),
),
},
},
})
}

func testAccDataSourceAzureRMStorageAccount_basic(rInt int, rString string, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestsa-%d"
location = "%s"
}
resource "azurerm_storage_account" "test" {
name = "acctestsads%s"
resource_group_name = "${azurerm_resource_group.test.name}"
location = "${azurerm_resource_group.test.location}"
account_tier = "Standard"
account_replication_type = "LRS"
tags {
environment = "production"
}
}
`, rInt, location, rString)
}

func testAccDataSourceAzureRMStorageAccount_basicWithDataSource(rInt int, rString string, location string) string {
config := testAccDataSourceAzureRMStorageAccount_basic(rInt, rString, location)
return fmt.Sprintf(`
%s
data "azurerm_storage_account" "test" {
name = "${azurerm_storage_account.test.name}"
resource_group_name = "${azurerm_storage_account.test.resource_group_name}"
}
`, config)
}
1 change: 1 addition & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_public_ip": dataSourceArmPublicIP(),
"azurerm_resource_group": dataSourceArmResourceGroup(),
"azurerm_role_definition": dataSourceArmRoleDefinition(),
"azurerm_storage_account": dataSourceArmStorageAccount(),
"azurerm_snapshot": dataSourceArmSnapshot(),
"azurerm_subnet": dataSourceArmSubnet(),
"azurerm_subscription": dataSourceArmSubscription(),
Expand Down
13 changes: 0 additions & 13 deletions azurerm/resource_arm_storage_account.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package azurerm

import (
"context"
"fmt"
"log"
"regexp"
"strings"

"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-06-01/storage"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
Expand Down Expand Up @@ -652,14 +650,3 @@ func validateArmStorageAccountType(v interface{}, k string) (ws []string, es []e
es = append(es, fmt.Errorf("Invalid storage account type %q", input))
return
}

func storageAccountStateRefreshFunc(client storage.AccountsClient, ctx context.Context, resourceGroupName string, storageAccountName string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
res, err := client.GetProperties(ctx, resourceGroupName, storageAccountName)
if err != nil {
return nil, "", fmt.Errorf("Error issuing read request in storageAccountStateRefreshFunc to Azure ARM for Storage Account '%s' (RG: '%s'): %s", storageAccountName, resourceGroupName, err)
}

return res, string(res.AccountProperties.ProvisioningState), nil
}
}
4 changes: 4 additions & 0 deletions website/azurerm.erb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@
<a href="/docs/providers/azurerm/d/role_definition.html">azurerm_role_definition</a>
</li>

<li<%= sidebar_current("docs-azurerm-datasource-storage-account") %>>
<a href="/docs/providers/azurerm/d/storage_account.html">azurerm_storage_account</a>
</li>

<li<%= sidebar_current("docs-azurerm-datasource-subscription") %>>
<a href="/docs/providers/azurerm/d/subscription.html">azurerm_subscription</a>
</li>
Expand Down
Loading

0 comments on commit 787f5a0

Please sign in to comment.