From 855b7217517da3c2f97e448248a8134ab7cca0de Mon Sep 17 00:00:00 2001 From: Kamil Turek Date: Sun, 6 Nov 2022 23:44:03 +0100 Subject: [PATCH 01/13] Create new resource --- .../email_identity_mail_from_attributes.go | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 internal/service/sesv2/email_identity_mail_from_attributes.go diff --git a/internal/service/sesv2/email_identity_mail_from_attributes.go b/internal/service/sesv2/email_identity_mail_from_attributes.go new file mode 100644 index 00000000000..c28c23a4c0e --- /dev/null +++ b/internal/service/sesv2/email_identity_mail_from_attributes.go @@ -0,0 +1,174 @@ +package sesv2 + +import ( + "context" + "errors" + "log" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/sesv2" + "github.com/aws/aws-sdk-go-v2/service/sesv2/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func ResourceEmailIdentityMailFromAttributes() *schema.Resource { + return &schema.Resource{ + CreateWithoutTimeout: resourceEmailIdentityMailFromAttributesCreate, + ReadWithoutTimeout: resourceEmailIdentityMailFromAttributesRead, + UpdateWithoutTimeout: resourceEmailIdentityMailFromAttributesUpdate, + DeleteWithoutTimeout: resourceEmailIdentityMailFromAttributesDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: map[string]*schema.Schema{ + "behavior_on_mx_failure": { + Type: schema.TypeString, + Optional: true, + Default: string(types.BehaviorOnMxFailureUseDefaultValue), + ValidateFunc: validation.StringInSlice(behaviorOnMXFailureValues(types.BehaviorOnMxFailure("").Values()), false), + }, + "email_identity": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "mail_from_domain": { + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +const ( + ResNameEmailIdentityMailFromAttributes = "Email Identity Mail From Attributes" +) + +func resourceEmailIdentityMailFromAttributesCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).SESV2Client + + in := &sesv2.PutEmailIdentityMailFromAttributesInput{ + EmailIdentity: aws.String(d.Get("email_identity").(string)), + } + + if v, ok := d.GetOk("mail_from_domain"); ok { + in.MailFromDomain = aws.String(v.(string)) + } + + if v, ok := d.GetOk("behavior_on_mx_failure"); ok { + in.BehaviorOnMxFailure = types.BehaviorOnMxFailure(v.(string)) + } + + if in.BehaviorOnMxFailure == types.BehaviorOnMxFailureRejectMessage && in.MailFromDomain == nil { + return create.DiagError(names.SESV2, create.ErrActionCreating, ResNameEmailIdentityMailFromAttributes, d.Get("email_identity").(string), errors.New("mail from is required if behavior on mx failure is REJECT_MESSAGE")) + } + + out, err := conn.PutEmailIdentityMailFromAttributes(ctx, in) + if err != nil { + return create.DiagError(names.SESV2, create.ErrActionCreating, ResNameEmailIdentityMailFromAttributes, d.Get("name").(string), err) + } + + if out == nil { + return create.DiagError(names.SESV2, create.ErrActionCreating, ResNameEmailIdentityMailFromAttributes, d.Get("name").(string), errors.New("empty output")) + } + + d.SetId(d.Get("email_identity").(string)) + + return resourceEmailIdentityMailFromAttributesRead(ctx, d, meta) +} + +func resourceEmailIdentityMailFromAttributesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).SESV2Client + + out, err := FindEmailIdentityByID(ctx, conn, d.Id()) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] SESV2 EmailIdentityMailFromAttributes (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return create.DiagError(names.SESV2, create.ErrActionReading, ResNameEmailIdentityMailFromAttributes, d.Id(), err) + } + + d.Set("email_identity", d.Id()) + + if out.MailFromAttributes != nil { + d.Set("behavior_on_mx_failure", out.MailFromAttributes.BehaviorOnMxFailure) + d.Set("mail_from_domain", out.MailFromAttributes.MailFromDomain) + } else { + d.Set("behavior_on_mx_failure", nil) + d.Set("mail_from_domain", nil) + } + + return nil +} + +func resourceEmailIdentityMailFromAttributesUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).SESV2Client + + update := false + + in := &sesv2.PutEmailIdentityMailFromAttributesInput{ + EmailIdentity: aws.String(d.Id()), + } + + if d.HasChanges("behavior_on_mx_failure", "mail_from_domain") { + in.BehaviorOnMxFailure = types.BehaviorOnMxFailure((d.Get("behavior_on_mx_failure").(string))) + in.MailFromDomain = aws.String(d.Get("mail_from_domain").(string)) + + update = true + } + + if !update { + return nil + } + + log.Printf("[DEBUG] Updating SESV2 EmailIdentityMailFromAttributes (%s): %#v", d.Id(), in) + _, err := conn.PutEmailIdentityMailFromAttributes(ctx, in) + if err != nil { + return create.DiagError(names.SESV2, create.ErrActionUpdating, ResNameEmailIdentityMailFromAttributes, d.Id(), err) + } + + return resourceEmailIdentityMailFromAttributesRead(ctx, d, meta) +} + +func resourceEmailIdentityMailFromAttributesDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).SESV2Client + + log.Printf("[INFO] Deleting SESV2 EmailIdentityMailFromAttributes %s", d.Id()) + + _, err := conn.PutEmailIdentityMailFromAttributes(ctx, &sesv2.PutEmailIdentityMailFromAttributesInput{ + EmailIdentity: aws.String(d.Id()), + }) + + if err != nil { + var nfe *types.NotFoundException + if errors.As(err, &nfe) { + return nil + } + + return create.DiagError(names.SESV2, create.ErrActionDeleting, ResNameEmailIdentityMailFromAttributes, d.Id(), err) + } + + return nil +} + +func behaviorOnMXFailureValues(in []types.BehaviorOnMxFailure) []string { + var out []string + + for _, v := range in { + out = append(out, string(v)) + } + + return out +} From 048a9b794eaf02281ba0213ac950c4f0a739836d Mon Sep 17 00:00:00 2001 From: Kamil Turek Date: Sun, 6 Nov 2022 23:44:13 +0100 Subject: [PATCH 02/13] Register the new resource --- internal/provider/provider.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 22b2674e274..07d6b4d7cda 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -2069,11 +2069,12 @@ func New(_ context.Context) (*schema.Provider, error) { "aws_ses_receipt_rule_set": ses.ResourceReceiptRuleSet(), "aws_ses_template": ses.ResourceTemplate(), - "aws_sesv2_configuration_set": sesv2.ResourceConfigurationSet(), - "aws_sesv2_dedicated_ip_assignment": sesv2.ResourceDedicatedIPAssignment(), - "aws_sesv2_dedicated_ip_pool": sesv2.ResourceDedicatedIPPool(), - "aws_sesv2_email_identity": sesv2.ResourceEmailIdentity(), - "aws_sesv2_email_identity_feedback_attributes": sesv2.ResourceEmailIdentityFeedbackAttributes(), + "aws_sesv2_configuration_set": sesv2.ResourceConfigurationSet(), + "aws_sesv2_dedicated_ip_assignment": sesv2.ResourceDedicatedIPAssignment(), + "aws_sesv2_dedicated_ip_pool": sesv2.ResourceDedicatedIPPool(), + "aws_sesv2_email_identity": sesv2.ResourceEmailIdentity(), + "aws_sesv2_email_identity_feedback_attributes": sesv2.ResourceEmailIdentityFeedbackAttributes(), + "aws_sesv2_email_identity_mail_from_attributes": sesv2.ResourceEmailIdentityMailFromAttributes(), "aws_sfn_activity": sfn.ResourceActivity(), "aws_sfn_state_machine": sfn.ResourceStateMachine(), From 78a90331ad0bf1bd2e8670f05a63ba35534ab4a6 Mon Sep 17 00:00:00 2001 From: Kamil Turek Date: Sun, 6 Nov 2022 23:45:17 +0100 Subject: [PATCH 03/13] Create acceptance tests --- ...mail_identity_mail_from_attributes_test.go | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 internal/service/sesv2/email_identity_mail_from_attributes_test.go diff --git a/internal/service/sesv2/email_identity_mail_from_attributes_test.go b/internal/service/sesv2/email_identity_mail_from_attributes_test.go new file mode 100644 index 00000000000..83383cdddc8 --- /dev/null +++ b/internal/service/sesv2/email_identity_mail_from_attributes_test.go @@ -0,0 +1,192 @@ +package sesv2_test + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go-v2/service/sesv2/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + tfsesv2 "github.com/hashicorp/terraform-provider-aws/internal/service/sesv2" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccSESV2EmailIdentityMailFromAttributes_basic(t *testing.T) { + rName := acctest.RandomDomainName() + resourceName := "aws_sesv2_email_identity_mail_from_attributes.test" + emailIdentityName := "aws_sesv2_email_identity.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, names.SESV2EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckEmailIdentityDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEmailIdentityMailFromAttributesConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEmailIdentityMailFromAttributesExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "email_identity", emailIdentityName, "email_identity"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccSESV2EmailIdentityMailFromAttributes_disappears(t *testing.T) { + rName := acctest.RandomDomainName() + resourceName := "aws_sesv2_email_identity_mail_from_attributes.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, names.SESV2EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckEmailIdentityDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEmailIdentityMailFromAttributesConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEmailIdentityMailFromAttributesExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfsesv2.ResourceEmailIdentity(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccSESV2EmailIdentityMailFromAttributes_behaviorOnMXFailure(t *testing.T) { + domain := acctest.RandomDomain() + mailFromDomain := domain.Subdomain("test") + + rName := domain.String() + resourceName := "aws_sesv2_email_identity_mail_from_attributes.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, names.SESV2EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckEmailIdentityDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEmailIdentityMailFromAttributesConfig_behaviorOnMXFailureAndMailFromDomain(rName, string(types.BehaviorOnMxFailureUseDefaultValue), mailFromDomain.String()), + Check: resource.ComposeTestCheckFunc( + testAccCheckEmailIdentityMailFromAttributesExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "behavior_on_mx_failure", string(types.BehaviorOnMxFailureUseDefaultValue)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccEmailIdentityMailFromAttributesConfig_behaviorOnMXFailureAndMailFromDomain(rName, string(types.BehaviorOnMxFailureRejectMessage), mailFromDomain.String()), + Check: resource.ComposeTestCheckFunc( + testAccCheckEmailIdentityMailFromAttributesExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "behavior_on_mx_failure", string(types.BehaviorOnMxFailureRejectMessage)), + ), + }, + }, + }) +} + +func TestAccSESV2EmailIdentityMailFromAttributes_mailFromDomain(t *testing.T) { + domain := acctest.RandomDomain() + mailFromDomain1 := domain.Subdomain("test1") + mailFromDomain2 := domain.Subdomain("test2") + + rName := domain.String() + resourceName := "aws_sesv2_email_identity_mail_from_attributes.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, names.SESV2EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckEmailIdentityDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEmailIdentityMailFromAttributesConfig_behaviorOnMXFailureAndMailFromDomain(rName, string(types.BehaviorOnMxFailureUseDefaultValue), mailFromDomain1.String()), + Check: resource.ComposeTestCheckFunc( + testAccCheckEmailIdentityMailFromAttributesExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "mail_from_domain", mailFromDomain1.String()), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccEmailIdentityMailFromAttributesConfig_behaviorOnMXFailureAndMailFromDomain(rName, string(types.BehaviorOnMxFailureUseDefaultValue), mailFromDomain2.String()), + Check: resource.ComposeTestCheckFunc( + testAccCheckEmailIdentityMailFromAttributesExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "mail_from_domain", mailFromDomain2.String()), + ), + }, + }, + }) +} + +func testAccCheckEmailIdentityMailFromAttributesExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return create.Error(names.SESV2, create.ErrActionCheckingExistence, tfsesv2.ResNameEmailIdentityMailFromAttributes, name, errors.New("not found")) + } + + if rs.Primary.ID == "" { + return create.Error(names.SESV2, create.ErrActionCheckingExistence, tfsesv2.ResNameEmailIdentityMailFromAttributes, name, errors.New("not set")) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).SESV2Client + + out, err := tfsesv2.FindEmailIdentityByID(context.Background(), conn, rs.Primary.ID) + + if err != nil { + return create.Error(names.SESV2, create.ErrActionCheckingExistence, tfsesv2.ResNameEmailIdentityMailFromAttributes, rs.Primary.ID, err) + } + + if out == nil || out.MailFromAttributes == nil { + return create.Error(names.SESV2, create.ErrActionCheckingExistence, tfsesv2.ResNameEmailIdentityMailFromAttributes, rs.Primary.ID, err) + } + + return nil + } +} + +func testAccEmailIdentityMailFromAttributesConfig_basic(rName string) string { + return fmt.Sprintf(` +resource "aws_sesv2_email_identity" "test" { + email_identity = %[1]q +} + +resource "aws_sesv2_email_identity_mail_from_attributes" "test" { + email_identity = aws_sesv2_email_identity.test.email_identity +} +`, rName) +} + +func testAccEmailIdentityMailFromAttributesConfig_behaviorOnMXFailureAndMailFromDomain(rName, behaviorOnMXFailure, mailFromDomain string) string { + return fmt.Sprintf(` +resource "aws_sesv2_email_identity" "test" { + email_identity = %[1]q +} + +resource "aws_sesv2_email_identity_mail_from_attributes" "test" { + email_identity = aws_sesv2_email_identity.test.email_identity + behavior_on_mx_failure = %[2]q + mail_from_domain = %[3]q +} +`, rName, behaviorOnMXFailure, mailFromDomain) +} From 3dd18e960630d8ba00e9abf645fcfc1e1db90766 Mon Sep 17 00:00:00 2001 From: Kamil Turek Date: Sun, 6 Nov 2022 23:50:53 +0100 Subject: [PATCH 04/13] Create a website page --- ...dentity_mail_from_attributes.html.markdown | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown diff --git a/website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown b/website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown new file mode 100644 index 00000000000..7d4290123ec --- /dev/null +++ b/website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown @@ -0,0 +1,48 @@ +--- +subcategory: "SESv2 (Simple Email V2)" +layout: "aws" +page_title: "AWS: aws_sesv2_email_identity_mail_from_attributes" +description: |- + Terraform resource for managing an AWS SESv2 (Simple Email V2) Email Identity Mail From Attributes. +--- + +# Resource: aws_sesv2_email_identity_mail_from_attributes + +Terraform resource for managing an AWS SESv2 (Simple Email V2) Email Identity Mail From Attributes. + +## Example Usage + +### Basic Usage + +```terraform +resource "aws_sesv2_email_identity" "example" { + email_identity = "example.com" +} + +resource "aws_sesv2_email_identity_mail_from_attributes" "example" { + email_identity = aws_sesv2_email_identity.example.email_identity + + behavior_on_mx_failure = "REJECT_MESSAGE" + mail_from_domain = "test.${aws_sesv2_email_identity.test.email_identity}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `email_identity` - (Required) The verified email identity. +* `behavior_on_mx_failure` - (Optional) The action to take if the required MX record isn't found when you send an email. Valid values: `USE_DEFAULT_VALUE`, `REJECT_MESSAGE`. +* `mail_from_domain` - (Optional) The custom MAIL FROM domain that you want the verified identity to use. + +## Attributes Reference + +No additional attributes are exported. + +## Import + +SESv2 (Simple Email V2) Email Identity Mail From Attributes can be imported using the `email_identity`, e.g., + +``` +$ terraform import aws_sesv2_email_identity_mail_from_attributes.example example.com +``` From 967de8e5b2123fbbfb91ae28e30444a53138d8a9 Mon Sep 17 00:00:00 2001 From: Kamil Turek Date: Mon, 7 Nov 2022 00:22:05 +0100 Subject: [PATCH 05/13] Add custom validation --- .../sesv2/email_identity_mail_from_attributes.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/internal/service/sesv2/email_identity_mail_from_attributes.go b/internal/service/sesv2/email_identity_mail_from_attributes.go index c28c23a4c0e..cf37aa660f4 100644 --- a/internal/service/sesv2/email_identity_mail_from_attributes.go +++ b/internal/service/sesv2/email_identity_mail_from_attributes.go @@ -17,6 +17,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) +var ErrMailFromRequired = errors.New("mail from domain is required if behavior on MX failure is REJECT_MESSAGE") + func ResourceEmailIdentityMailFromAttributes() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceEmailIdentityMailFromAttributesCreate, @@ -67,8 +69,8 @@ func resourceEmailIdentityMailFromAttributesCreate(ctx context.Context, d *schem in.BehaviorOnMxFailure = types.BehaviorOnMxFailure(v.(string)) } - if in.BehaviorOnMxFailure == types.BehaviorOnMxFailureRejectMessage && in.MailFromDomain == nil { - return create.DiagError(names.SESV2, create.ErrActionCreating, ResNameEmailIdentityMailFromAttributes, d.Get("email_identity").(string), errors.New("mail from is required if behavior on mx failure is REJECT_MESSAGE")) + if in.BehaviorOnMxFailure == types.BehaviorOnMxFailureRejectMessage && (in.MailFromDomain == nil || aws.ToString(in.MailFromDomain) == "") { + return create.DiagError(names.SESV2, create.ErrActionCreating, ResNameEmailIdentityMailFromAttributes, d.Get("email_identity").(string), ErrMailFromRequired) } out, err := conn.PutEmailIdentityMailFromAttributes(ctx, in) @@ -126,6 +128,10 @@ func resourceEmailIdentityMailFromAttributesUpdate(ctx context.Context, d *schem in.BehaviorOnMxFailure = types.BehaviorOnMxFailure((d.Get("behavior_on_mx_failure").(string))) in.MailFromDomain = aws.String(d.Get("mail_from_domain").(string)) + if in.BehaviorOnMxFailure == types.BehaviorOnMxFailureRejectMessage && (in.MailFromDomain == nil || aws.ToString(in.MailFromDomain) == "") { + return create.DiagError(names.SESV2, create.ErrActionUpdating, ResNameEmailIdentityMailFromAttributes, d.Get("email_identity").(string), ErrMailFromRequired) + } + update = true } From 207b5a9832206fc3f7d75435dc396b415288b47e Mon Sep 17 00:00:00 2001 From: Kamil Turek Date: Mon, 7 Nov 2022 00:22:58 +0100 Subject: [PATCH 06/13] Add a note about the validation --- .../r/sesv2_email_identity_mail_from_attributes.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown b/website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown index 7d4290123ec..eeee3378865 100644 --- a/website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown +++ b/website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown @@ -33,7 +33,7 @@ The following arguments are supported: * `email_identity` - (Required) The verified email identity. * `behavior_on_mx_failure` - (Optional) The action to take if the required MX record isn't found when you send an email. Valid values: `USE_DEFAULT_VALUE`, `REJECT_MESSAGE`. -* `mail_from_domain` - (Optional) The custom MAIL FROM domain that you want the verified identity to use. +* `mail_from_domain` - (Optional) The custom MAIL FROM domain that you want the verified identity to use. Required if `behavior_on_mx_failure` is `REJECT_MESSAGE`. ## Attributes Reference From 6f3566cf584281d69d29c8de94bff71c82f90a2d Mon Sep 17 00:00:00 2001 From: Kamil Turek Date: Mon, 7 Nov 2022 00:48:37 +0100 Subject: [PATCH 07/13] Add a changelog entry --- .changelog/27672.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/27672.txt diff --git a/.changelog/27672.txt b/.changelog/27672.txt new file mode 100644 index 00000000000..ded5317eb41 --- /dev/null +++ b/.changelog/27672.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_sesv2_email_identity_mail_from_attributes +``` From 16d04a306fbcb35880d229a89a5d9f9902e7142c Mon Sep 17 00:00:00 2001 From: Kamil Turek Date: Mon, 7 Nov 2022 17:38:36 +0100 Subject: [PATCH 08/13] Fix the basic usage example --- .../r/sesv2_email_identity_mail_from_attributes.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown b/website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown index eeee3378865..e7b08c63d76 100644 --- a/website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown +++ b/website/docs/r/sesv2_email_identity_mail_from_attributes.html.markdown @@ -23,7 +23,7 @@ resource "aws_sesv2_email_identity_mail_from_attributes" "example" { email_identity = aws_sesv2_email_identity.example.email_identity behavior_on_mx_failure = "REJECT_MESSAGE" - mail_from_domain = "test.${aws_sesv2_email_identity.test.email_identity}" + mail_from_domain = "subdomain.${aws_sesv2_email_identity.example.email_identity}" } ``` From 130cd6c148773bb3d2ddfc51d8efe7689002ecd6 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Fri, 11 Nov 2022 11:14:50 -0500 Subject: [PATCH 09/13] r/aws_sesv2_email_identity_mail_from_attributes: use email_identity in diag error --- internal/service/sesv2/email_identity_mail_from_attributes.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/sesv2/email_identity_mail_from_attributes.go b/internal/service/sesv2/email_identity_mail_from_attributes.go index cf37aa660f4..bddcc1e2883 100644 --- a/internal/service/sesv2/email_identity_mail_from_attributes.go +++ b/internal/service/sesv2/email_identity_mail_from_attributes.go @@ -75,11 +75,11 @@ func resourceEmailIdentityMailFromAttributesCreate(ctx context.Context, d *schem out, err := conn.PutEmailIdentityMailFromAttributes(ctx, in) if err != nil { - return create.DiagError(names.SESV2, create.ErrActionCreating, ResNameEmailIdentityMailFromAttributes, d.Get("name").(string), err) + return create.DiagError(names.SESV2, create.ErrActionCreating, ResNameEmailIdentityMailFromAttributes, d.Get("email_identity").(string), err) } if out == nil { - return create.DiagError(names.SESV2, create.ErrActionCreating, ResNameEmailIdentityMailFromAttributes, d.Get("name").(string), errors.New("empty output")) + return create.DiagError(names.SESV2, create.ErrActionCreating, ResNameEmailIdentityMailFromAttributes, d.Get("email_identity").(string), errors.New("empty output")) } d.SetId(d.Get("email_identity").(string)) From 3162175c9459698258a6022f96c198ea9e7bd399 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Fri, 11 Nov 2022 11:35:48 -0500 Subject: [PATCH 10/13] r/aws_sesv2_email_identity_mail_from_attributes: split disappears tests --- ...mail_identity_mail_from_attributes_test.go | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/internal/service/sesv2/email_identity_mail_from_attributes_test.go b/internal/service/sesv2/email_identity_mail_from_attributes_test.go index 83383cdddc8..c46978b91db 100644 --- a/internal/service/sesv2/email_identity_mail_from_attributes_test.go +++ b/internal/service/sesv2/email_identity_mail_from_attributes_test.go @@ -44,8 +44,34 @@ func TestAccSESV2EmailIdentityMailFromAttributes_basic(t *testing.T) { } func TestAccSESV2EmailIdentityMailFromAttributes_disappears(t *testing.T) { + domain := acctest.RandomDomain() + mailFromDomain := domain.Subdomain("test") + + rName := domain.String() + resourceName := "aws_sesv2_email_identity_mail_from_attributes.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, names.SESV2EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckEmailIdentityDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEmailIdentityMailFromAttributesConfig_behaviorOnMXFailureAndMailFromDomain(rName, string(types.BehaviorOnMxFailureUseDefaultValue), mailFromDomain.String()), + Check: resource.ComposeTestCheckFunc( + testAccCheckEmailIdentityMailFromAttributesExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfsesv2.ResourceEmailIdentityMailFromAttributes(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccSESV2EmailIdentityMailFromAttributes_disappearsEmailIdentity(t *testing.T) { rName := acctest.RandomDomainName() resourceName := "aws_sesv2_email_identity_mail_from_attributes.test" + emailIdentityName := "aws_sesv2_email_identity.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -57,7 +83,7 @@ func TestAccSESV2EmailIdentityMailFromAttributes_disappears(t *testing.T) { Config: testAccEmailIdentityMailFromAttributesConfig_basic(rName), Check: resource.ComposeTestCheckFunc( testAccCheckEmailIdentityMailFromAttributesExists(resourceName), - acctest.CheckResourceDisappears(acctest.Provider, tfsesv2.ResourceEmailIdentity(), resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfsesv2.ResourceEmailIdentity(), emailIdentityName), ), ExpectNonEmptyPlan: true, }, From abd449879ec3292a54678ce31b915ec224eabc73 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Fri, 11 Nov 2022 11:39:19 -0500 Subject: [PATCH 11/13] r/aws_sesv2_email_identity_mail_from_attributes: update nil check err --- .../service/sesv2/email_identity_mail_from_attributes_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/sesv2/email_identity_mail_from_attributes_test.go b/internal/service/sesv2/email_identity_mail_from_attributes_test.go index c46978b91db..3ac1b8a8b06 100644 --- a/internal/service/sesv2/email_identity_mail_from_attributes_test.go +++ b/internal/service/sesv2/email_identity_mail_from_attributes_test.go @@ -184,7 +184,7 @@ func testAccCheckEmailIdentityMailFromAttributesExists(name string) resource.Tes } if out == nil || out.MailFromAttributes == nil { - return create.Error(names.SESV2, create.ErrActionCheckingExistence, tfsesv2.ResNameEmailIdentityMailFromAttributes, rs.Primary.ID, err) + return create.Error(names.SESV2, create.ErrActionCheckingExistence, tfsesv2.ResNameEmailIdentityMailFromAttributes, rs.Primary.ID, errors.New("mail from attributes not set")) } return nil From 8dfc37faead572a6ab9aed92a1a8d2c9ef1650ed Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Fri, 11 Nov 2022 11:41:22 -0500 Subject: [PATCH 12/13] r/aws_sesv2_email_identity_feedback_attributes: update nil check err --- .../service/sesv2/email_identity_feedback_attributes_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/sesv2/email_identity_feedback_attributes_test.go b/internal/service/sesv2/email_identity_feedback_attributes_test.go index de5010e2ce5..3f96eeed7d3 100644 --- a/internal/service/sesv2/email_identity_feedback_attributes_test.go +++ b/internal/service/sesv2/email_identity_feedback_attributes_test.go @@ -141,7 +141,7 @@ func testAccCheckEmailIdentityFeedbackAttributesExist(name string, emailForwardi return create.Error(names.SESV2, create.ErrActionCheckingExistence, tfsesv2.ResNameEmailIdentity, rs.Primary.ID, err) } if out == nil || out.FeedbackForwardingStatus != emailForwardingEnabled { - return create.Error(names.SESV2, create.ErrActionCheckingExistence, tfsesv2.ResNameEmailIdentityFeedbackAttributes, rs.Primary.ID, err) + return create.Error(names.SESV2, create.ErrActionCheckingExistence, tfsesv2.ResNameEmailIdentityFeedbackAttributes, rs.Primary.ID, errors.New("feedback attributes not set")) } return nil From 61a747af6b10e25d7433fd70d0c0bcaa44997202 Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Fri, 11 Nov 2022 11:46:55 -0500 Subject: [PATCH 13/13] r/aws_sesv2_email_identity_mail_from_attributes: use enum validate func --- .../email_identity_mail_from_attributes.go | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/internal/service/sesv2/email_identity_mail_from_attributes.go b/internal/service/sesv2/email_identity_mail_from_attributes.go index bddcc1e2883..6466d83d9e3 100644 --- a/internal/service/sesv2/email_identity_mail_from_attributes.go +++ b/internal/service/sesv2/email_identity_mail_from_attributes.go @@ -10,9 +10,9 @@ import ( "github.com/aws/aws-sdk-go-v2/service/sesv2/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/enum" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -32,10 +32,10 @@ func ResourceEmailIdentityMailFromAttributes() *schema.Resource { Schema: map[string]*schema.Schema{ "behavior_on_mx_failure": { - Type: schema.TypeString, - Optional: true, - Default: string(types.BehaviorOnMxFailureUseDefaultValue), - ValidateFunc: validation.StringInSlice(behaviorOnMXFailureValues(types.BehaviorOnMxFailure("").Values()), false), + Type: schema.TypeString, + Optional: true, + Default: string(types.BehaviorOnMxFailureUseDefaultValue), + ValidateDiagFunc: enum.Validate[types.BehaviorOnMxFailure](), }, "email_identity": { Type: schema.TypeString, @@ -168,13 +168,3 @@ func resourceEmailIdentityMailFromAttributesDelete(ctx context.Context, d *schem return nil } - -func behaviorOnMXFailureValues(in []types.BehaviorOnMxFailure) []string { - var out []string - - for _, v := range in { - out = append(out, string(v)) - } - - return out -}