Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/labeler.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
- any-glob-to-any-file:
- modules/msk-cluster/**/*

":floppy_disk: ses-identity":
- changed-files:
- any-glob-to-any-file:
- modules/ses-identity/**/*

":floppy_disk: sns-fifo-topic":
- changed-files:
- any-glob-to-any-file:
Expand Down
3 changes: 3 additions & 0 deletions .github/labels.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
- color: "fbca04"
description: "This issue or pull request is related to msk-cluster module."
name: ":floppy_disk: msk-cluster"
- color: "fbca04"
description: "This issue or pull request is related to ses-identity module."
name: ":floppy_disk: ses-identity"
- color: "fbca04"
description: "This issue or pull request is related to sns-fifo-topic module."
name: ":floppy_disk: sns-fifo-topic"
Expand Down
24 changes: 23 additions & 1 deletion .tflint.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,30 @@ rule "terraform_unused_required_providers" {

plugin "aws" {
source = "github.com/terraform-linters/tflint-ruleset-aws"
version = "0.38.0"
version = "0.39.0"

enabled = true
deep_check = false
}

# INFO: Wrong validation
rule "aws_route53_record_invalid_health_check_id" {
enabled = false
}
# INFO: Wrong validation
rule "aws_route53_record_invalid_name" {
enabled = false
}
# INFO: Wrong validation
rule "aws_route53_record_invalid_set_identifier" {
enabled = false
}
# INFO: Wrong validation
rule "aws_route53_record_invalid_type" {
enabled = false
}
# INFO: Wrong validation
rule "aws_route53_record_invalid_zone_id" {
enabled = false
}

7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Terraform module which creates messaging related resources on AWS.
- [eventbridge-event-bus](./modules/eventbridge-event-bus)
- [eventbridge-rule](./modules/eventbridge-rule)
- [msk-cluster](./modules/msk-cluster)
- [ses-identity](./modules/ses-identity)
- [sns-fifo-topic](./modules/sns-fifo-topic)
- [sns-standard-topic](./modules/sns-standard-topic)

Expand All @@ -22,6 +23,10 @@ Terraform Modules from [this package](https://github.com/tedilabs/terraform-aws-
- Rule
- **AWS MSK (Managed Streaming for Apache Kafka)**
- Cluster
- **AWS SES (Simple Email Service)**
- Identity
- Domain Identity
- Email Identity
- **AWS SNS (Simple Notification Service)**
- FIFO Topic
- Standard Topic
Expand All @@ -46,4 +51,4 @@ Like this project? Follow the repository on [GitHub](https://github.com/tedilabs

Provided under the terms of the [Apache License](LICENSE).

Copyright © 2023, [Byungjin Park](https://www.posquit0.com).
Copyright © 2023-2025, [Byungjin Park](https://www.posquit0.com).
59 changes: 59 additions & 0 deletions modules/ses-identity/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# ses-identity

This module creates following resources.

- `aws_sesv2_email_identity`
- `aws_route53_record` (optional)

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.10 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.84 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.98.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_resource_group"></a> [resource\_group](#module\_resource\_group) | tedilabs/misc/aws//modules/resource-group | ~> 0.10.0 |

## Resources

| Name | Type |
|------|------|
| [aws_route53_record.dkim](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
| [aws_sesv2_email_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sesv2_email_identity) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_name"></a> [name](#input\_name) | (Required) The domain name of the SES domain identity. | `string` | n/a | yes |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN of the SES identity. |
| <a name="output_configuration_set"></a> [configuration\_set](#output\_configuration\_set) | The configuration set to use by default when sending from this identity. |
| <a name="output_dkim"></a> [dkim](#output\_dkim) | The configuration for the DKIM. |
| <a name="output_id"></a> [id](#output\_id) | The ID of the SES identity. |
| <a name="output_name"></a> [name](#output\_name) | The domain name for the SES identity. |
| <a name="output_status"></a> [status](#output\_status) | The status of the SES identity. |
| <a name="output_type"></a> [type](#output\_type) | The type of the SES identity. |
<!-- END_TF_DOCS -->
60 changes: 60 additions & 0 deletions modules/ses-identity/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
locals {
metadata = {
package = "terraform-aws-messaging"
version = trimspace(file("${path.module}/../../VERSION"))
module = basename(path.module)
name = var.name
}
module_tags = var.module_tags_enabled ? {
"module.terraform.io/package" = local.metadata.package
"module.terraform.io/version" = local.metadata.version
"module.terraform.io/name" = local.metadata.module
"module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}"
"module.terraform.io/instance" = local.metadata.name
} : {}
}

locals {
signing_key_type = {
"RSA_1024" = "RSA_1024_BIT"
"RSA_2048" = "RSA_2048_BIT"
}
signing_key_type_reverse = {
for k, v in local.signing_key_type : v => k
}
}

###################################################
# SES Domain Identity
###################################################

resource "aws_sesv2_email_identity" "this" {
email_identity = var.name
configuration_set_name = var.configuration_set

dkim_signing_attributes {
# Easy DKIM
next_signing_key_length = (var.dkim.type == "EASY_DKIM"
? local.signing_key_type[var.dkim.signing_key_type]
: null
)

# BYODKIM
domain_signing_private_key = (var.dkim.type == "BYODKIM"
? var.dkim.private_key
: null
)
domain_signing_selector = (var.dkim.type == "BYODKIM"
? var.dkim.selector_name
: null
)
}

tags = merge(
{
"Name" = local.metadata.name
},
local.module_tags,
var.tags,
)
}
65 changes: 65 additions & 0 deletions modules/ses-identity/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
output "arn" {
description = "The ARN of the SES identity."
value = aws_sesv2_email_identity.this.arn
}

output "id" {
description = "The ID of the SES identity."
value = aws_sesv2_email_identity.this.id
}

output "status" {
description = "The status of the SES identity."
value = aws_sesv2_email_identity.this.verified_for_sending_status ? "VERIFIED" : "PENDING"
}

output "name" {
description = "The domain name for the SES identity."
value = aws_sesv2_email_identity.this.email_identity
}

output "type" {
description = "The type of the SES identity."
value = aws_sesv2_email_identity.this.identity_type
}

output "configuration_set" {
description = "The configuration set to use by default when sending from this identity."
value = aws_sesv2_email_identity.this.configuration_set_name
}

output "dkim" {
description = "The configuration for the DKIM."
value = {
type = var.dkim.type
status = one(aws_sesv2_email_identity.this.dkim_signing_attributes[*].status)
current_signing_key_type = local.signing_key_type_reverse[one(aws_sesv2_email_identity.this.dkim_signing_attributes[*].current_signing_key_length)]
signing_key_type = local.signing_key_type_reverse[one(aws_sesv2_email_identity.this.dkim_signing_attributes[*].next_signing_key_length)]
selector_name = one(aws_sesv2_email_identity.this.dkim_signing_attributes[*].domain_signing_selector)
origin = one(aws_sesv2_email_identity.this.dkim_signing_attributes[*].signing_attributes_origin)
last_key_generated_at = one(aws_sesv2_email_identity.this.dkim_signing_attributes[*].last_key_generation_timestamp)

verification = {
enabled = var.dkim.verification.enabled
zone = {
id = var.dkim.verification.zone_id
}
records = [
for record in aws_route53_record.dkim : {
name = record.name
value = record.records
type = record.type
ttl = record.ttl
}
]
}
}
}

# output "debug" {
# value = {
# for k, v in aws_sesv2_email_identity.this :
# k => v
# if !contains(["arn", "id", "email_identity", "identity_type", "tags", "tags_all", "dkim_signing_attributes", "verified_for_sending_status", "configuration_set_name"], k)
# }
# }
31 changes: 31 additions & 0 deletions modules/ses-identity/resource-group.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
locals {
resource_group_name = (var.resource_group_name != ""
? var.resource_group_name
: join(".", [
local.metadata.package,
local.metadata.module,
replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"),
])
)
}


module "resource_group" {
source = "tedilabs/misc/aws//modules/resource-group"
version = "~> 0.10.0"

count = (var.resource_group_enabled && var.module_tags_enabled) ? 1 : 0

name = local.resource_group_name
description = var.resource_group_description

query = {
resource_tags = local.module_tags
}

module_tags_enabled = false
tags = merge(
local.module_tags,
var.tags,
)
}
18 changes: 18 additions & 0 deletions modules/ses-identity/route53.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
###################################################
# DKIM Verification
###################################################

resource "aws_route53_record" "dkim" {
for_each = (var.dkim.type == "EASY_DKIM" && var.dkim.verification.enabled
? toset(aws_sesv2_email_identity.this.dkim_signing_attributes[0].tokens)
: []
)

zone_id = var.dkim.verification.zone_id
name = "${each.key}._domainkey.${aws_sesv2_email_identity.this.email_identity}"
type = "CNAME"
records = ["${each.key}.dkim.amazonses.com"]

ttl = "600"
allow_overwrite = true
}
Loading