diff --git a/.changelog/32026.txt b/.changelog/32026.txt new file mode 100644 index 00000000000..d076a1345b5 --- /dev/null +++ b/.changelog/32026.txt @@ -0,0 +1,7 @@ +```release-note:new-data-source +aws_sesv2_email_identity +``` + +```release-note:new-data-source +aws_sesv2_email_identity_mail_from_attributes +``` diff --git a/internal/service/sesv2/email_identity.go b/internal/service/sesv2/email_identity.go index 0b574d1460f..e0a7002329d 100644 --- a/internal/service/sesv2/email_identity.go +++ b/internal/service/sesv2/email_identity.go @@ -163,6 +163,16 @@ func resourceEmailIdentityCreate(ctx context.Context, d *schema.ResourceData, me return resourceEmailIdentityRead(ctx, d, meta) } +func emailIdentityNameToARN(meta interface{}, emailIdentityName string) string { + return arn.ARN{ + Partition: meta.(*conns.AWSClient).Partition, + Service: "ses", + Region: meta.(*conns.AWSClient).Region, + AccountID: meta.(*conns.AWSClient).AccountID, + Resource: fmt.Sprintf("identity/%s", emailIdentityName), + }.String() +} + func resourceEmailIdentityRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*conns.AWSClient).SESV2Client(ctx) @@ -178,13 +188,7 @@ func resourceEmailIdentityRead(ctx context.Context, d *schema.ResourceData, meta return create.DiagError(names.SESV2, create.ErrActionReading, ResNameEmailIdentity, d.Id(), err) } - arn := arn.ARN{ - Partition: meta.(*conns.AWSClient).Partition, - Service: "ses", - Region: meta.(*conns.AWSClient).Region, - AccountID: meta.(*conns.AWSClient).AccountID, - Resource: fmt.Sprintf("identity/%s", d.Id()), - }.String() + arn := emailIdentityNameToARN(meta, d.Id()) d.Set("arn", arn) d.Set("configuration_set_name", out.ConfigurationSetName) diff --git a/internal/service/sesv2/email_identity_data_source.go b/internal/service/sesv2/email_identity_data_source.go new file mode 100644 index 00000000000..173553fdbac --- /dev/null +++ b/internal/service/sesv2/email_identity_data_source.go @@ -0,0 +1,125 @@ +package sesv2 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @SDKDataSource("aws_sesv2_email_identity") +// @Tags(identifierAttribute="arn") +func DataSourceEmailIdentity() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceEmailIdentityRead, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "configuration_set_name": { + Type: schema.TypeString, + Computed: true, + }, + "dkim_signing_attributes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "current_signing_key_length": { + Type: schema.TypeString, + Computed: true, + }, + "domain_signing_private_key": { + Type: schema.TypeString, + Computed: true, + }, + "domain_signing_selector": { + Type: schema.TypeString, + Computed: true, + }, + "last_key_generation_timestamp": { + Type: schema.TypeString, + Computed: true, + }, + "next_signing_key_length": { + Type: schema.TypeString, + Computed: true, + }, + "signing_attributes_origin": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "tokens": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + "email_identity": { + Type: schema.TypeString, + Required: true, + }, + "identity_type": { + Type: schema.TypeString, + Computed: true, + }, + names.AttrTags: tftags.TagsSchemaComputed(), + "verified_for_sending_status": { + Type: schema.TypeBool, + Computed: true, + }, + }, + } +} + +const ( + DSNameEmailIdentity = "Email Identity Data Source" +) + +func dataSourceEmailIdentityRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).SESV2Client(ctx) + + name := d.Get("email_identity").(string) + + out, err := FindEmailIdentityByID(ctx, conn, name) + if err != nil { + return append(diags, create.DiagError(names.SESV2, create.ErrActionReading, DSNameEmailIdentity, name, err)...) + } + + arn := emailIdentityNameToARN(meta, name) + + d.SetId(name) + d.Set("arn", arn) + d.Set("configuration_set_name", out.ConfigurationSetName) + d.Set("email_identity", name) + + if out.DkimAttributes != nil { + tfMap := flattenDKIMAttributes(out.DkimAttributes) + tfMap["domain_signing_private_key"] = d.Get("dkim_signing_attributes.0.domain_signing_private_key").(string) + tfMap["domain_signing_selector"] = d.Get("dkim_signing_attributes.0.domain_signing_selector").(string) + + if err := d.Set("dkim_signing_attributes", []interface{}{tfMap}); err != nil { + return append(diags, create.DiagError(names.SESV2, create.ErrActionSetting, ResNameEmailIdentity, name, err)...) + } + } else { + d.Set("dkim_signing_attributes", nil) + } + + d.Set("identity_type", string(out.IdentityType)) + d.Set("verified_for_sending_status", out.VerifiedForSendingStatus) + + return diags +} diff --git a/internal/service/sesv2/email_identity_data_source_test.go b/internal/service/sesv2/email_identity_data_source_test.go new file mode 100644 index 00000000000..88a1dde957d --- /dev/null +++ b/internal/service/sesv2/email_identity_data_source_test.go @@ -0,0 +1,56 @@ +package sesv2_test + +import ( + "fmt" + "testing" + + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccSESV2EmailIdentityDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_sesv2_email_identity.test" + dataSourceName := "data.aws_sesv2_email_identity.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.SESV2EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckEmailIdentityDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccEmailIdentityDataSourceConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEmailIdentityExists(ctx, dataSourceName), + resource.TestCheckResourceAttrPair(resourceName, "arn", dataSourceName, "arn"), + resource.TestCheckResourceAttrPair(resourceName, "email_identity", dataSourceName, "email_identity"), + resource.TestCheckResourceAttrPair(resourceName, "dkim_signing_attributes.#", dataSourceName, "dkim_signing_attributes.#"), + resource.TestCheckResourceAttrPair(resourceName, "dkim_signing_attributes.0.current_signing_key_length", dataSourceName, "dkim_signing_attributes.0.current_signing_key_length"), + resource.TestCheckResourceAttrPair(resourceName, "dkim_signing_attributes.0.last_key_generation_timestamp", dataSourceName, "dkim_signing_attributes.0.last_key_generation_timestamp"), + resource.TestCheckResourceAttrPair(resourceName, "dkim_signing_attributes.0.next_signing_key_length", dataSourceName, "dkim_signing_attributes.0.next_signing_key_length"), + resource.TestCheckResourceAttrPair(resourceName, "dkim_signing_attributes.0.signing_attributes_origin", dataSourceName, "dkim_signing_attributes.0.signing_attributes_origin"), + resource.TestCheckResourceAttrPair(resourceName, "dkim_signing_attributes.0.status", dataSourceName, "dkim_signing_attributes.0.status"), + resource.TestCheckResourceAttrPair(resourceName, "dkim_signing_attributes.0.tokens.#", dataSourceName, "dkim_signing_attributes.0.tokens.#"), + resource.TestCheckResourceAttrPair(resourceName, "identity_type", dataSourceName, "identity_type"), + resource.TestCheckResourceAttrPair(resourceName, "verified_for_sending_status", dataSourceName, "verified_for_sending_status"), + ), + }, + }, + }) +} + +func testAccEmailIdentityDataSourceConfig_basic(rName string) string { + return fmt.Sprintf(` +resource "aws_sesv2_email_identity" "test" { + email_identity = %[1]q +} + +data "aws_sesv2_email_identity" "test" { + email_identity = aws_sesv2_email_identity.test.email_identity +} +`, rName) +} diff --git a/internal/service/sesv2/email_identity_mail_from_attributes_data_source.go b/internal/service/sesv2/email_identity_mail_from_attributes_data_source.go new file mode 100644 index 00000000000..318fcf8fff6 --- /dev/null +++ b/internal/service/sesv2/email_identity_mail_from_attributes_data_source.go @@ -0,0 +1,63 @@ +package sesv2 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @SDKDataSource("aws_sesv2_email_identity_mail_from_attributes") +func DataSourceEmailIdentityMailFromAttributes() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceEmailIdentityMailFromAttributesRead, + + Schema: map[string]*schema.Schema{ + "behavior_on_mx_failure": { + Type: schema.TypeString, + Computed: true, + }, + "email_identity": { + Type: schema.TypeString, + Required: true, + }, + "mail_from_domain": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +const ( + DSNameEmailIdentityMailFromAttributes = "Email Identity Mail From Attributes Data Source" +) + +func dataSourceEmailIdentityMailFromAttributesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).SESV2Client(ctx) + + name := d.Get("email_identity").(string) + + out, err := FindEmailIdentityByID(ctx, conn, name) + + if err != nil { + return append(diags, create.DiagError(names.SESV2, create.ErrActionReading, ResNameEmailIdentityMailFromAttributes, name, err)...) + } + + d.SetId(name) + d.Set("email_identity", name) + + 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 diags +} diff --git a/internal/service/sesv2/email_identity_mail_from_attributes_data_source_test.go b/internal/service/sesv2/email_identity_mail_from_attributes_data_source_test.go new file mode 100644 index 00000000000..d1882f1cef3 --- /dev/null +++ b/internal/service/sesv2/email_identity_mail_from_attributes_data_source_test.go @@ -0,0 +1,57 @@ +package sesv2_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go-v2/service/sesv2/types" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccSESV2EmailIdentityMailFromAttributesDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + domain := acctest.RandomDomain() + mailFromDomain1 := domain.Subdomain("test1") + + rName := domain.String() + resourceName := "aws_sesv2_email_identity_mail_from_attributes.test" + dataSourceName := "data.aws_sesv2_email_identity_mail_from_attributes.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.SESV2EndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckEmailIdentityDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccEmailIdentityMailFromAttributesDataSourceConfig_basic(rName, string(types.BehaviorOnMxFailureRejectMessage), mailFromDomain1.String()), + Check: resource.ComposeTestCheckFunc( + testAccCheckEmailIdentityMailFromAttributesExists(ctx, dataSourceName), + resource.TestCheckResourceAttrPair(resourceName, "email_identity", dataSourceName, "email_identity"), + resource.TestCheckResourceAttrPair(resourceName, "behavior_on_mx_failure", dataSourceName, "behavior_on_mx_failure"), + resource.TestCheckResourceAttrPair(resourceName, "mail_from_domain", dataSourceName, "mail_from_domain"), + ), + }, + }, + }) +} + +func testAccEmailIdentityMailFromAttributesDataSourceConfig_basic(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 +} + +data "aws_sesv2_email_identity_mail_from_attributes" "test" { + email_identity = aws_sesv2_email_identity_mail_from_attributes.test.email_identity +} +`, rName, behaviorOnMXFailure, mailFromDomain) +} diff --git a/internal/service/sesv2/service_package_gen.go b/internal/service/sesv2/service_package_gen.go index ec5a4deaf15..8c2ebe58935 100644 --- a/internal/service/sesv2/service_package_gen.go +++ b/internal/service/sesv2/service_package_gen.go @@ -31,6 +31,17 @@ func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePac Factory: DataSourceDedicatedIPPool, TypeName: "aws_sesv2_dedicated_ip_pool", }, + { + Factory: DataSourceEmailIdentity, + TypeName: "aws_sesv2_email_identity", + Tags: &types.ServicePackageResourceTags{ + IdentifierAttribute: "arn", + }, + }, + { + Factory: DataSourceEmailIdentityMailFromAttributes, + TypeName: "aws_sesv2_email_identity_mail_from_attributes", + }, } } diff --git a/website/docs/d/sesv2_email_identity.html.markdown b/website/docs/d/sesv2_email_identity.html.markdown new file mode 100644 index 00000000000..18cf93cd549 --- /dev/null +++ b/website/docs/d/sesv2_email_identity.html.markdown @@ -0,0 +1,43 @@ +--- +subcategory: "SESv2 (Simple Email V2)" +layout: "aws" +page_title: "AWS: aws_sesv2_email_identity" +description: |- + Terraform data source for managing an AWS SESv2 (Simple Email V2) Email Identity. +--- + +# Data Source: aws_sesv2_email_identity + +Terraform data source for managing an AWS SESv2 (Simple Email V2) Email Identity. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_sesv2_email_identity" "example" { + email_identity = "example.com" +} +``` + +## Argument Reference + +The following arguments are required: + +* `email_identity` - (Required) The name of the email identity. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - ARN of the Email Identity. +* `dkim_signing_attributes` - A list of objects that contains at most one element with information about the private key and selector that you want to use to configure DKIM for the identity for Bring Your Own DKIM (BYODKIM) for the identity, or, configures the key length to be used for Easy DKIM. + * `current_signing_key_length` - [Easy DKIM] The key length of the DKIM key pair in use. + * `last_key_generation_timestamp` - [Easy DKIM] The last time a key pair was generated for this identity. + * `next_signing_key_length` - [Easy DKIM] The key length of the future DKIM key pair to be generated. This can be changed at most once per day. + * `signing_attributes_origin` - A string that indicates how DKIM was configured for the identity. `AWS_SES` indicates that DKIM was configured for the identity by using Easy DKIM. `EXTERNAL` indicates that DKIM was configured for the identity by using Bring Your Own DKIM (BYODKIM). + * `status` - Describes whether or not Amazon SES has successfully located the DKIM records in the DNS records for the domain. See the [AWS SES API v2 Reference](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_DkimAttributes.html#SES-Type-DkimAttributes-Status) for supported statuses. + * `tokens` - If you used Easy DKIM to configure DKIM authentication for the domain, then this object contains a set of unique strings that you use to create a set of CNAME records that you add to the DNS configuration for your domain. When Amazon SES detects these records in the DNS configuration for your domain, the DKIM authentication process is complete. If you configured DKIM authentication for the domain by providing your own public-private key pair, then this object contains the selector for the public key. +* `identity_type` - The email identity type. Valid values: `EMAIL_ADDRESS`, `DOMAIN`. +* `tags` - Key-value mapping of resource tags. +* `verified_for_sending_status` - Specifies whether or not the identity is verified. diff --git a/website/docs/d/sesv2_email_identity_mail_from_attributes.html.markdown b/website/docs/d/sesv2_email_identity_mail_from_attributes.html.markdown new file mode 100644 index 00000000000..01e4096b503 --- /dev/null +++ b/website/docs/d/sesv2_email_identity_mail_from_attributes.html.markdown @@ -0,0 +1,38 @@ +--- +subcategory: "SESv2 (Simple Email V2)" +layout: "aws" +page_title: "AWS: aws_sesv2_email_identity_mail_from_attributes" +description: |- + Terraform data source for managing an AWS SESv2 (Simple Email V2) Email Identity Mail From Attributes. +--- + +# Data Source: aws_sesv2_email_identity_mail_from_attributes + +Terraform data source for managing an AWS SESv2 (Simple Email V2) Email Identity Mail From Attributes. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_sesv2_email_identity" "example" { + email_identity = "example.com" +} + +data "aws_sesv2_email_identity_mail_from_attributes" "example" { + email_identity = data.aws_sesv2_email_identity.example.email_identity +} +``` + +## Argument Reference + +The following arguments are required: + +* `email_identity` - (Required) The name of the email identity. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `behavior_on_mx_failure` - 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` - The custom MAIL FROM domain that you want the verified identity to use. diff --git a/website/docs/r/sesv2_email_identity.html.markdown b/website/docs/r/sesv2_email_identity.html.markdown index 01040212391..d59df831e45 100644 --- a/website/docs/r/sesv2_email_identity.html.markdown +++ b/website/docs/r/sesv2_email_identity.html.markdown @@ -58,12 +58,15 @@ resource "aws_sesv2_email_identity" "example" { ## Argument Reference -The following arguments are supported: +The following arguments are required: * `email_identity` - (Required) The email address or domain to verify. + +The following arguments are optional: + * `configuration_set_name` - (Optional) The configuration set to use by default when sending from this identity. Note that any configuration set defined in the email sending request takes precedence. * `dkim_signing_attributes` - (Optional) The configuration of the DKIM authentication settings for an email domain identity. -* `tags` - (Optional) A map of tags to assign to the service. 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. +* `tags` - (Optional) Key-value mapping of resource tags. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ### dkim_signing_attributes @@ -79,7 +82,7 @@ The following arguments are supported: In addition to all arguments above, the following attributes are exported: * `arn` - ARN of the Email Identity. -* `dkim_signing_attributes` - An object that contains information about the private key and selector that you want to use to configure DKIM for the identity for Bring Your Own DKIM (BYODKIM) for the identity, or, configures the key length to be used for Easy DKIM. +* `dkim_signing_attributes` - A list of objects that contains at most one element with information about the private key and selector that you want to use to configure DKIM for the identity for Bring Your Own DKIM (BYODKIM) for the identity, or, configures the key length to be used for Easy DKIM. * `current_signing_key_length` - [Easy DKIM] The key length of the DKIM key pair in use. * `last_key_generation_timestamp` - [Easy DKIM] The last time a key pair was generated for this identity. * `next_signing_key_length` - [Easy DKIM] The key length of the future DKIM key pair to be generated. This can be changed at most once per day. @@ -87,6 +90,7 @@ In addition to all arguments above, the following attributes are exported: * `status` - Describes whether or not Amazon SES has successfully located the DKIM records in the DNS records for the domain. See the [AWS SES API v2 Reference](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_DkimAttributes.html#SES-Type-DkimAttributes-Status) for supported statuses. * `tokens` - If you used Easy DKIM to configure DKIM authentication for the domain, then this object contains a set of unique strings that you use to create a set of CNAME records that you add to the DNS configuration for your domain. When Amazon SES detects these records in the DNS configuration for your domain, the DKIM authentication process is complete. If you configured DKIM authentication for the domain by providing your own public-private key pair, then this object contains the selector for the public key. * `identity_type` - The email identity type. Valid values: `EMAIL_ADDRESS`, `DOMAIN`. +* `tags_all` - Map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). * `verified_for_sending_status` - Specifies whether or not the identity is verified. ## Import