From 66368948d1ff4f09d52426693dc861b962819943 Mon Sep 17 00:00:00 2001 From: Script47 Date: Sun, 4 Jan 2026 00:09:30 +0000 Subject: [PATCH] feat(ses-domain-identity): add module --- ses-domain-identity/README.md | 37 ++++++++++++++++++++++++++++++++ ses-domain-identity/data.tf | 4 ++++ ses-domain-identity/providers.tf | 10 +++++++++ ses-domain-identity/route53.tf | 25 +++++++++++++++++++++ ses-domain-identity/ses.tf | 8 +++++++ ses-domain-identity/variables.tf | 33 ++++++++++++++++++++++++++++ 6 files changed, 117 insertions(+) create mode 100644 ses-domain-identity/README.md create mode 100644 ses-domain-identity/data.tf create mode 100644 ses-domain-identity/providers.tf create mode 100644 ses-domain-identity/route53.tf create mode 100644 ses-domain-identity/ses.tf create mode 100644 ses-domain-identity/variables.tf diff --git a/ses-domain-identity/README.md b/ses-domain-identity/README.md new file mode 100644 index 0000000..d0456df --- /dev/null +++ b/ses-domain-identity/README.md @@ -0,0 +1,37 @@ +# SES Domain Identity + +## About + +This module allows you to setup domain identification for SES with the following features: + +- Domain verification +- DKIM +- DMARC + +## Usage + +See `variables.tf` for the full argument reference. + +```hcl +module "ses_doamin_identity" { + source = "github.com/script47/aws-tf-modules/ses-domain-identity" + + hosted_zone = "my-hosted-zone" + domain = "example.org" + + domain_verification = { + ttl = 600 + } + + dkim = { + enabled = true + ttl = 600 + } + + dmarc = { + enabled = true + policy = "v=DMARC1; p=reject;" + ttl = 600 + } +} +``` diff --git a/ses-domain-identity/data.tf b/ses-domain-identity/data.tf new file mode 100644 index 0000000..f58b9c8 --- /dev/null +++ b/ses-domain-identity/data.tf @@ -0,0 +1,4 @@ +data "aws_route53_zone" "hosted_zone" { + name = var.hosted_zone + private_zone = false +} diff --git a/ses-domain-identity/providers.tf b/ses-domain-identity/providers.tf new file mode 100644 index 0000000..5ec6724 --- /dev/null +++ b/ses-domain-identity/providers.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.13" + + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 6" + } + } +} diff --git a/ses-domain-identity/route53.tf b/ses-domain-identity/route53.tf new file mode 100644 index 0000000..cbd32b4 --- /dev/null +++ b/ses-domain-identity/route53.tf @@ -0,0 +1,25 @@ +resource "aws_route53_record" "domain_verification" { + zone_id = data.aws_route53_zone.hosted_zone.zone_id + name = "_amazonses.${var.domain}" + type = "TXT" + ttl = var.domain_verification.ttl + records = [aws_ses_domain_identity.this.verification_token] +} + +resource "aws_route53_record" "dkim" { + count = var.dkim.enabled ? 3 : 0 + zone_id = data.aws_route53_zone.hosted_zone.zone_id + name = "${aws_ses_domain_dkim.this[0].dkim_tokens[count.index]}._domainkey.${var.domain}" + type = "CNAME" + ttl = var.dkim.ttl + records = ["${aws_ses_domain_dkim.this[0].dkim_tokens[count.index]}.dkim.amazonses.com"] +} + +resource "aws_route53_record" "dmarc" { + count = var.dmarc.enabled ? 1 : 0 + zone_id = data.aws_route53_zone.hosted_zone.zone_id + name = "_dmarc.${var.domain}" + type = "TXT" + ttl = var.dmarc.ttl + records = [var.dmarc.policy] +} \ No newline at end of file diff --git a/ses-domain-identity/ses.tf b/ses-domain-identity/ses.tf new file mode 100644 index 0000000..0138cf1 --- /dev/null +++ b/ses-domain-identity/ses.tf @@ -0,0 +1,8 @@ +resource "aws_ses_domain_identity" "this" { + domain = var.domain +} + +resource "aws_ses_domain_dkim" "this" { + count = var.dkim.enabled ? 1 : 0 + domain = aws_ses_domain_identity.this.domain +} diff --git a/ses-domain-identity/variables.tf b/ses-domain-identity/variables.tf new file mode 100644 index 0000000..819a7ed --- /dev/null +++ b/ses-domain-identity/variables.tf @@ -0,0 +1,33 @@ +variable "hosted_zone" { + type = string + description = "The name of the hosted zone" +} + +variable "domain" { + type = string + description = "The domain name" +} + +variable "domain_verification" { + type = object({ + ttl = optional(number, 600) + }) + default = {} +} + +variable "dkim" { + type = object({ + enabled = optional(bool, true) + ttl = optional(number, 600) + }) + default = {} +} + +variable "dmarc" { + type = object({ + enabled = optional(bool, false) + policy = optional(string, "v=DMARC1; p=reject;") + ttl = optional(number, 600) + }) + default = {} +}