diff --git a/.changelog/29671.txt b/.changelog/29671.txt new file mode 100644 index 00000000000..76a65c79b66 --- /dev/null +++ b/.changelog/29671.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_sesv2_configuration_set: Allow `suppression_options.suppressed_reasons` to be an empty list (`[]`) in order to disable the suppression list +``` diff --git a/internal/service/sesv2/configuration_set.go b/internal/service/sesv2/configuration_set.go index 1eb3eb392f8..eff1f1c7bea 100644 --- a/internal/service/sesv2/configuration_set.go +++ b/internal/service/sesv2/configuration_set.go @@ -14,6 +14,7 @@ import ( "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go-v2/service/sesv2" "github.com/aws/aws-sdk-go-v2/service/sesv2/types" + "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -112,7 +113,6 @@ func ResourceConfigurationSet() *schema.Resource { "suppressed_reasons": { Type: schema.TypeList, Optional: true, - MinItems: 1, Elem: &schema.Schema{ Type: schema.TypeString, ValidateDiagFunc: enum.Validate[types.SuppressionListReason](), @@ -187,36 +187,46 @@ func resourceConfigurationSetCreate(ctx context.Context, d *schema.ResourceData, var diags diag.Diagnostics conn := meta.(*conns.AWSClient).SESV2Client(ctx) - in := &sesv2.CreateConfigurationSetInput{ + input := &sesv2.CreateConfigurationSetInput{ ConfigurationSetName: aws.String(d.Get("configuration_set_name").(string)), Tags: getTagsIn(ctx), } if v, ok := d.GetOk("delivery_options"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - in.DeliveryOptions = expandDeliveryOptions(v.([]interface{})[0].(map[string]interface{})) + input.DeliveryOptions = expandDeliveryOptions(v.([]interface{})[0].(map[string]interface{})) } if v, ok := d.GetOk("reputation_options"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - in.ReputationOptions = expandReputationOptions(v.([]interface{})[0].(map[string]interface{})) + input.ReputationOptions = expandReputationOptions(v.([]interface{})[0].(map[string]interface{})) } if v, ok := d.GetOk("sending_options"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - in.SendingOptions = expandSendingOptions(v.([]interface{})[0].(map[string]interface{})) + input.SendingOptions = expandSendingOptions(v.([]interface{})[0].(map[string]interface{})) } - if v, ok := d.GetOk("suppression_options"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - in.SuppressionOptions = expandSuppressionOptions(v.([]interface{})[0].(map[string]interface{})) + if v, ok := d.GetRawConfig().AsValueMap()["suppression_options"]; ok && v.LengthInt() > 0 { + if v, ok := v.Index(cty.NumberIntVal(0)).AsValueMap()["suppressed_reasons"]; ok && !v.IsNull() { + tfMap := map[string]interface{}{ + "suppressed_reasons": []interface{}{}, + } + + for _, v := range v.AsValueSlice() { + tfMap["suppressed_reasons"] = append(tfMap["suppressed_reasons"].([]interface{}), v.AsString()) + } + + input.SuppressionOptions = expandSuppressionOptions(tfMap) + } } if v, ok := d.GetOk("tracking_options"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - in.TrackingOptions = expandTrackingOptions(v.([]interface{})[0].(map[string]interface{})) + input.TrackingOptions = expandTrackingOptions(v.([]interface{})[0].(map[string]interface{})) } if v, ok := d.GetOk("vdm_options"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - in.VdmOptions = expandVDMOptions(v.([]interface{})[0].(map[string]interface{})) + input.VdmOptions = expandVDMOptions(v.([]interface{})[0].(map[string]interface{})) } - out, err := conn.CreateConfigurationSet(ctx, in) + out, err := conn.CreateConfigurationSet(ctx, input) if err != nil { return create.AppendDiagError(diags, names.SESV2, create.ErrActionCreating, ResNameConfigurationSet, d.Get("configuration_set_name").(string), err) } @@ -648,13 +658,17 @@ func expandSuppressionOptions(tfMap map[string]interface{}) *types.SuppressionOp return nil } - a := &types.SuppressionOptions{} + apiObject := &types.SuppressionOptions{} - if v, ok := tfMap["suppressed_reasons"].([]interface{}); ok && len(v) > 0 { - a.SuppressedReasons = expandSuppressedReasons(v) + if v, ok := tfMap["suppressed_reasons"].([]interface{}); ok { + if len(v) > 0 { + apiObject.SuppressedReasons = expandSuppressedReasons(v) + } else { + apiObject.SuppressedReasons = make([]types.SuppressionListReason, 0) + } } - return a + return apiObject } func expandSuppressedReasons(tfList []interface{}) []types.SuppressionListReason { diff --git a/internal/service/sesv2/configuration_set_test.go b/internal/service/sesv2/configuration_set_test.go index 0daf8c6002c..8541faca73f 100644 --- a/internal/service/sesv2/configuration_set_test.go +++ b/internal/service/sesv2/configuration_set_test.go @@ -218,6 +218,34 @@ func TestAccSESV2ConfigurationSet_suppressedReasons(t *testing.T) { }) } +func TestAccSESV2ConfigurationSet_suppressedReasonsEmpty(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_sesv2_configuration_set.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.SESV2ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckConfigurationSetDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccConfigurationSetConfig_suppressedReasonsEmpty(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckConfigurationSetExists(ctx, resourceName), + resource.TestCheckResourceAttr(resourceName, "suppression_options.#", acctest.Ct1), + resource.TestCheckResourceAttr(resourceName, "suppression_options.0.suppressed_reasons.#", acctest.Ct0), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccSESV2ConfigurationSet_engagementMetrics(t *testing.T) { ctx := acctest.Context(t) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -339,6 +367,17 @@ func TestAccSESV2ConfigurationSet_tags(t *testing.T) { }) } +func testAccConfigurationSetConfig_suppressedReasonsEmpty(rName string) string { + return fmt.Sprintf(` +resource "aws_sesv2_configuration_set" "test" { + configuration_set_name = %[1]q + suppression_options { + suppressed_reasons = [] + } +} +`, rName) +} + func testAccCheckConfigurationSetDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).SESV2Client(ctx)