Skip to content

Commit 8d58228

Browse files
committed
feat(ses-identity): support policies, custom mail from, email feedback forwarding
1 parent 25d9c9b commit 8d58228

File tree

6 files changed

+150
-70
lines changed

6 files changed

+150
-70
lines changed

modules/ses-identity/README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
This module creates following resources.
44

55
- `aws_sesv2_email_identity`
6+
- `aws_sesv2_email_identity_feedback_attributes`
7+
- `aws_sesv2_email_identity_mail_from_attributes` (optional)
8+
- `aws_sesv2_email_identity_policy` (optional)
69
- `aws_route53_record` (optional)
710

811
<!-- BEGIN_TF_DOCS -->
@@ -31,15 +34,21 @@ This module creates following resources.
3134
|------|------|
3235
| [aws_route53_record.dkim](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
3336
| [aws_sesv2_email_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sesv2_email_identity) | resource |
37+
| [aws_sesv2_email_identity_feedback_attributes.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sesv2_email_identity_feedback_attributes) | resource |
38+
| [aws_sesv2_email_identity_mail_from_attributes.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sesv2_email_identity_mail_from_attributes) | resource |
39+
| [aws_sesv2_email_identity_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sesv2_email_identity_policy) | resource |
3440

3541
## Inputs
3642

3743
| Name | Description | Type | Default | Required |
3844
|------|-------------|------|---------|:--------:|
3945
| <a name="input_name"></a> [name](#input\_name) | (Required) The domain name of the SES domain identity. | `string` | n/a | yes |
4046
| <a name="input_configuration_set"></a> [configuration\_set](#input\_configuration\_set) | (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. | `string` | `null` | no |
41-
| <a name="input_dkim"></a> [dkim](#input\_dkim) | (Optional) The configuration for the DKIM (DomainKeys Identified Mail). `dkim` as defined below.<br/> (Optional) `type` - Whether to use either Easy DKIM (`EASY_DKIM`) or Bring Your Own DKIM (`BYODKIM`), and depending on your choice, you'll have to configure the signing key length of the private key. Valid values are `EASY_DKIM` and `BYODKIM`. Defaults to `EASY_DKIM`.<br/> (Optional) `signing_key_type` - The key type of the future DKIM key pair to be generated. This can be changed at most once per day. The signing key length of the private key. Valid values are `RSA_1024` and `RSA_2048`. Defaults to `RSA_2048`. Only required if `type` is `EASY_DKIM`.<br/> (Optional) `private_key` - A private key that's used to generate a DKIM signature. The private key must use 1024 or 2048-bit RSA encryption, and must be encoded using base64 encoding. Only required if `type` is `BYODKIM`.<br/> (Optional) `selector_name` - A string that's used to identify a public key in the DNS configuration for a domain. Only required if `type` is `BYODKIM`.<br/> (Optional) `verification` - A configuration for the DKIM verification. `verification` as defined below.<br/> (Optional) `enabled` - Whether to process DKIM verification by creating the necessary domain records in the module. Defaults to `false`.<br/> (Optional) `zone_id` - The ID of Hosted Zone to automatically manage the records for DKIM verification. | <pre>object({<br/> type = optional(string, "EASY_DKIM")<br/> signing_key_type = optional(string, "RSA_2048")<br/> private_key = optional(string)<br/> selector_name = optional(string)<br/> verification = optional(object({<br/> enabled = optional(bool, false)<br/> zone_id = optional(string)<br/> }))<br/> })</pre> | `{}` | no |
47+
| <a name="input_custom_mail_from"></a> [custom\_mail\_from](#input\_custom\_mail\_from) | (Optional) The configuration for Custom Mail From. Configuring a custom MAIL FROM domain for messages sent from this identity enables the MAIL FROM address to align with the From address. Domain alignment must be achieved in order to be DMARC compliant. `custom_mail_from` as defined below.<br/> (Optional) `enabled` - Whether to enable custom mail from.<br/> (Optional) `domain` - The custom MAIL FROM domain that you want the verified identity to use. The MAIL FROM domain must meet the following criteria:<br/> - It has to be a subdomain of the verified identity.<br/> - It can't be used to receive email.<br/> - It can't be used in a "From" address if the MAIL FROM domain is a destination for feedback forwarding emails.<br/> (Optional) `behavior_on_mx_failure` - The action to take if the MAIL FROM domain is not found or not verified. Valid values are `REJECT_MESSAGE` and `USE_DEFAULT_VALUE`. Defaults to `REJECT_MESSAGE`. | <pre>object({<br/> enabled = optional(bool, false)<br/> domain = optional(string, "")<br/> behavior_on_mx_failure = optional(string, "REJECT_MESSAGE")<br/> })</pre> | `{}` | no |
48+
| <a name="input_dkim"></a> [dkim](#input\_dkim) | (Optional) The configuration for the DKIM (DomainKeys Identified Mail). `dkim` as defined below.<br/> (Optional) `type` - Whether to use either Easy DKIM (`EASY_DKIM`) or Bring Your Own DKIM (`BYODKIM`), and depending on your choice, you'll have to configure the signing key length of the private key. Valid values are `EASY_DKIM` and `BYODKIM`. Defaults to `EASY_DKIM`.<br/> (Optional) `signing_key_type` - The key type of the future DKIM key pair to be generated. This can be changed at most once per day. The signing key length of the private key. Valid values are `RSA_1024` and `RSA_2048`. Defaults to `RSA_2048`. Only required if `type` is `EASY_DKIM`.<br/> (Optional) `private_key` - A private key that's used to generate a DKIM signature. The private key must use 1024 or 2048-bit RSA encryption, and must be encoded using base64 encoding. Only required if `type` is `BYODKIM`.<br/> (Optional) `selector_name` - A string that's used to identify a public key in the DNS configuration for a domain. Only required if `type` is `BYODKIM`.<br/>variable "dkim" {<br/> description = <<EOF<br/> (Optional) The configuration for the DKIM (DomainKeys Identified Mail). `dkim` as defined below.<br/> (Optional) `type` - Whether to use either Easy DKIM (`EASY_DKIM`) or Bring Your Own DKIM (`BYODKIM`), and depending on your choice, you'll have to configure the signing key length of the private key. Valid values are `EASY_DKIM` and `BYODKIM`. Defaults to `EASY_DKIM`.<br/> (Optional) `signing_key_type` - The key type of the future DKIM key pair to be generated. This can be changed at most once per day. The signing key length of the private key. Valid values are `RSA_1024` and `RSA_2048`. Defaults to `RSA_2048`. Only required if `type` is `EASY_DKIM`.<br/> (Optional) `private_key` - A private key that's used to generate a DKIM signature. The private key must use 1024 or 2048-bit RSA encryption, and must be encoded using base64 encoding. Only required if `type` is `BYODKIM`.<br/> (Optional) `selector_name` - A string that's used to identify a public key in the DNS configuration for a domain. Only required if `type` is `BYODKIM`.<br/> (Optional) `verification` - A configuration for the DKIM verification. `verification` as defined below.<br/> (Optional) `enabled` - Whether to process DKIM verification by creating the necessary domain records in the module. Defaults to `false`.<br/> (Optional) `zone_id` - The ID of Hosted Zone to automatically manage the records for DKIM verification. | <pre>object({<br/> type = optional(string, "EASY_DKIM")<br/> signing_key_type = optional(string, "RSA_2048")<br/> private_key = optional(string)<br/> selector_name = optional(string)<br/> verification = optional(object({<br/> enabled = optional(bool, false)<br/> zone_id = optional(string)<br/> }))<br/> })</pre> | `{}` | no |
49+
| <a name="input_email_feedback_forwarding"></a> [email\_feedback\_forwarding](#input\_email\_feedback\_forwarding) | (Optional) The configuration for Email Feedback Forwarding. `email_feedback_forwarding` as defined below.<br/> (Optional) `enabled` - Whether to enable email feedback forwarding. Amazon SES will automatically notify you by email when a bounce or a complaint event occurs. If you have another method in place, you can disable this feature to avoid receiving multiple notifications for the same event. Defaults to `true`. | <pre>object({<br/> enabled = optional(bool, true)<br/> })</pre> | `{}` | no |
4250
| <a name="input_module_tags_enabled"></a> [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no |
51+
| <a name="input_policies"></a> [policies](#input\_policies) | (Optional) A map of authorization policies for the SES identity. The authorization policy is a JSON document that you attach to an identity to specify what API actions you're allowing or denying for that identity, and under which conditions. Each key is the name of the policy, and the value is the policy document. | `map(string)` | `{}` | no |
4352
| <a name="input_resource_group_description"></a> [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no |
4453
| <a name="input_resource_group_enabled"></a> [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no |
4554
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no |
@@ -51,9 +60,12 @@ This module creates following resources.
5160
|------|-------------|
5261
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN of the SES identity. |
5362
| <a name="output_configuration_set"></a> [configuration\_set](#output\_configuration\_set) | The configuration set to use by default when sending from this identity. |
63+
| <a name="output_custom_mail_from"></a> [custom\_mail\_from](#output\_custom\_mail\_from) | The configuration for the custom mail from. |
5464
| <a name="output_dkim"></a> [dkim](#output\_dkim) | The configuration for the DKIM. |
65+
| <a name="output_email_feedback_forwarding"></a> [email\_feedback\_forwarding](#output\_email\_feedback\_forwarding) | The configuration for the email feedback forwarding. |
5566
| <a name="output_id"></a> [id](#output\_id) | The ID of the SES identity. |
5667
| <a name="output_name"></a> [name](#output\_name) | The domain name for the SES identity. |
68+
| <a name="output_policies"></a> [policies](#output\_policies) | A set of authorization policy names for the SES identity. |
5769
| <a name="output_status"></a> [status](#output\_status) | The status of the SES identity. |
5870
| <a name="output_type"></a> [type](#output\_type) | The type of the SES identity. |
5971
<!-- END_TF_DOCS -->

modules/ses-identity/main.tf

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ locals {
2222
signing_key_type_reverse = {
2323
for k, v in local.signing_key_type : v => k
2424
}
25+
identity_type = strcontains(var.name, "@") ? "EMAIL_ADDRESS" : "DOMAIN"
2526
}
2627

28+
2729
###################################################
2830
# SES Domain Identity
2931
###################################################
@@ -32,22 +34,26 @@ resource "aws_sesv2_email_identity" "this" {
3234
email_identity = var.name
3335
configuration_set_name = var.configuration_set
3436

35-
dkim_signing_attributes {
36-
# Easy DKIM
37-
next_signing_key_length = (var.dkim.type == "EASY_DKIM"
38-
? local.signing_key_type[var.dkim.signing_key_type]
39-
: null
40-
)
41-
42-
# BYODKIM
43-
domain_signing_private_key = (var.dkim.type == "BYODKIM"
44-
? var.dkim.private_key
45-
: null
46-
)
47-
domain_signing_selector = (var.dkim.type == "BYODKIM"
48-
? var.dkim.selector_name
49-
: null
50-
)
37+
dynamic "dkim_signing_attributes" {
38+
for_each = local.identity_type == "DOMAIN" ? ["go"] : []
39+
40+
content {
41+
# Easy DKIM
42+
next_signing_key_length = (var.dkim.type == "EASY_DKIM"
43+
? local.signing_key_type[var.dkim.signing_key_type]
44+
: null
45+
)
46+
47+
# BYODKIM
48+
domain_signing_private_key = (var.dkim.type == "BYODKIM"
49+
? var.dkim.private_key
50+
: null
51+
)
52+
domain_signing_selector = (var.dkim.type == "BYODKIM"
53+
? var.dkim.selector_name
54+
: null
55+
)
56+
}
5157
}
5258

5359
tags = merge(
@@ -57,4 +63,28 @@ resource "aws_sesv2_email_identity" "this" {
5763
local.module_tags,
5864
var.tags,
5965
)
66+
}
67+
68+
69+
###################################################
70+
# Email Feedback Forwarding
71+
###################################################
72+
73+
resource "aws_sesv2_email_identity_feedback_attributes" "this" {
74+
email_identity = aws_sesv2_email_identity.this.email_identity
75+
email_forwarding_enabled = var.email_feedback_forwarding.enabled
76+
}
77+
78+
79+
###################################################
80+
# Custom Mail From
81+
###################################################
82+
83+
resource "aws_sesv2_email_identity_mail_from_attributes" "this" {
84+
count = var.custom_mail_from.enabled ? 1 : 0
85+
86+
email_identity = aws_sesv2_email_identity.this.email_identity
87+
88+
mail_from_domain = var.custom_mail_from.domain
89+
behavior_on_mx_failure = var.custom_mail_from.behavior_on_mx_failure
6090
}

modules/ses-identity/outputs.tf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ output "configuration_set" {
2828
value = aws_sesv2_email_identity.this.configuration_set_name
2929
}
3030

31+
output "policies" {
32+
description = "A set of authorization policy names for the SES identity."
33+
value = keys(aws_sesv2_email_identity_policy.this)
34+
}
35+
3136
output "dkim" {
3237
description = "The configuration for the DKIM."
3338
value = {
@@ -56,6 +61,22 @@ output "dkim" {
5661
}
5762
}
5863

64+
output "email_feedback_forwarding" {
65+
description = "The configuration for the email feedback forwarding."
66+
value = {
67+
enabled = aws_sesv2_email_identity_feedback_attributes.this.email_forwarding_enabled
68+
}
69+
}
70+
71+
output "custom_mail_from" {
72+
description = "The configuration for the custom mail from."
73+
value = {
74+
enabled = var.custom_mail_from.enabled
75+
domain = one(aws_sesv2_email_identity_mail_from_attributes.this[*].mail_from_domain)
76+
behavior_on_mx_failure = one(aws_sesv2_email_identity_mail_from_attributes.this[*].behavior_on_mx_failure)
77+
}
78+
}
79+
5980
# output "debug" {
6081
# value = {
6182
# for k, v in aws_sesv2_email_identity.this :

modules/ses-identity/policies.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
###################################################
2+
# Authorization Policies
3+
###################################################
4+
5+
resource "aws_sesv2_email_identity_policy" "this" {
6+
for_each = var.policies
7+
8+
email_identity = aws_sesv2_email_identity.this.email_identity
9+
10+
policy_name = each.key
11+
policy = each.value
12+
}

modules/ses-identity/route53.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
###################################################
44

55
resource "aws_route53_record" "dkim" {
6-
for_each = (var.dkim.type == "EASY_DKIM" && var.dkim.verification.enabled
6+
for_each = (aws_sesv2_email_identity.this.identity_type == "DOMAIN" && var.dkim.type == "EASY_DKIM" && var.dkim.verification.enabled
77
? toset(aws_sesv2_email_identity.this.dkim_signing_attributes[0].tokens)
88
: []
99
)

0 commit comments

Comments
 (0)