diff --git a/.changelog/43208.txt b/.changelog/43208.txt new file mode 100644 index 000000000000..bef18843a6c7 --- /dev/null +++ b/.changelog/43208.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_cloudfrontkeyvaluestore_keys_exclusive: Fix errant deletion of key value pairs when a value is changed +``` diff --git a/internal/service/cloudfrontkeyvaluestore/equal.go b/internal/service/cloudfrontkeyvaluestore/equal.go index b8269fe493e4..75f9f54c1ad7 100644 --- a/internal/service/cloudfrontkeyvaluestore/equal.go +++ b/internal/service/cloudfrontkeyvaluestore/equal.go @@ -12,3 +12,8 @@ import ( func resourceKeyValuePairEqual(s1, s2 awstypes.ListKeysResponseListItem) bool { return aws.ToString(s1.Key) == aws.ToString(s2.Key) && aws.ToString(s1.Value) == aws.ToString(s2.Value) } + +// resourceKeyValuePairKeyEqual determines whether two key value pairs have an equal key +func resourceKeyValuePairKeyEqual(s1, s2 awstypes.ListKeysResponseListItem) bool { + return aws.ToString(s1.Key) == aws.ToString(s2.Key) +} diff --git a/internal/service/cloudfrontkeyvaluestore/keys_exclusive.go b/internal/service/cloudfrontkeyvaluestore/keys_exclusive.go index aab3d5ace86b..05e7b8fc8c13 100644 --- a/internal/service/cloudfrontkeyvaluestore/keys_exclusive.go +++ b/internal/service/cloudfrontkeyvaluestore/keys_exclusive.go @@ -124,7 +124,8 @@ func (r *keysExclusiveResource) syncKeyValuePairs(ctx context.Context, plan *key return diags } - put, del, _ := intflex.DiffSlices(have, want, resourceKeyValuePairEqual) + put, del, modify, _ := intflex.DiffSlicesWithModify(have, want, resourceKeyValuePairEqual, resourceKeyValuePairKeyEqual) + put = append(put, modify...) // We need to perform a batched operation in the event of many Key Value Pairs // to stay within AWS service limits @@ -295,7 +296,6 @@ func FindResourceKeyValuePairsForKeyValueStore(ctx context.Context, conn *cloudf paginator := cloudfrontkeyvaluestore.NewListKeysPaginator(conn, input) for paginator.HasMorePages() { page, err := paginator.NextPage(ctx) - if err != nil { return nil, nil, err } @@ -324,7 +324,8 @@ func expandDeleteKeyRequestListItem(delete []awstypes.ListKeysResponseListItem) out := []awstypes.DeleteKeyRequestListItem{} for _, r := range delete { out = append(out, awstypes.DeleteKeyRequestListItem{ - Key: r.Key}) + Key: r.Key, + }) } return out diff --git a/internal/service/cloudfrontkeyvaluestore/keys_exclusive_test.go b/internal/service/cloudfrontkeyvaluestore/keys_exclusive_test.go index f1bc78af6ab2..6a6b3dc14f49 100644 --- a/internal/service/cloudfrontkeyvaluestore/keys_exclusive_test.go +++ b/internal/service/cloudfrontkeyvaluestore/keys_exclusive_test.go @@ -333,6 +333,41 @@ func TestAccCloudFrontKeyValueStoreKeysExclusive_maxBatchSize(t *testing.T) { }) } +func TestAccCloudFrontKeyValueStoreKeysExclusive_valueUpdate(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + keys := []string{sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)} + values := []string{sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)} + valuesUpdated := []string{sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)} + resourceName := "aws_cloudfrontkeyvaluestore_keys_exclusive.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.CloudFront) + }, + ErrorCheck: acctest.ErrorCheck(t, names.CloudFront), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckKeysExclusiveDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccKeysExclusiveConfig_basic(keys, values, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckKeysExclusiveExists(ctx, resourceName), + testCheckMultipleKeyValuePairs(keys, values, resourceName), + ), + }, + { + Config: testAccKeysExclusiveConfig_basic(keys, valuesUpdated, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckKeysExclusiveExists(ctx, resourceName), + testCheckMultipleKeyValuePairs(keys, valuesUpdated, resourceName), + ), + }, + }, + }) +} + func testAccCheckKeysExclusiveDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).CloudFrontKeyValueStoreClient(ctx) @@ -369,7 +404,6 @@ func testAccCheckKeysExclusiveExists(ctx context.Context, n string) resource.Tes conn := acctest.Provider.Meta().(*conns.AWSClient).CloudFrontKeyValueStoreClient(ctx) _, out, err := tfcloudfrontkeyvaluestore.FindResourceKeyValuePairsForKeyValueStore(ctx, conn, rs.Primary.Attributes["key_value_store_arn"]) - if err != nil { return create.Error(names.CloudFrontKeyValueStore, create.ErrActionCheckingExistence, tfcloudfrontkeyvaluestore.ResNameKeysExclusive, rs.Primary.Attributes["key_value_store_arn"], err) } @@ -393,7 +427,6 @@ func testAccCheckKeyValueStoreKeysExclusiveUpdate(ctx context.Context, n string, conn := acctest.Provider.Meta().(*conns.AWSClient).CloudFrontKeyValueStoreClient(ctx) resp, err := tfcloudfrontkeyvaluestore.FindKeyValueStoreByARN(ctx, conn, rs.Primary.Attributes["key_value_store_arn"]) - if err != nil { return fmt.Errorf("error finding Cloudfront KeyValueStore in out of band test") } @@ -406,7 +439,6 @@ func testAccCheckKeyValueStoreKeysExclusiveUpdate(ctx context.Context, n string, } _, err = conn.UpdateKeys(ctx, &input) - if err != nil { return fmt.Errorf("Error updating CloudFront KeyValueStore %s Key for out of band tests", rs.Primary.Attributes["key_value_store_arn"]) }