Skip to content

Commit

Permalink
resource/aws_ebs_snapshot: Support tagging-on-create and in-place `ta…
Browse files Browse the repository at this point in the history
…gs` updates (#10935)

Output from acceptance testing in AWS Commercial:

```
--- PASS: TestAccAWSEBSSnapshot_tags (45.18s)
--- PASS: TestAccAWSEBSSnapshot_withDescription (50.53s)
--- PASS: TestAccAWSEBSSnapshot_withKms (54.61s)
--- PASS: TestAccAWSEBSSnapshot_basic (56.06s)
```

Output from acceptance testing in AWS GovCloud (US) (unrelated failure due to hardcoded AWS Commerical ARN):

```
--- PASS: TestAccAWSEBSSnapshot_withDescription (30.50s)
--- PASS: TestAccAWSEBSSnapshot_tags (33.01s)
--- PASS: TestAccAWSEBSSnapshot_basic (47.10s)
--- FAIL: TestAccAWSEBSSnapshot_withKms (48.82s)
```
  • Loading branch information
DrFaust92 authored and bflad committed Nov 21, 2019
1 parent f8370f1 commit ee5a354
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 21 deletions.
33 changes: 20 additions & 13 deletions aws/resource_aws_ebs_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import (
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func resourceAwsEbsSnapshot() *schema.Resource {
return &schema.Resource{
Create: resourceAwsEbsSnapshotCreate,
Read: resourceAwsEbsSnapshotRead,
Update: resourceAwsEbsSnapshotUpdate,
Delete: resourceAwsEbsSnapshotDelete,

Timeouts: &schema.ResourceTimeout{
Expand Down Expand Up @@ -57,12 +59,7 @@ func resourceAwsEbsSnapshot() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},

"tags": {
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
},
"tags": tagsSchema(),
},
}
}
Expand All @@ -71,7 +68,8 @@ func resourceAwsEbsSnapshotCreate(d *schema.ResourceData, meta interface{}) erro
conn := meta.(*AWSClient).ec2conn

request := &ec2.CreateSnapshotInput{
VolumeId: aws.String(d.Get("volume_id").(string)),
VolumeId: aws.String(d.Get("volume_id").(string)),
TagSpecifications: ec2TagSpecificationsFromMap(d.Get("tags").(map[string]interface{}), ec2.ResourceTypeSnapshot),
}
if v, ok := d.GetOk("description"); ok {
request.Description = aws.String(v.(string))
Expand Down Expand Up @@ -106,10 +104,6 @@ func resourceAwsEbsSnapshotCreate(d *schema.ResourceData, meta interface{}) erro
return err
}

if err := setTags(conn, d); err != nil {
log.Printf("[WARN] error setting tags: %s", err)
}

return resourceAwsEbsSnapshotRead(d, meta)
}

Expand Down Expand Up @@ -145,13 +139,26 @@ func resourceAwsEbsSnapshotRead(d *schema.ResourceData, meta interface{}) error
d.Set("kms_key_id", snapshot.KmsKeyId)
d.Set("volume_size", snapshot.VolumeSize)

if err := d.Set("tags", tagsToMap(snapshot.Tags)); err != nil {
log.Printf("[WARN] error saving tags to state: %s", err)
if err := d.Set("tags", keyvaluetags.Ec2KeyValueTags(snapshot.Tags).IgnoreAws().Map()); err != nil {
return fmt.Errorf("error setting tags: %s", err)
}

return nil
}

func resourceAwsEbsSnapshotUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn

if d.HasChange("tags") {
o, n := d.GetChange("tags")
if err := keyvaluetags.Ec2UpdateTags(conn, d.Id(), o, n); err != nil {
return fmt.Errorf("error updating tags: %s", err)
}
}

return resourceAwsEbsSnapshotRead(d, meta)
}

func resourceAwsEbsSnapshotDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn
input := &ec2.DeleteSnapshotInput{
Expand Down
111 changes: 103 additions & 8 deletions aws/resource_aws_ebs_snapshot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
func TestAccAWSEBSSnapshot_basic(t *testing.T) {
var v ec2.Snapshot
rName := fmt.Sprintf("tf-acc-ebs-snapshot-basic-%s", acctest.RandString(7))
resourceName := "aws_ebs_snapshot.test"

deleteSnapshot := func() {
conn := testAccProvider.Meta().(*AWSClient).ec2conn
Expand Down Expand Up @@ -47,16 +48,57 @@ func TestAccAWSEBSSnapshot_basic(t *testing.T) {
{
Config: testAccAwsEbsSnapshotConfigBasic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckSnapshotExists("aws_ebs_snapshot.test", &v),
testAccCheckTags(&v.Tags, "Name", rName),
testAccCheckSnapshotExists(resourceName, &v),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.Name", rName),
),
},
{
PreConfig: deleteSnapshot,
Config: testAccAwsEbsSnapshotConfigBasic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckSnapshotExists("aws_ebs_snapshot.test", &v),
testAccCheckTags(&v.Tags, "Name", rName),
testAccCheckSnapshotExists(resourceName, &v),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.Name", rName),
),
},
},
})
}

