diff --git a/.changelog/47409.txt b/.changelog/47409.txt new file mode 100644 index 000000000000..f0686f73d3ec --- /dev/null +++ b/.changelog/47409.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_wafv2_web_acl_logging_configuration: Fix `redacted_fields` removal not being detected +``` diff --git a/internal/service/wafv2/web_acl_logging_configuration.go b/internal/service/wafv2/web_acl_logging_configuration.go index 65793785983f..4597b4dc8285 100644 --- a/internal/service/wafv2/web_acl_logging_configuration.go +++ b/internal/service/wafv2/web_acl_logging_configuration.go @@ -589,6 +589,14 @@ func redactedFieldsHash(v any) int { } func suppressRedactedFieldsDiff(k, old, new string, d *schema.ResourceData) bool { + // Detect full removal via raw parameters: d.GetChange() can return stale + // "new" data for nested TypeList attributes, causing the Set comparison + // below to miss the diff. + // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/41778 + if k == "redacted_fields.#" && old != "0" && new == "0" { + return false + } + o, n := d.GetChange("redacted_fields") oList := o.([]any) nList := n.([]any) diff --git a/internal/service/wafv2/web_acl_logging_configuration_test.go b/internal/service/wafv2/web_acl_logging_configuration_test.go index d3910f137247..8a61cce2b9d7 100644 --- a/internal/service/wafv2/web_acl_logging_configuration_test.go +++ b/internal/service/wafv2/web_acl_logging_configuration_test.go @@ -492,6 +492,50 @@ func TestAccWAFV2WebACLLoggingConfiguration_updateEmptyRedactedFields(t *testing }) } +// Reference: https://github.com/hashicorp/terraform-provider-aws/issues/41778 +func TestAccWAFV2WebACLLoggingConfiguration_removeRedactedFields(t *testing.T) { + ctx := acctest.Context(t) + var v awstypes.LoggingConfiguration + rName := acctest.RandomWithPrefix(t, acctest.ResourcePrefix) + resourceName := "aws_wafv2_web_acl_logging_configuration.test" + webACLResourceName := "aws_wafv2_web_acl.test" + + acctest.ParallelTest(ctx, t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.WAFV2ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckWebACLLoggingConfigurationDestroy(ctx, t), + Steps: []resource.TestStep{ + { + Config: testAccWebACLLoggingConfigurationConfig_updateSingleHeaderRedactedField(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckWebACLLoggingConfigurationExists(ctx, t, resourceName, &v), + resource.TestCheckResourceAttrPair(resourceName, names.AttrResourceARN, webACLResourceName, names.AttrARN), + resource.TestCheckResourceAttr(resourceName, "log_destination_configs.#", "1"), + resource.TestCheckResourceAttr(resourceName, "redacted_fields.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "redacted_fields.*", map[string]string{ + "single_header.0.name": "user-agent", + }), + ), + }, + { + Config: testAccWebACLLoggingConfigurationConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckWebACLLoggingConfigurationExists(ctx, t, resourceName, &v), + resource.TestCheckResourceAttrPair(resourceName, names.AttrResourceARN, webACLResourceName, names.AttrARN), + resource.TestCheckResourceAttr(resourceName, "log_destination_configs.#", "1"), + resource.TestCheckResourceAttr(resourceName, "redacted_fields.#", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccWAFV2WebACLLoggingConfiguration_Disappears_webACL(t *testing.T) { ctx := acctest.Context(t) var v awstypes.LoggingConfiguration