From 7a67215a2098cdd1f771aa95d8bab98acb442edc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 22 Jan 2021 09:33:23 -0500 Subject: [PATCH 1/4] resource/aws_ebs_volume: Allow both 'snapshot_id' and 'size'. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSEBSVolume_snapshotID' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSEBSVolume_snapshotID -timeout 120m === RUN TestAccAWSEBSVolume_snapshotID === PAUSE TestAccAWSEBSVolume_snapshotID === RUN TestAccAWSEBSVolume_snapshotIDAndSize === PAUSE TestAccAWSEBSVolume_snapshotIDAndSize === CONT TestAccAWSEBSVolume_snapshotID === CONT TestAccAWSEBSVolume_snapshotIDAndSize --- PASS: TestAccAWSEBSVolume_snapshotIDAndSize (44.60s) --- PASS: TestAccAWSEBSVolume_snapshotID (46.74s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 46.829s --- aws/resource_aws_ebs_volume.go | 16 ++-- aws/resource_aws_ebs_volume_test.go | 143 ++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 9 deletions(-) diff --git a/aws/resource_aws_ebs_volume.go b/aws/resource_aws_ebs_volume.go index 47c6ae8122f..2f7d5c460b3 100644 --- a/aws/resource_aws_ebs_volume.go +++ b/aws/resource_aws_ebs_volume.go @@ -62,17 +62,15 @@ func resourceAwsEbsVolume() *schema.Resource { ForceNew: true, }, "size": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - ExactlyOneOf: []string{"size", "snapshot_id"}, + Type: schema.TypeInt, + Optional: true, + Computed: true, }, "snapshot_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ExactlyOneOf: []string{"size", "snapshot_id"}, + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, }, "outpost_arn": { Type: schema.TypeString, diff --git a/aws/resource_aws_ebs_volume_test.go b/aws/resource_aws_ebs_volume_test.go index 8550bbebe5e..2d5f2919518 100644 --- a/aws/resource_aws_ebs_volume_test.go +++ b/aws/resource_aws_ebs_volume_test.go @@ -595,6 +595,84 @@ func TestAccAWSEBSVolume_gp3_throughput(t *testing.T) { }) } +func TestAccAWSEBSVolume_snapshotID(t *testing.T) { + var v ec2.Volume + resourceName := "aws_ebs_volume.test" + snapshotResourceName := "aws_ebs_snapshot.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: resourceName, + Providers: testAccProviders, + CheckDestroy: testAccCheckVolumeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsEbsVolumeConfigSnapshotId(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckVolumeExists(resourceName, &v), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "ec2", regexp.MustCompile(`volume/vol-.+`)), + resource.TestCheckResourceAttr(resourceName, "encrypted", "false"), + resource.TestCheckResourceAttr(resourceName, "iops", "100"), + resource.TestCheckResourceAttr(resourceName, "kms_key_id", ""), + resource.TestCheckResourceAttr(resourceName, "multi_attach_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "outpost_arn", ""), + resource.TestCheckResourceAttr(resourceName, "size", "1"), + resource.TestCheckResourceAttrPair(resourceName, "snapshot_id", snapshotResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + resource.TestCheckResourceAttr(resourceName, "throughput", "0"), + resource.TestCheckResourceAttr(resourceName, "type", "gp2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSEBSVolume_snapshotIDAndSize(t *testing.T) { + var v ec2.Volume + resourceName := "aws_ebs_volume.test" + snapshotResourceName := "aws_ebs_snapshot.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: resourceName, + Providers: testAccProviders, + CheckDestroy: testAccCheckVolumeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsEbsVolumeConfigSnapshotIdAndSize(rName, 20), + Check: resource.ComposeTestCheckFunc( + testAccCheckVolumeExists(resourceName, &v), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "ec2", regexp.MustCompile(`volume/vol-.+`)), + resource.TestCheckResourceAttr(resourceName, "encrypted", "false"), + resource.TestCheckResourceAttr(resourceName, "iops", "100"), + resource.TestCheckResourceAttr(resourceName, "kms_key_id", ""), + resource.TestCheckResourceAttr(resourceName, "multi_attach_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "outpost_arn", ""), + resource.TestCheckResourceAttr(resourceName, "size", "20"), + resource.TestCheckResourceAttrPair(resourceName, "snapshot_id", snapshotResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + resource.TestCheckResourceAttr(resourceName, "throughput", "0"), + resource.TestCheckResourceAttr(resourceName, "type", "gp2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAWSEBSVolume_disappears(t *testing.T) { var v ec2.Volume resourceName := "aws_ebs_volume.test" @@ -1166,3 +1244,68 @@ resource "aws_ebs_volume" "test" { } `, rName, iops)) } + +func testAccAwsEbsVolumeConfigSnapshotId(rName string) string { + return composeConfig( + testAccAvailableAZsNoOptInConfig(), + fmt.Sprintf(` +resource "aws_ebs_volume" "source" { + availability_zone = data.aws_availability_zones.available.names[0] + size = 1 + + tags = { + Name = %[1]q + } +} + +resource "aws_ebs_snapshot" "test" { + volume_id = aws_ebs_volume.source.id + + tags = { + Name = %[1]q + } +} + +resource "aws_ebs_volume" "test" { + availability_zone = data.aws_availability_zones.available.names[0] + snapshot_id = aws_ebs_snapshot.test.id + + tags = { + Name = %[1]q + } +} +`, rName)) +} + +func testAccAwsEbsVolumeConfigSnapshotIdAndSize(rName string, size int) string { + return composeConfig( + testAccAvailableAZsNoOptInConfig(), + fmt.Sprintf(` +resource "aws_ebs_volume" "source" { + availability_zone = data.aws_availability_zones.available.names[0] + size = 10 + + tags = { + Name = %[1]q + } +} + +resource "aws_ebs_snapshot" "test" { + volume_id = aws_ebs_volume.source.id + + tags = { + Name = %[1]q + } +} + +resource "aws_ebs_volume" "test" { + availability_zone = data.aws_availability_zones.available.names[0] + snapshot_id = aws_ebs_snapshot.test.id + size = %[2]d + + tags = { + Name = %[1]q + } +} +`, rName, size)) +} From 5edf9b011ea9a8883f42baf3096ae3c53eca1053 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 22 Jan 2021 09:11:37 -0500 Subject: [PATCH 2/4] Fix formatting error in 'tools/main.go' --- tools/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/main.go b/tools/main.go index 1e8cedff106..f16d5ded289 100644 --- a/tools/main.go +++ b/tools/main.go @@ -6,7 +6,7 @@ import ( _ "github.com/bflad/tfproviderdocs" _ "github.com/client9/misspell/cmd/misspell" _ "github.com/golangci/golangci-lint/cmd/golangci-lint" + _ "github.com/hashicorp/go-changelog/cmd/changelog-build" _ "github.com/katbyte/terrafmt" _ "github.com/terraform-linters/tflint" - _ "github.com/hashicorp/go-changelog/cmd/changelog-build" ) From 9351cb859ff67d7de75a75779c0f909ca4d777fb Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 22 Jan 2021 09:44:12 -0500 Subject: [PATCH 3/4] Add CHANGELOG entry. --- .changelog/17243.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/17243.txt diff --git a/.changelog/17243.txt b/.changelog/17243.txt new file mode 100644 index 00000000000..0d66d523ba5 --- /dev/null +++ b/.changelog/17243.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_ebs_volume: Allow both `size` and `snapshot_id` attributes to be specified +``` From f3fbad95ef9ac528159b70a1529df5afe122012f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 22 Jan 2021 09:57:57 -0500 Subject: [PATCH 4/4] resource/aws_ebs_volume: Ensure at least one of 'snapshot_id' or 'size'. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSEBSVolume_' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSEBSVolume_ -timeout 120m === RUN TestAccAWSEBSVolume_basic === PAUSE TestAccAWSEBSVolume_basic === RUN TestAccAWSEBSVolume_updateAttachedEbsVolume === PAUSE TestAccAWSEBSVolume_updateAttachedEbsVolume === RUN TestAccAWSEBSVolume_updateSize === PAUSE TestAccAWSEBSVolume_updateSize === RUN TestAccAWSEBSVolume_updateType === PAUSE TestAccAWSEBSVolume_updateType === RUN TestAccAWSEBSVolume_updateIops_Io1 === PAUSE TestAccAWSEBSVolume_updateIops_Io1 === RUN TestAccAWSEBSVolume_updateIops_Io2 === PAUSE TestAccAWSEBSVolume_updateIops_Io2 === RUN TestAccAWSEBSVolume_kmsKey === PAUSE TestAccAWSEBSVolume_kmsKey === RUN TestAccAWSEBSVolume_NoIops === PAUSE TestAccAWSEBSVolume_NoIops === RUN TestAccAWSEBSVolume_InvalidIopsForType === PAUSE TestAccAWSEBSVolume_InvalidIopsForType === RUN TestAccAWSEBSVolume_InvalidThroughputForType === PAUSE TestAccAWSEBSVolume_InvalidThroughputForType === RUN TestAccAWSEBSVolume_withTags === PAUSE TestAccAWSEBSVolume_withTags === RUN TestAccAWSEBSVolume_multiAttach === PAUSE TestAccAWSEBSVolume_multiAttach === RUN TestAccAWSEBSVolume_outpost === PAUSE TestAccAWSEBSVolume_outpost === RUN TestAccAWSEBSVolume_gp3_basic === PAUSE TestAccAWSEBSVolume_gp3_basic === RUN TestAccAWSEBSVolume_gp3_iops === PAUSE TestAccAWSEBSVolume_gp3_iops === RUN TestAccAWSEBSVolume_gp3_throughput === PAUSE TestAccAWSEBSVolume_gp3_throughput === RUN TestAccAWSEBSVolume_snapshotID === PAUSE TestAccAWSEBSVolume_snapshotID === RUN TestAccAWSEBSVolume_snapshotIDAndSize === PAUSE TestAccAWSEBSVolume_snapshotIDAndSize === RUN TestAccAWSEBSVolume_disappears === PAUSE TestAccAWSEBSVolume_disappears === CONT TestAccAWSEBSVolume_basic === CONT TestAccAWSEBSVolume_withTags === CONT TestAccAWSEBSVolume_disappears === CONT TestAccAWSEBSVolume_snapshotIDAndSize === CONT TestAccAWSEBSVolume_snapshotID === CONT TestAccAWSEBSVolume_gp3_throughput === CONT TestAccAWSEBSVolume_gp3_iops === CONT TestAccAWSEBSVolume_gp3_basic === CONT TestAccAWSEBSVolume_outpost === CONT TestAccAWSEBSVolume_multiAttach === CONT TestAccAWSEBSVolume_updateIops_Io2 === CONT TestAccAWSEBSVolume_InvalidThroughputForType === CONT TestAccAWSEBSVolume_InvalidIopsForType === CONT TestAccAWSEBSVolume_NoIops === CONT TestAccAWSEBSVolume_kmsKey === CONT TestAccAWSEBSVolume_updateType === CONT TestAccAWSEBSVolume_updateIops_Io1 === CONT TestAccAWSEBSVolume_updateSize === CONT TestAccAWSEBSVolume_updateAttachedEbsVolume === CONT TestAccAWSEBSVolume_outpost data_source_aws_outposts_outposts_test.go:66: skipping since no Outposts found --- SKIP: TestAccAWSEBSVolume_outpost (2.98s) --- PASS: TestAccAWSEBSVolume_InvalidThroughputForType (20.53s) --- PASS: TestAccAWSEBSVolume_InvalidIopsForType (20.60s) --- PASS: TestAccAWSEBSVolume_disappears (57.32s) --- PASS: TestAccAWSEBSVolume_NoIops (65.27s) --- PASS: TestAccAWSEBSVolume_multiAttach (72.48s) --- PASS: TestAccAWSEBSVolume_withTags (72.54s) --- PASS: TestAccAWSEBSVolume_basic (72.60s) --- PASS: TestAccAWSEBSVolume_gp3_basic (73.47s) --- PASS: TestAccAWSEBSVolume_kmsKey (74.54s) --- PASS: TestAccAWSEBSVolume_snapshotIDAndSize (80.58s) --- PASS: TestAccAWSEBSVolume_snapshotID (84.31s) --- PASS: TestAccAWSEBSVolume_updateIops_Io2 (84.79s) --- PASS: TestAccAWSEBSVolume_updateType (97.39s) --- PASS: TestAccAWSEBSVolume_updateIops_Io1 (100.53s) --- PASS: TestAccAWSEBSVolume_gp3_throughput (101.28s) --- PASS: TestAccAWSEBSVolume_updateSize (101.72s) --- PASS: TestAccAWSEBSVolume_gp3_iops (102.74s) --- PASS: TestAccAWSEBSVolume_updateAttachedEbsVolume (189.96s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 190.076s --- aws/resource_aws_ebs_volume.go | 16 +++++++++------- website/docs/r/ebs_volume.html.markdown | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/aws/resource_aws_ebs_volume.go b/aws/resource_aws_ebs_volume.go index 2f7d5c460b3..6b57529222d 100644 --- a/aws/resource_aws_ebs_volume.go +++ b/aws/resource_aws_ebs_volume.go @@ -62,15 +62,17 @@ func resourceAwsEbsVolume() *schema.Resource { ForceNew: true, }, "size": { - Type: schema.TypeInt, - Optional: true, - Computed: true, + Type: schema.TypeInt, + Optional: true, + Computed: true, + AtLeastOneOf: []string{"size", "snapshot_id"}, }, "snapshot_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + AtLeastOneOf: []string{"size", "snapshot_id"}, }, "outpost_arn": { Type: schema.TypeString, diff --git a/website/docs/r/ebs_volume.html.markdown b/website/docs/r/ebs_volume.html.markdown index e0c1e716ead..f5746c4142d 100644 --- a/website/docs/r/ebs_volume.html.markdown +++ b/website/docs/r/ebs_volume.html.markdown @@ -23,7 +23,7 @@ resource "aws_ebs_volume" "example" { } ``` -~> **NOTE**: One of `size` or `snapshot_id` is required when specifying an EBS volume +~> **NOTE**: At least one of `size` or `snapshot_id` is required when specifying an EBS volume ## Argument Reference