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 resource - azurerm_storage_account_blob_settings #3807

Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions azurerm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,9 @@ type ArmClient struct {
web *web.Client

// Storage
storageServiceClient storage.AccountsClient
storageUsageClient storage.UsagesClient
storageServiceClient storage.AccountsClient
storageUsageClient storage.UsagesClient
storageBlobServicesClient storage.BlobServicesClient
}

// getArmClient is a helper method which returns a fully instantiated
Expand Down Expand Up @@ -325,6 +326,10 @@ func (c *ArmClient) registerStorageClients(endpoint, subscriptionId string, auth
c.configureClient(&usageClient.Client, auth)
c.storageUsageClient = usageClient

blobServicesClient := storage.NewBlobServicesClientWithBaseURI(endpoint, subscriptionId)
c.configureClient(&blobServicesClient.Client, auth)
c.storageBlobServicesClient = blobServicesClient

c.storage = intStor.BuildClient(accountsClient, options)
}

Expand Down
1 change: 1 addition & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_sql_server": resourceArmSqlServer(),
"azurerm_sql_virtual_network_rule": resourceArmSqlVirtualNetworkRule(),
"azurerm_storage_account": resourceArmStorageAccount(),
"azurerm_storage_account_blob_settings": resourceArmStorageAccountBlobSettings(),
"azurerm_storage_blob": resourceArmStorageBlob(),
"azurerm_storage_container": resourceArmStorageContainer(),
"azurerm_storage_queue": resourceArmStorageQueue(),
Expand Down
177 changes: 177 additions & 0 deletions azurerm/resource_arm_storage_account_blob_settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package azurerm

import (
"fmt"
"log"

"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-04-01/storage"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

var storageAccountBlobSettingsResourceName = "azurerm_storage_account_blob_settings"

func resourceArmStorageAccountBlobSettings() *schema.Resource {
return &schema.Resource{
Create: resourceArmStorageAccountBlobSettingsCreateUpdate,
Read: resourceArmStorageAccountBlobSettingsRead,
Update: resourceArmStorageAccountBlobSettingsCreateUpdate,
Delete: resourceArmStorageAccountBlobSettingsDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"resource_group_name": azure.SchemaResourceGroupName(),

"storage_account_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"enable_soft_delete": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},

"soft_delete_retention_days": {
Type: schema.TypeInt,
Optional: true,
Default: 7,
ValidateFunc: validation.IntBetween(1, 365),
},
},
}
}

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

log.Printf("[INFO] preparing arguments for Azure ARM Storage Account Blob Settings creation.")

resourceGroupName := d.Get("resource_group_name").(string)
storageAccountName := d.Get("storage_account_name").(string)
enableSoftDelete := d.Get("enable_soft_delete").(bool)
softDeleteRetentionDays := int32(d.Get("soft_delete_retention_days").(int))

if requireResourcesToBeImported && d.IsNewResource() {
existing, err := client.GetServiceProperties(ctx, resourceGroupName, storageAccountName)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("error checking for presence of existing Storage Account Blob Settings (Storage Account %q / Resource Group %q): %s",
storageAccountName, resourceGroupName, err)
}
}

if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError(storageAccountBlobSettingsResourceName, *existing.ID)
}
}

properties := storage.BlobServicePropertiesProperties{
DeleteRetentionPolicy: &storage.DeleteRetentionPolicy{
Enabled: &enableSoftDelete,
Days: &softDeleteRetentionDays,
},
}

propertiesWrapper := storage.BlobServiceProperties{
BlobServicePropertiesProperties: &properties,
}

_, err := client.SetServiceProperties(ctx, resourceGroupName, storageAccountName, propertiesWrapper)

if err != nil {
return fmt.Errorf("error while updataing Storage Account Blob Settings (Storage Account %q / Resource Group %q): %s",
storageAccountName, resourceGroupName, err)
}

read, err := client.GetServiceProperties(ctx, resourceGroupName, storageAccountName)

if err != nil || read.ID == nil {
return fmt.Errorf("can't read ID of Storage Account Blob Settings (Storage Account %q / Resource Group %q): %s",
storageAccountName, resourceGroupName, err)
}

d.SetId(*read.ID)

return resourceArmStorageAccountBlobSettingsRead(d, meta)
}

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

log.Printf("[INFO] Reading Azure ARM Storage Account Blob Settings.")

id, err := parseAzureResourceID(d.Id())

if err != nil {
return err
}

resourceGroupName := id.ResourceGroup
storageAccountName := id.Path["storageAccounts"]

resp, err := client.GetServiceProperties(ctx, resourceGroupName, storageAccountName)

if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
d.SetId("")
return nil
}
return fmt.Errorf("error making Read request on Azure Storage Account %q: %+v", storageAccountName, err)
}

d.Set("resource_group_name", resourceGroupName)
d.Set("storage_account_name", storageAccountName)

if props := resp.BlobServicePropertiesProperties; props != nil {
if policy := props.DeleteRetentionPolicy; policy != nil {
if policy.Enabled != nil {
d.Set("enable_soft_delete", policy.Enabled)
}
if policy.Days != nil {
d.Set("soft_delete_retention_days", policy.Days)
}
}
}

return nil
}

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

id, err := parseAzureResourceID(d.Id())
if err != nil {
return err
}

resourceGroupName := id.ResourceGroup
storageAccountName := id.Path["storageAccounts"]
enableSoftDelete := false
propertiesWrapper := storage.BlobServiceProperties{
BlobServicePropertiesProperties: &storage.BlobServicePropertiesProperties{
DeleteRetentionPolicy: &storage.DeleteRetentionPolicy{
Enabled: &enableSoftDelete,
},
},
}

