From a549d0a69ab6b523496f417ee115547ca859c829 Mon Sep 17 00:00:00 2001 From: Alex Bacchin Date: Thu, 28 Nov 2024 09:15:15 +1100 Subject: [PATCH 1/5] added `completion_duration_minutes` argument --- internal/service/ec2/ebs_snapshot_copy.go | 9 +++++ .../service/ec2/ebs_snapshot_copy_test.go | 38 +++++++++++++++++++ .../docs/r/ebs_snapshot_copy.html.markdown | 1 + 3 files changed, 48 insertions(+) diff --git a/internal/service/ec2/ebs_snapshot_copy.go b/internal/service/ec2/ebs_snapshot_copy.go index 8e4a3b0a275..3e5c0ef0621 100644 --- a/internal/service/ec2/ebs_snapshot_copy.go +++ b/internal/service/ec2/ebs_snapshot_copy.go @@ -109,6 +109,11 @@ func resourceEBSSnapshotCopy() *schema.Resource { Type: schema.TypeInt, Computed: true, }, + "completion_duration_minutes": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.All(validation.IntDivisibleBy(15), validation.IntAtMost(2880)), + }, }, } } @@ -135,6 +140,10 @@ func resourceEBSSnapshotCopyCreate(ctx context.Context, d *schema.ResourceData, input.KmsKeyId = aws.String(v.(string)) } + if v, ok := d.GetOk("completion_duration_minutes"); ok { + input.CompletionDurationMinutes = aws.Int32(int32(v.(int))) + } + output, err := conn.CopySnapshot(ctx, input) if err != nil { diff --git a/internal/service/ec2/ebs_snapshot_copy_test.go b/internal/service/ec2/ebs_snapshot_copy_test.go index 0941be389b5..cb98d8f5638 100644 --- a/internal/service/ec2/ebs_snapshot_copy_test.go +++ b/internal/service/ec2/ebs_snapshot_copy_test.go @@ -200,6 +200,29 @@ func TestAccEC2EBSSnapshotCopy_storageTier(t *testing.T) { }) } +func TestAccEC2EBSSnapshotCopy_withCompletionDurationMinutes(t *testing.T) { + ctx := acctest.Context(t) + var snapshot awstypes.Snapshot + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_ebs_snapshot_copy.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.EC2ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckEBSSnapshotDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccEBSSnapshotCopyConfig_completionDurationMinutes(rName, 15), + Check: resource.ComposeTestCheckFunc( + testAccCheckSnapshotExists(ctx, resourceName, &snapshot), + resource.TestCheckResourceAttr(resourceName, "completion_duration_minutes", "15"), + ), + }, + }, + }) +} + func testAccEBSSnapshotCopyBaseConfig(rName string) string { return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` data "aws_region" "current" {} @@ -349,3 +372,18 @@ resource "aws_ebs_snapshot_copy" "test" { } `, rName)) } + +func testAccEBSSnapshotCopyConfig_completionDurationMinutes(rName string, durantionMinutes int) string { + return acctest.ConfigCompose(testAccEBSSnapshotCopyBaseConfig(rName), fmt.Sprintf(` +resource "aws_ebs_snapshot_copy" "test" { + source_snapshot_id = aws_ebs_snapshot.test.id + source_region = data.aws_region.current.name + completion_duration_minutes = %[2]d + + tags = { + Name = %[1]q + } + +} +`, rName, durantionMinutes)) +} diff --git a/website/docs/r/ebs_snapshot_copy.html.markdown b/website/docs/r/ebs_snapshot_copy.html.markdown index 0961d0477d3..b1fe2c69ef7 100644 --- a/website/docs/r/ebs_snapshot_copy.html.markdown +++ b/website/docs/r/ebs_snapshot_copy.html.markdown @@ -52,6 +52,7 @@ This resource supports the following arguments: * `storage_tier` - (Optional) The name of the storage tier. Valid values are `archive` and `standard`. Default value is `standard`. * `permanent_restore` - (Optional) Indicates whether to permanently restore an archived snapshot. * `temporary_restore_days` - (Optional) Specifies the number of days for which to temporarily restore an archived snapshot. Required for temporary restores only. The snapshot will be automatically re-archived after this period. +* `completion_duration_minutes` - (Optional) Specifies a completion duration to initiate a time-based snapshot copy. Time-based snapshot copy operations complete within the specified duration. Value must be between 15 and 2880 minutes, in 15 minute increments only. * `tags` - A map of tags for the snapshot. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ## Attribute Reference From c2a6c2adfc3501530f2b1507606604a4e8eb6e8f Mon Sep 17 00:00:00 2001 From: Alex Bacchin Date: Thu, 28 Nov 2024 09:20:09 +1100 Subject: [PATCH 2/5] added changelog --- .changelog/40336.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/40336.txt diff --git a/.changelog/40336.txt b/.changelog/40336.txt new file mode 100644 index 00000000000..50800365f5a --- /dev/null +++ b/.changelog/40336.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/ebs_snapshot_copy: Add `completion_duration_minutes` argument. +``` From 782d8e1a9162be0f2de082e885e0e88212bd843b Mon Sep 17 00:00:00 2001 From: Alex Bacchin Date: Thu, 28 Nov 2024 10:38:23 +1100 Subject: [PATCH 3/5] fixed terraform fmt --- internal/service/ec2/ebs_snapshot_copy_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/service/ec2/ebs_snapshot_copy_test.go b/internal/service/ec2/ebs_snapshot_copy_test.go index cb98d8f5638..67054846c27 100644 --- a/internal/service/ec2/ebs_snapshot_copy_test.go +++ b/internal/service/ec2/ebs_snapshot_copy_test.go @@ -383,7 +383,6 @@ resource "aws_ebs_snapshot_copy" "test" { tags = { Name = %[1]q } - } `, rName, durantionMinutes)) } From 5867b46f5ecd80ff2e97b5f0f15c2bc29ebc3da1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 5 Dec 2024 11:42:00 -0500 Subject: [PATCH 4/5] Tweak CHANGELOG entry. --- .changelog/40336.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/40336.txt b/.changelog/40336.txt index 50800365f5a..64a639970cc 100644 --- a/.changelog/40336.txt +++ b/.changelog/40336.txt @@ -1,3 +1,3 @@ ```release-note:enhancement -resource/ebs_snapshot_copy: Add `completion_duration_minutes` argument. +resource/aws_ebs_snapshot_copy: Add `completion_duration_minutes` argument ``` From cee48d9236e2012a7c9173e012520c04037f8cde Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 5 Dec 2024 11:52:20 -0500 Subject: [PATCH 5/5] Cosmetics. --- internal/service/ec2/ebs_snapshot_copy.go | 34 +++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/internal/service/ec2/ebs_snapshot_copy.go b/internal/service/ec2/ebs_snapshot_copy.go index 3e5c0ef0621..cd0f93d01e9 100644 --- a/internal/service/ec2/ebs_snapshot_copy.go +++ b/internal/service/ec2/ebs_snapshot_copy.go @@ -44,6 +44,12 @@ func resourceEBSSnapshotCopy() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "completion_duration_minutes": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + ValidateFunc: validation.All(validation.IntDivisibleBy(15), validation.IntAtMost(2880)), + }, "data_encryption_key_id": { Type: schema.TypeString, Computed: true, @@ -109,11 +115,6 @@ func resourceEBSSnapshotCopy() *schema.Resource { Type: schema.TypeInt, Computed: true, }, - "completion_duration_minutes": { - Type: schema.TypeInt, - Optional: true, - ValidateFunc: validation.All(validation.IntDivisibleBy(15), validation.IntAtMost(2880)), - }, }, } } @@ -128,6 +129,10 @@ func resourceEBSSnapshotCopyCreate(ctx context.Context, d *schema.ResourceData, TagSpecifications: getTagSpecificationsIn(ctx, awstypes.ResourceTypeSnapshot), } + if v, ok := d.GetOk("completion_duration_minutes"); ok { + input.CompletionDurationMinutes = aws.Int32(int32(v.(int))) + } + if v, ok := d.GetOk(names.AttrDescription); ok { input.Description = aws.String(v.(string)) } @@ -140,10 +145,6 @@ func resourceEBSSnapshotCopyCreate(ctx context.Context, d *schema.ResourceData, input.KmsKeyId = aws.String(v.(string)) } - if v, ok := d.GetOk("completion_duration_minutes"); ok { - input.CompletionDurationMinutes = aws.Int32(int32(v.(int))) - } - output, err := conn.CopySnapshot(ctx, input) if err != nil { @@ -154,8 +155,7 @@ func resourceEBSSnapshotCopyCreate(ctx context.Context, d *schema.ResourceData, _, err = tfresource.RetryWhenAWSErrCodeEquals(ctx, d.Timeout(schema.TimeoutCreate), func() (interface{}, error) { - waiter := ec2.NewSnapshotCompletedWaiter(conn) - return waiter.WaitForOutput(ctx, &ec2.DescribeSnapshotsInput{ + return ec2.NewSnapshotCompletedWaiter(conn).WaitForOutput(ctx, &ec2.DescribeSnapshotsInput{ SnapshotIds: []string{d.Id()}, }, d.Timeout(schema.TimeoutCreate)) }, @@ -165,19 +165,19 @@ func resourceEBSSnapshotCopyCreate(ctx context.Context, d *schema.ResourceData, return sdkdiag.AppendErrorf(diags, "waiting for EBS Snapshot Copy (%s) create: %s", d.Id(), err) } - if v, ok := d.GetOk("storage_tier"); ok && v.(string) == string(awstypes.TargetStorageTierArchive) { - _, err = conn.ModifySnapshotTier(ctx, &ec2.ModifySnapshotTierInput{ + if v, ok := d.GetOk("storage_tier"); ok && awstypes.TargetStorageTier(v.(string)) == awstypes.TargetStorageTierArchive { + input := &ec2.ModifySnapshotTierInput{ SnapshotId: aws.String(d.Id()), StorageTier: awstypes.TargetStorageTier(v.(string)), - }) + } + + _, err := conn.ModifySnapshotTier(ctx, input) if err != nil { return sdkdiag.AppendErrorf(diags, "setting EBS Snapshot Copy (%s) Storage Tier: %s", d.Id(), err) } - _, err = waitEBSSnapshotTierArchive(ctx, conn, d.Id(), ebsSnapshotArchivedTimeout) - - if err != nil { + if _, err := waitEBSSnapshotTierArchive(ctx, conn, d.Id(), ebsSnapshotArchivedTimeout); err != nil { return sdkdiag.AppendErrorf(diags, "waiting for EBS Snapshot Copy (%s) Storage Tier archive: %s", d.Id(), err) } }