diff --git a/aws/resource_aws_glacier_vault.go b/aws/resource_aws_glacier_vault.go index 8e1845164be..20574497843 100644 --- a/aws/resource_aws_glacier_vault.go +++ b/aws/resource_aws_glacier_vault.go @@ -7,7 +7,6 @@ import ( "regexp" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/glacier" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" @@ -31,18 +30,11 @@ func resourceAwsGlacierVault() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - if !regexp.MustCompile(`^[.0-9A-Za-z-_]+$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "only alphanumeric characters, hyphens, underscores, and periods are allowed in %q", k)) - } - if len(value) > 255 { - errors = append(errors, fmt.Errorf( - "%q cannot be longer than 255 characters", k)) - } - return - }, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 255), + validation.StringMatch(regexp.MustCompile(`^[.0-9A-Za-z-_]+$`), + "only alphanumeric characters, hyphens, underscores, and periods are allowed"), + ), }, "location": { @@ -56,29 +48,34 @@ func resourceAwsGlacierVault() *schema.Resource { }, "access_policy": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringIsJSON, - StateFunc: func(v interface{}) string { - json, _ := structure.NormalizeJsonString(v) - return json - }, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: suppressEquivalentAwsPolicyDiffs, }, "notification": { Type: schema.TypeList, Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "events": { Type: schema.TypeSet, Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + "ArchiveRetrievalCompleted", + "InventoryRetrievalCompleted", + }, false), + }, + Set: schema.HashString, }, "sns_topic": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + ValidateFunc: validateArn, }, }, }, @@ -90,42 +87,59 @@ func resourceAwsGlacierVault() *schema.Resource { } func resourceAwsGlacierVaultCreate(d *schema.ResourceData, meta interface{}) error { - glacierconn := meta.(*AWSClient).glacierconn + conn := meta.(*AWSClient).glacierconn input := &glacier.CreateVaultInput{ VaultName: aws.String(d.Get("name").(string)), } - out, err := glacierconn.CreateVault(input) + _, err := conn.CreateVault(input) if err != nil { - return fmt.Errorf("Error creating Glacier Vault: %s", err) + return fmt.Errorf("Error creating Glacier Vault: %w", err) } d.SetId(d.Get("name").(string)) - d.Set("location", out.Location) - return resourceAwsGlacierVaultUpdate(d, meta) + if v, ok := d.GetOk("tags"); ok { + if err := keyvaluetags.GlacierUpdateTags(conn, d.Id(), nil, v.(map[string]interface{})); err != nil { + return fmt.Errorf("error updating Glacier Vault (%s) tags: %w", d.Id(), err) + } + } + + if _, ok := d.GetOk("access_policy"); ok { + if err := resourceAwsGlacierVaultPolicyUpdate(conn, d); err != nil { + return fmt.Errorf("error updating Glacier Vault (%s) access policy: %w", d.Id(), err) + } + } + + if _, ok := d.GetOk("notification"); ok { + if err := resourceAwsGlacierVaultNotificationUpdate(conn, d); err != nil { + return fmt.Errorf("error updating Glacier Vault (%s) notification: %w", d.Id(), err) + } + } + + return resourceAwsGlacierVaultRead(d, meta) } func resourceAwsGlacierVaultUpdate(d *schema.ResourceData, meta interface{}) error { - glacierconn := meta.(*AWSClient).glacierconn + conn := meta.(*AWSClient).glacierconn if d.HasChange("tags") { o, n := d.GetChange("tags") - if err := keyvaluetags.GlacierUpdateTags(glacierconn, d.Id(), o, n); err != nil { + if err := keyvaluetags.GlacierUpdateTags(conn, d.Id(), o, n); err != nil { return fmt.Errorf("error updating Glacier Vault (%s) tags: %s", d.Id(), err) } } if d.HasChange("access_policy") { - if err := resourceAwsGlacierVaultPolicyUpdate(glacierconn, d); err != nil { - return err + if err := resourceAwsGlacierVaultPolicyUpdate(conn, d); err != nil { + return fmt.Errorf("error updating Glacier Vault (%s) access policy: %w", d.Id(), err) } } if d.HasChange("notification") { - if err := resourceAwsGlacierVaultNotificationUpdate(glacierconn, d); err != nil { - return err + if err := resourceAwsGlacierVaultNotificationUpdate(conn, d); err != nil { + return fmt.Errorf("error updating Glacier Vault (%s) notification: %w", d.Id(), err) } } @@ -133,16 +147,21 @@ func resourceAwsGlacierVaultUpdate(d *schema.ResourceData, meta interface{}) err } func resourceAwsGlacierVaultRead(d *schema.ResourceData, meta interface{}) error { - glacierconn := meta.(*AWSClient).glacierconn + conn := meta.(*AWSClient).glacierconn ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig input := &glacier.DescribeVaultInput{ VaultName: aws.String(d.Id()), } - out, err := glacierconn.DescribeVault(input) + out, err := conn.DescribeVault(input) + if isAWSErr(err, glacier.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] Glaier Vault (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } if err != nil { - return fmt.Errorf("Error reading Glacier Vault: %s", err.Error()) + return fmt.Errorf("Error reading Glacier Vault: %w", err) } awsClient := meta.(*AWSClient) @@ -155,91 +174,83 @@ func resourceAwsGlacierVaultRead(d *schema.ResourceData, meta interface{}) error } d.Set("location", location) - tags, err := keyvaluetags.GlacierListTags(glacierconn, d.Id()) + tags, err := keyvaluetags.GlacierListTags(conn, d.Id()) if err != nil { - return fmt.Errorf("error listing tags for Glacier Vault (%s): %s", d.Id(), err) + return fmt.Errorf("error listing tags for Glacier Vault (%s): %w", d.Id(), err) } if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + return fmt.Errorf("error setting tags: %w", err) } log.Printf("[DEBUG] Getting the access_policy for Vault %s", d.Id()) - pol, err := glacierconn.GetVaultAccessPolicy(&glacier.GetVaultAccessPolicyInput{ + pol, err := conn.GetVaultAccessPolicy(&glacier.GetVaultAccessPolicyInput{ VaultName: aws.String(d.Id()), }) - if awserr, ok := err.(awserr.Error); ok && awserr.Code() == "ResourceNotFoundException" { + if isAWSErr(err, glacier.ErrCodeResourceNotFoundException, "") { d.Set("access_policy", "") - } else if pol != nil { - policy, err := structure.NormalizeJsonString(*pol.Policy.Policy) + } else if err != nil { + return fmt.Errorf("error getting access policy for Glacier Vault (%s): %w", d.Id(), err) + } else if pol != nil && pol.Policy != nil { + policy, err := structure.NormalizeJsonString(aws.StringValue(pol.Policy.Policy)) if err != nil { - return fmt.Errorf("access policy contains an invalid JSON: %s", err) + return fmt.Errorf("access policy contains an invalid JSON: %w", err) } d.Set("access_policy", policy) - } else { - return err } - notifications, err := getGlacierVaultNotification(glacierconn, d.Id()) - if awserr, ok := err.(awserr.Error); ok && awserr.Code() == "ResourceNotFoundException" { - d.Set("notification", "") + notifications, err := getGlacierVaultNotification(conn, d.Id()) + if isAWSErr(err, glacier.ErrCodeResourceNotFoundException, "") { + d.Set("notification", []map[string]interface{}{}) } else if pol != nil { d.Set("notification", notifications) } else { - return err + return fmt.Errorf("error setting notification: %w", err) } return nil } func resourceAwsGlacierVaultDelete(d *schema.ResourceData, meta interface{}) error { - glacierconn := meta.(*AWSClient).glacierconn + conn := meta.(*AWSClient).glacierconn log.Printf("[DEBUG] Glacier Delete Vault: %s", d.Id()) - _, err := glacierconn.DeleteVault(&glacier.DeleteVaultInput{ + _, err := conn.DeleteVault(&glacier.DeleteVaultInput{ VaultName: aws.String(d.Id()), }) if err != nil { - return fmt.Errorf("Error deleting Glacier Vault: %s", err.Error()) + return fmt.Errorf("Error deleting Glacier Vault: %w", err) } return nil } -func resourceAwsGlacierVaultNotificationUpdate(glacierconn *glacier.Glacier, d *schema.ResourceData) error { +func resourceAwsGlacierVaultNotificationUpdate(conn *glacier.Glacier, d *schema.ResourceData) error { if v, ok := d.GetOk("notification"); ok { settings := v.([]interface{}) - if len(settings) > 1 { - return fmt.Errorf("Only a single Notification Block is allowed for Glacier Vault") - } else if len(settings) == 1 { - s := settings[0].(map[string]interface{}) - var events []*string - for _, id := range s["events"].(*schema.Set).List() { - events = append(events, aws.String(id.(string))) - } - - _, err := glacierconn.SetVaultNotifications(&glacier.SetVaultNotificationsInput{ - VaultName: aws.String(d.Id()), - VaultNotificationConfig: &glacier.VaultNotificationConfig{ - SNSTopic: aws.String(s["sns_topic"].(string)), - Events: events, - }, - }) + s := settings[0].(map[string]interface{}) + + _, err := conn.SetVaultNotifications(&glacier.SetVaultNotificationsInput{ + VaultName: aws.String(d.Id()), + VaultNotificationConfig: &glacier.VaultNotificationConfig{ + SNSTopic: aws.String(s["sns_topic"].(string)), + Events: expandStringSet(s["events"].(*schema.Set)), + }, + }) - if err != nil { - return fmt.Errorf("Error Updating Glacier Vault Notifications: %s", err.Error()) - } + if err != nil { + return fmt.Errorf("Error Updating Glacier Vault Notifications: %w", err) } } else { - _, err := glacierconn.DeleteVaultNotifications(&glacier.DeleteVaultNotificationsInput{ + _, err := conn.DeleteVaultNotifications(&glacier.DeleteVaultNotificationsInput{ VaultName: aws.String(d.Id()), }) if err != nil { - return fmt.Errorf("Error Removing Glacier Vault Notifications: %s", err.Error()) + return fmt.Errorf("Error Removing Glacier Vault Notifications: %w", err) } } @@ -247,7 +258,7 @@ func resourceAwsGlacierVaultNotificationUpdate(glacierconn *glacier.Glacier, d * return nil } -func resourceAwsGlacierVaultPolicyUpdate(glacierconn *glacier.Glacier, d *schema.ResourceData) error { +func resourceAwsGlacierVaultPolicyUpdate(conn *glacier.Glacier, d *schema.ResourceData) error { vaultName := d.Id() policyContents := d.Get("access_policy").(string) @@ -258,22 +269,22 @@ func resourceAwsGlacierVaultPolicyUpdate(glacierconn *glacier.Glacier, d *schema if policyContents != "" { log.Printf("[DEBUG] Glacier Vault: %s, put policy", vaultName) - _, err := glacierconn.SetVaultAccessPolicy(&glacier.SetVaultAccessPolicyInput{ + _, err := conn.SetVaultAccessPolicy(&glacier.SetVaultAccessPolicyInput{ VaultName: aws.String(d.Id()), Policy: policy, }) if err != nil { - return fmt.Errorf("Error putting Glacier Vault policy: %s", err.Error()) + return fmt.Errorf("Error putting Glacier Vault policy: %w", err) } } else { log.Printf("[DEBUG] Glacier Vault: %s, delete policy: %s", vaultName, policy) - _, err := glacierconn.DeleteVaultAccessPolicy(&glacier.DeleteVaultAccessPolicyInput{ + _, err := conn.DeleteVaultAccessPolicy(&glacier.DeleteVaultAccessPolicyInput{ VaultName: aws.String(d.Id()), }) if err != nil { - return fmt.Errorf("Error deleting Glacier Vault policy: %s", err.Error()) + return fmt.Errorf("Error deleting Glacier Vault policy: %w", err) } } @@ -287,14 +298,14 @@ func buildGlacierVaultLocation(accountId, vaultName string) (string, error) { return fmt.Sprintf("/" + accountId + "/vaults/" + vaultName), nil } -func getGlacierVaultNotification(glacierconn *glacier.Glacier, vaultName string) ([]map[string]interface{}, error) { +func getGlacierVaultNotification(conn *glacier.Glacier, vaultName string) ([]map[string]interface{}, error) { request := &glacier.GetVaultNotificationsInput{ VaultName: aws.String(vaultName), } - response, err := glacierconn.GetVaultNotifications(request) + response, err := conn.GetVaultNotifications(request) if err != nil { - return nil, fmt.Errorf("Error reading Glacier Vault Notifications: %s", err.Error()) + return nil, fmt.Errorf("Error reading Glacier Vault Notifications: %w", err) } notifications := make(map[string]interface{}) diff --git a/aws/resource_aws_glacier_vault_test.go b/aws/resource_aws_glacier_vault_test.go index 1ce209de0a1..16261e9e365 100644 --- a/aws/resource_aws_glacier_vault_test.go +++ b/aws/resource_aws_glacier_vault_test.go @@ -3,10 +3,10 @@ package aws import ( "fmt" "log" + "regexp" "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/glacier" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" @@ -75,7 +75,8 @@ func testSweepGlacierVaults(region string) error { } func TestAccAWSGlacierVault_basic(t *testing.T) { - rInt := acctest.RandInt() + var vault glacier.DescribeVaultOutput + rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_glacier_vault.test" resource.ParallelTest(t, resource.TestCase{ @@ -84,9 +85,14 @@ func TestAccAWSGlacierVault_basic(t *testing.T) { CheckDestroy: testAccCheckGlacierVaultDestroy, Steps: []resource.TestStep{ { - Config: testAccGlacierVault_basic(rInt), + Config: testAccGlacierVaultBasicConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckGlacierVaultExists(resourceName), + testAccCheckGlacierVaultExists(resourceName, &vault), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "name", rName), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "glacier", regexp.MustCompile(`vaults/.+`)), + resource.TestCheckResourceAttr(resourceName, "notification.#", "0"), + resource.TestCheckResourceAttr(resourceName, "access_policy", ""), ), }, { @@ -98,9 +104,11 @@ func TestAccAWSGlacierVault_basic(t *testing.T) { }) } -func TestAccAWSGlacierVault_full(t *testing.T) { - rInt := acctest.RandInt() +func TestAccAWSGlacierVault_notification(t *testing.T) { + var vault glacier.DescribeVaultOutput + rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_glacier_vault.test" + snsResourceName := "aws_sns_topic.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -108,9 +116,12 @@ func TestAccAWSGlacierVault_full(t *testing.T) { CheckDestroy: testAccCheckGlacierVaultDestroy, Steps: []resource.TestStep{ { - Config: testAccGlacierVault_full(rInt), + Config: testAccGlacierVaultNotificationConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckGlacierVaultExists(resourceName), + testAccCheckGlacierVaultExists(resourceName, &vault), + resource.TestCheckResourceAttr(resourceName, "notification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "notification.0.events.#", "2"), + resource.TestCheckResourceAttrPair(resourceName, "notification.0.sns_topic", snsResourceName, "arn"), ), }, { @@ -118,12 +129,30 @@ func TestAccAWSGlacierVault_full(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + { + Config: testAccGlacierVaultBasicConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlacierVaultExists(resourceName, &vault), + resource.TestCheckResourceAttr(resourceName, "notification.#", "0"), + testAccCheckVaultNotificationsMissing(resourceName), + ), + }, + { + Config: testAccGlacierVaultNotificationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlacierVaultExists(resourceName, &vault), + resource.TestCheckResourceAttr(resourceName, "notification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "notification.0.events.#", "2"), + resource.TestCheckResourceAttrPair(resourceName, "notification.0.sns_topic", snsResourceName, "arn"), + ), + }, }, }) } -func TestAccAWSGlacierVault_RemoveNotifications(t *testing.T) { - rInt := acctest.RandInt() +func TestAccAWSGlacierVault_policy(t *testing.T) { + var vault glacier.DescribeVaultOutput + rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_glacier_vault.test" resource.ParallelTest(t, resource.TestCase{ @@ -132,9 +161,12 @@ func TestAccAWSGlacierVault_RemoveNotifications(t *testing.T) { CheckDestroy: testAccCheckGlacierVaultDestroy, Steps: []resource.TestStep{ { - Config: testAccGlacierVault_full(rInt), + Config: testAccGlacierVaultPolicyConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckGlacierVaultExists(resourceName), + testAccCheckGlacierVaultExists(resourceName, &vault), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestMatchResourceAttr(resourceName, "access_policy", + regexp.MustCompile(`"Sid":"cross-account-upload".+`)), ), }, { @@ -143,17 +175,92 @@ func TestAccAWSGlacierVault_RemoveNotifications(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccGlacierVault_withoutNotification(rInt), + Config: testAccGlacierVaultPolicyConfigUpdated(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckGlacierVaultExists(resourceName), - testAccCheckVaultNotificationsMissing(resourceName), + testAccCheckGlacierVaultExists(resourceName, &vault), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestMatchResourceAttr(resourceName, "access_policy", + regexp.MustCompile(`"Sid":"cross-account-upload1".+`)), + ), + }, + { + Config: testAccGlacierVaultBasicConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlacierVaultExists(resourceName, &vault), + resource.TestCheckResourceAttr(resourceName, "access_policy", ""), + ), + }, + }, + }) +} + +func TestAccAWSGlacierVault_tags(t *testing.T) { + var vault glacier.DescribeVaultOutput + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_glacier_vault.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGlacierVaultDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGlacierVaultConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlacierVaultExists(resourceName, &vault), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGlacierVaultConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlacierVaultExists(resourceName, &vault), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccGlacierVaultConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlacierVaultExists(resourceName, &vault), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), }, }, }) } -func testAccCheckGlacierVaultExists(name string) resource.TestCheckFunc { +func TestAccAWSGlacierVault_disappears(t *testing.T) { + var vault glacier.DescribeVaultOutput + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_glacier_vault.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGlacierVaultDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGlacierVaultBasicConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlacierVaultExists(resourceName, &vault), + testAccCheckResourceDisappears(testAccProvider, resourceAwsGlacierVault(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckGlacierVaultExists(name string, vault *glacier.DescribeVaultOutput) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] if !ok { @@ -164,8 +271,8 @@ func testAccCheckGlacierVaultExists(name string) resource.TestCheckFunc { return fmt.Errorf("No ID is set") } - glacierconn := testAccProvider.Meta().(*AWSClient).glacierconn - out, err := glacierconn.DescribeVault(&glacier.DescribeVaultInput{ + conn := testAccProvider.Meta().(*AWSClient).glacierconn + out, err := conn.DescribeVault(&glacier.DescribeVaultInput{ VaultName: aws.String(rs.Primary.ID), }) @@ -182,6 +289,8 @@ func testAccCheckGlacierVaultExists(name string) resource.TestCheckFunc { *out.VaultName, rs.Primary.ID) } + *vault = *out + return nil } } @@ -197,13 +306,13 @@ func testAccCheckVaultNotificationsMissing(name string) resource.TestCheckFunc { return fmt.Errorf("No ID is set") } - glacierconn := testAccProvider.Meta().(*AWSClient).glacierconn - out, err := glacierconn.GetVaultNotifications(&glacier.GetVaultNotificationsInput{ + conn := testAccProvider.Meta().(*AWSClient).glacierconn + out, err := conn.GetVaultNotifications(&glacier.GetVaultNotificationsInput{ VaultName: aws.String(rs.Primary.ID), }) - if awserr, ok := err.(awserr.Error); ok && awserr.Code() != "ResourceNotFoundException" { - return fmt.Errorf("Expected ResourceNotFoundException for Vault %s Notification Block but got %s", rs.Primary.ID, awserr.Code()) + if !isAWSErr(err, glacier.ErrCodeResourceNotFoundException, "") { + return fmt.Errorf("Expected ResourceNotFoundException for Vault %s Notification Block but got %s", rs.Primary.ID, err) } if out.VaultNotificationConfig != nil { @@ -228,7 +337,7 @@ func testAccCheckGlacierVaultDestroy(s *terraform.State) error { } if _, err := conn.DescribeVault(input); err != nil { // Verify the error is what we want - if ae, ok := err.(awserr.Error); ok && ae.Code() == "ResourceNotFoundException" { + if isAWSErr(err, glacier.ErrCodeResourceNotFoundException, "") { continue } @@ -239,47 +348,123 @@ func testAccCheckGlacierVaultDestroy(s *terraform.State) error { return nil } -func testAccGlacierVault_basic(rInt int) string { +func testAccGlacierVaultBasicConfig(rName string) string { return fmt.Sprintf(` resource "aws_glacier_vault" "test" { - name = "my_test_vault_%d" + name = %[1]q } -`, rInt) +`, rName) } -func testAccGlacierVault_full(rInt int) string { +func testAccGlacierVaultNotificationConfig(rName string) string { return fmt.Sprintf(` -resource "aws_sns_topic" "aws_sns_topic" { - name = "glacier-sns-topic-%d" +resource "aws_sns_topic" "test" { + name = %[1]q } resource "aws_glacier_vault" "test" { - name = "my_test_vault_%d" + name = %[1]q notification { - sns_topic = aws_sns_topic.aws_sns_topic.arn + sns_topic = aws_sns_topic.test.arn events = ["ArchiveRetrievalCompleted", "InventoryRetrievalCompleted"] } +} +`, rName) +} - tags = { - Test = "Test1" - } +func testAccGlacierVaultPolicyConfig(rName string) string { + return fmt.Sprintf(` +data "aws_partition" "current" {} + +data "aws_region" "current" {} + +data "aws_caller_identity" "current" {} + +resource "aws_glacier_vault" "test" { + name = %[1]q + + access_policy = <