func TestAccAWSEBSSnapshot_tags(t *testing.T) {
var v ec2.Snapshot
rName := fmt.Sprintf("tf-acc-ebs-snapshot-desc-%s", acctest.RandString(7))
resourceName := "aws_ebs_snapshot.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSEbsSnapshotDestroy,
Steps: []resource.TestStep{
{
Config: testAccAwsEbsSnapshotConfigBasicTags1(rName, "key1", "value1"),
Check: resource.ComposeTestCheckFunc(
testAccCheckSnapshotExists(resourceName, &v),
resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"),
),
},
{
Config: testAccAwsEbsSnapshotConfigBasicTags2(rName, "key1", "value1updated", "key2", "value2"),
Check: resource.ComposeTestCheckFunc(
testAccCheckSnapshotExists(resourceName, &v),
resource.TestCheckResourceAttr(resourceName, "tags.%", "3"),
resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"),
resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"),
),
},
{
Config: testAccAwsEbsSnapshotConfigBasicTags1(rName, "key2", "value2"),
Check: resource.ComposeTestCheckFunc(
testAccCheckSnapshotExists(resourceName, &v),
resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"),
),
},
},
Expand All @@ -66,6 +108,7 @@ func TestAccAWSEBSSnapshot_basic(t *testing.T) {
func TestAccAWSEBSSnapshot_withDescription(t *testing.T) {
var v ec2.Snapshot
rName := fmt.Sprintf("tf-acc-ebs-snapshot-desc-%s", acctest.RandString(7))
resourceName := "aws_ebs_snapshot.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand All @@ -75,8 +118,8 @@ func TestAccAWSEBSSnapshot_withDescription(t *testing.T) {
{
Config: testAccAwsEbsSnapshotConfigWithDescription(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckSnapshotExists("aws_ebs_snapshot.test", &v),
resource.TestCheckResourceAttr("aws_ebs_snapshot.test", "description", rName),
testAccCheckSnapshotExists(resourceName, &v),
resource.TestCheckResourceAttr(resourceName, "description", rName),
),
},
},
Expand All @@ -86,6 +129,7 @@ func TestAccAWSEBSSnapshot_withDescription(t *testing.T) {
func TestAccAWSEBSSnapshot_withKms(t *testing.T) {
var v ec2.Snapshot
rName := fmt.Sprintf("tf-acc-ebs-snapshot-kms-%s", acctest.RandString(7))
resourceName := "aws_ebs_snapshot.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand All @@ -95,8 +139,8 @@ func TestAccAWSEBSSnapshot_withKms(t *testing.T) {
{
Config: testAccAwsEbsSnapshotConfigWithKms(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckSnapshotExists("aws_ebs_snapshot.test", &v),
resource.TestMatchResourceAttr("aws_ebs_snapshot.test", "kms_key_id",
testAccCheckSnapshotExists(resourceName, &v),
resource.TestMatchResourceAttr(resourceName, "kms_key_id",
regexp.MustCompile(`^arn:aws:kms:[a-z]{2}-[a-z]+-\d{1}:[0-9]{12}:key/[a-z0-9-]{36}$`)),
),
},
Expand Down Expand Up @@ -182,6 +226,57 @@ resource "aws_ebs_snapshot" "test" {
`, rName)
}

func testAccAwsEbsSnapshotConfigBasicTags1(rName, tagKey1, tagValue1 string) string {
return fmt.Sprintf(`
data "aws_region" "current" {}
resource "aws_ebs_volume" "test" {
availability_zone = "${data.aws_region.current.name}a"
size = 1
}
resource "aws_ebs_snapshot" "test" {
volume_id = "${aws_ebs_volume.test.id}"
tags = {
Name = "%s"
"%s" = "%s"
}
timeouts {
create = "10m"
delete = "10m"
}
}
`, rName, tagKey1, tagValue1)
}

func testAccAwsEbsSnapshotConfigBasicTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string {
return fmt.Sprintf(`
data "aws_region" "current" {}
resource "aws_ebs_volume" "test" {
availability_zone = "${data.aws_region.current.name}a"
size = 1
}
resource "aws_ebs_snapshot" "test" {
volume_id = "${aws_ebs_volume.test.id}"
tags = {
Name = "%s"
"%s" = "%s"
"%s" = "%s"
}
timeouts {
create = "10m"
delete = "10m"
}
}
`, rName, tagKey1, tagValue1, tagKey2, tagValue2)
}

func testAccAwsEbsSnapshotConfigWithDescription(rName string) string {
return fmt.Sprintf(`
data "aws_region" "current" {}
Expand Down

0 comments on commit ee5a354

Please sign in to comment.