_, err = client.SetServiceProperties(ctx, resourceGroupName, storageAccountName, propertiesWrapper)

if err != nil {
return fmt.Errorf("error deleting Storage Account Blob Settings (Storage Account %q / Resource Group %q): %s",
storageAccountName, resourceGroupName, err)
}

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

import (
"fmt"
"testing"

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

func TestAccAzureRMStorageAccountBlobSettings_basic(t *testing.T) {
resourceName := "azurerm_storage_account_blob_settings.testsabs"
storageAccountResourceName := "azurerm_storage_account.testsa"
ri := tf.AccRandTimeInt()
rs := acctest.RandString(4)
location := testLocation()
createConfig := testAccAzureRMStorageAccountBlobSettings_basic(ri, rs, location)
updateConfig := testAccAzureRMStorageAccountBlobSettings_update(ri, rs, location)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMStorageAccountBlobSettingsDestroy,
Steps: []resource.TestStep{
{
Config: createConfig,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMStorageAccountExists(storageAccountResourceName),
resource.TestCheckResourceAttr(resourceName, "enable_soft_delete", "true"),
resource.TestCheckResourceAttr(resourceName, "soft_delete_retention_days", "123"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: updateConfig,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMStorageAccountExists(storageAccountResourceName),
resource.TestCheckResourceAttr(resourceName, "enable_soft_delete", "true"),
resource.TestCheckResourceAttr(resourceName, "soft_delete_retention_days", "99"),
),
},
},
})
}

func testAccAzureRMStorageAccountBlobSettings_basic(rInt int, rString string, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "testrg" {
name = "acctestAzureRMSABS-%d"
location = "%s"
}

resource "azurerm_storage_account" "testsa" {
name = "unlikely23exst2acct%s"
resource_group_name = "${azurerm_resource_group.testrg.name}"

location = "${azurerm_resource_group.testrg.location}"
account_tier = "Standard"
account_replication_type = "LRS"
}

resource "azurerm_storage_account_blob_settings" "testsabs" {
resource_group_name = "${azurerm_resource_group.testrg.name}"
storage_account_name = "${azurerm_storage_account.testsa.name}"
enable_soft_delete = true
soft_delete_retention_days = 123
}
`, rInt, location, rString)
}

func testAccAzureRMStorageAccountBlobSettings_update(rInt int, rString string, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "testrg" {
name = "acctestAzureRMSABS-%d"
location = "%s"
}

resource "azurerm_storage_account" "testsa" {
name = "unlikely23exst2acct%s"
resource_group_name = "${azurerm_resource_group.testrg.name}"

location = "${azurerm_resource_group.testrg.location}"
account_tier = "Standard"
account_replication_type = "LRS"
}

resource "azurerm_storage_account_blob_settings" "testsabs" {
resource_group_name = "${azurerm_resource_group.testrg.name}"
storage_account_name = "${azurerm_storage_account.testsa.name}"
enable_soft_delete = true
soft_delete_retention_days = 99
}
`, rInt, location, rString)
}

func testCheckAzureRMStorageAccountBlobSettingsDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*ArmClient).storageBlobServicesClient
ctx := testAccProvider.Meta().(*ArmClient).StopContext

for _, rs := range s.RootModule().Resources {
if rs.Type != "azurerm_storage_account_blob_settings" {
continue
}

storageAccountName := rs.Primary.Attributes["storage_account_name"]
resourceGroupName := rs.Primary.Attributes["resource_group_name"]

resp, err := client.GetServiceProperties(ctx, resourceGroupName, storageAccountName)
if err != nil {
if !utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Storage Account Blob Settings still exist:\n%#v", resp.BlobServicePropertiesProperties)
}
return nil
}
}

return nil
}
61 changes: 61 additions & 0 deletions website/docs/r/storage_account_blob_settings.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
layout: "azurerm"
page_title: "Azure Resource Manager: azurerm_storage_account_blob_settings"
sidebar_current: "docs-azurerm-resource-azurerm-storage-account-blob-settings"
description: |-
Manages Azure Storage Account Blob Properties.
---

# azurerm_storage_account_blob_settings

Manages Azure Storage Account Blob Properties.

## Example Usage

```hcl
resource "azurerm_resource_group" "testrg" {
name = "resourceGroupName"
location = "westus"
}

resource "azurerm_storage_account" "testsa" {
name = "storageaccountname"
resource_group_name = "${azurerm_resource_group.testrg.name}"
location = "westus"
account_tier = "Standard"
account_replication_type = "LRS"
}

resource "azurerm_storage_account_blob_settings" "testsabs" {
resource_group_name = "${azurerm_resource_group.testrg.name}"
storage_account_name = "${azurerm_storage_account.testsa.name}"
enable_soft_delete = true
soft_delete_retention_days = 123
}
```

## Argument Reference

The following arguments are supported:

* `resource_group_name` - (Required) The name of the resource group in which to create the storage account. Changing this forces a new resource to be created.

* `storage_account_name` - (Required) Specifies the name of the storage account the blob settings are applied to.

* `enable_soft_delete` - (Optional) Boolean flag which controls whether soft delete is enabled or not. Defaults to `false`.

* `soft_delete_retention_days` - (Optional) Specifies the number of days that the blob should be retained. The minimum specified value can be 1 an the maximum value can be 365. Defaults to `7`.

## Attributes Reference

The following attributes are exported in addition to the arguments listed above:

* `id` - The ID of the Storage Account Blob Settings.

## Import

Storage Accounts can be imported using the `resource id`, e.g.

```shell
terraform import azurerm_storage_account_blob_settings.storageAccBlobSettings /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresourcegroup/providers/Microsoft.Storage/storageAccounts/myaccount/blobServices/default
```