Skip to content

Commit

Permalink
feat: add module code
Browse files Browse the repository at this point in the history
  • Loading branch information
RubenMakandra committed Sep 11, 2024
1 parent 9516456 commit 22180a4
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 0 deletions.
63 changes: 63 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
locals {
dkim_verification_records = { for dkim_token in aws_sesv2_email_identity.ses_domain.dkim_signing_attributes[0].tokens :
"${dkim_token}._domainkey.${var.domain}" => "${dkim_token}.dkim.amazonses.com."
}
}

resource "aws_sesv2_email_identity" "ses_domain" {
email_identity = var.domain
configuration_set_name = var.configuration_set_name
}

resource "aws_route53_record" "amazonses_dkim_record" {
count = anytrue([var.verify_domain, var.verify_dkim]) ? 3 : 0

zone_id = var.zone_id
name = "${element(aws_sesv2_email_identity.ses_domain.dkim_signing_attributes[0].tokens, count.index)}._domainkey.${var.domain}"
type = "CNAME"
ttl = "1800"
records = ["${element(aws_sesv2_email_identity.ses_domain.dkim_signing_attributes[0].tokens, count.index)}.dkim.amazonses.com"]
}

resource "aws_route53_record" "amazonses_dmarc_record" {
count = var.configure_dmarc ? 1 : 0

zone_id = var.zone_id
name = "_dmarc.${aws_sesv2_email_identity.ses_domain.email_identity}"
type = "TXT"
ttl = "3600"
records = ["v=DMARC1; p=${var.dmarc_action};"]
}

resource "aws_sesv2_email_identity_mail_from_attributes" "custom_mail_from" {
count = length(var.custom_from_subdomain) > 0 ? 1 : 0

email_identity = aws_sesv2_email_identity.ses_domain.email_identity
behavior_on_mx_failure = var.custom_from_behavior_on_mx_failure
mail_from_domain = "${one(var.custom_from_subdomain)}.${aws_sesv2_email_identity.ses_domain.email_identity}"
}

resource "aws_route53_record" "amazonses_spf_record" {
count = var.create_spf_record ? 1 : 0

zone_id = var.zone_id
name = length(var.custom_from_subdomain) > 0 ? join("", [aws_sesv2_email_identity_mail_from_attributes.custom_mail_from[0].mail_from_domain]) : aws_sesv2_email_identity.ses_domain.email_identity
type = "TXT"
ttl = "3600"
records = ["v=spf1 include:amazonses.com -all"]
}

data "aws_region" "current" {
count = length(var.custom_from_subdomain) > 0 ? 1 : 0
}

resource "aws_route53_record" "custom_mail_from_mx" {
count = length(var.custom_from_subdomain) > 0 ? 1 : 0

zone_id = var.zone_id
name = join("", aws_sesv2_email_identity_mail_from_attributes.custom_mail_from[*].mail_from_domain)
type = "MX"
ttl = "600"
records = ["10 feedback-smtp.${join("", data.aws_region.current[*].name)}.amazonses.com"]
}

23 changes: 23 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
output "ses_domain_identity_arn" {
value = try(aws_sesv2_email_identity.ses_domain.arn, "")
description = "The ARN of the SES domain identity"
}

output "ses_dkim_tokens" {
value = try(aws_sesv2_email_identity.ses_domain.dkim_signing_attributes[0].tokens, "")
description = "A list of DKIM Tokens which, when added to the DNS Domain as CNAME records, allows for receivers to verify that emails were indeed authorized by the domain owner."
}

output "spf_record" {
value = try(aws_route53_record.amazonses_spf_record[0].fqdn, "")
description = "The SPF record for the domain. This is a TXT record that should be added to the domain's DNS settings to allow SES to send emails on behalf of the domain."
}

output "custom_from_domain" {
value = try(join("", aws_sesv2_email_identity_mail_from_attributes.custom_mail_from[*].mail_from_domain))
description = "The custom mail FROM domain"
}

output "dmarc" {
value = aws_sesv2_email_identity.ses_domain.email_identity
}
76 changes: 76 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
variable "domain" {
description = "The domain or email address to create the SES identity for."
type = string
}

variable "zone_id" {
type = string
description = "Route53 parent zone ID. If provided (not empty), the module will create Route53 DNS records used for verification"
default = ""
}

variable "verify_domain" {
type = bool
description = "If provided the module will create Route53 DNS records used for DKIM verification."
default = false
}

variable "verify_dkim" {
type = bool
description = "If provided the module will create Route53 DNS records used for DKIM verification."
default = false
}

variable "create_spf_record" {
type = bool
description = "If provided the module will create an SPF record for `domain`."
default = false
}

variable "custom_from_subdomain" {
type = list(string)
description = "If provided the module will create a custom subdomain for the `From` address."
default = []
nullable = false

validation {
condition = length(var.custom_from_subdomain) <= 1
error_message = "Only one custom_from_subdomain is allowed."
}

validation {
condition = length(var.custom_from_subdomain) > 0 ? can(regex("^[a-zA-Z0-9-]+$", var.custom_from_subdomain[0])) : true
error_message = "The custom_from_subdomain must be a valid subdomain."
}
}

variable "custom_from_behavior_on_mx_failure" {
type = string
description = "The behaviour of the custom_from_subdomain when the MX record is not found. Defaults to `UseDefaultValue`."
default = "USE_DEFAULT_VALUE"

validation {
condition = contains(["USE_DEFAULT_VALUE", "REJECT_MESSAGE"], var.custom_from_behavior_on_mx_failure)
error_message = "The custom_from_behavior_on_mx_failure must be `USE_DEFAULT_VALUE` or `REJECT_MESSAGE`."
}
}

variable "configuration_set_name" {
description = "Name of the configuration set to use for the identity"
type = string
default = null
}

variable "configure_dmarc" {
type = bool
default = false
}

variable "dmarc_action" {
type = string
validation {
condition = contains(["none", "quarantine", "reject"], var.dmarc_action)
error_message = "The DMARC action has to be one of [\"none\", \"quarantine\", \"reject\"]"
}
default = "none"
}
10 changes: 10 additions & 0 deletions versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.2.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.37.0"
}
}
}

0 comments on commit 22180a4

Please sign in to comment.