Skip to content

Commit 3676ca3

Browse files
chrisbloerobg-test
andauthored
[PRM-741] Rearchitect SES (#625)
Co-authored-by: robg-test <106234256+robg-test@users.noreply.github.com>
1 parent 5d02d4b commit 3676ca3

22 files changed

Lines changed: 351 additions & 415 deletions

infrastructure/dns_email_auth.tf

Lines changed: 0 additions & 9 deletions
This file was deleted.

infrastructure/iam.tf

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -355,37 +355,37 @@ resource "aws_iam_policy" "s3_document_data_policy_post_document_review_lambda"
355355
})
356356
}
357357

358-
# data "aws_iam_policy_document" "reporting_ses" {
359-
# statement {
360-
# sid = "SESAccess"
361-
# effect = "Allow"
362-
#
363-
# actions = [
364-
# "ses:SendEmail",
365-
# "ses:SendRawEmail"
366-
# ]
367-
#
368-
# resources = [
369-
# "arn:aws:ses:${var.region}:${data.aws_caller_identity.current.account_id}:identity/*",
370-
# "arn:aws:ses:${var.region}:${data.aws_caller_identity.current.account_id}:configuration-set/${aws_ses_configuration_set.reporting.name}"
371-
# ]
372-
#
373-
# condition {
374-
# test = "StringEquals"
375-
# variable = "ses:FromAddress"
376-
# values = [local.reporting_ses_from_address_value]
377-
# }
378-
# }
379-
# }
380-
#
381-
# data "aws_iam_policy_document" "ses_feedback_s3_put" {
382-
# statement {
383-
# effect = "Allow"
384-
# actions = [
385-
# "s3:PutObject"
386-
# ]
387-
# resources = [
388-
# "${module.ses-feedback-store.bucket_arn}/ses-feedback/*"
389-
# ]
390-
# }
391-
# }
358+
data "aws_iam_policy_document" "reporting_ses" {
359+
statement {
360+
sid = "SESAccess"
361+
effect = "Allow"
362+
363+
actions = [
364+
"ses:SendEmail",
365+
"ses:SendRawEmail"
366+
]
367+
368+
resources = [
369+
"arn:aws:ses:${var.region}:${data.aws_caller_identity.current.account_id}:identity/*",
370+
"arn:aws:ses:${var.region}:${data.aws_caller_identity.current.account_id}:configuration-set/${aws_ses_configuration_set.reporting.name}"
371+
]
372+
373+
condition {
374+
test = "StringEquals"
375+
variable = "ses:FromAddress"
376+
values = [module.ses.report_email_address]
377+
}
378+
}
379+
}
380+
381+
data "aws_iam_policy_document" "ses_feedback_s3_put" {
382+
statement {
383+
effect = "Allow"
384+
actions = [
385+
"s3:PutObject"
386+
]
387+
resources = [
388+
"${module.ses-feedback-store.bucket_arn}/ses-feedback/*"
389+
]
390+
}
391+
}

infrastructure/kms_sns.tf

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ module "sns_encryption_key" {
44
kms_key_description = "Custom KMS Key to enable server side encryption for sns subscriptions"
55
environment = var.environment
66
owner = var.owner
7-
# service_identifiers = ["sns.amazonaws.com", "cloudwatch.amazonaws.com", "ses.amazonaws.com"]
8-
service_identifiers = ["sns.amazonaws.com", "cloudwatch.amazonaws.com"]
7+
service_identifiers = ["sns.amazonaws.com", "cloudwatch.amazonaws.com", "ses.amazonaws.com"]
98
kms_deletion_window = var.kms_deletion_window
109
}
Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
1-
# module "report-distribution-lambda" {
2-
# source = "./modules/lambda"
3-
# name = "ReportDistribution"
4-
# handler = "handlers.report_distribution_handler.lambda_handler"
5-
# lambda_timeout = 300
6-
#
7-
# iam_role_policy_documents = [
8-
# module.ndr-report-store.s3_read_policy_document,
9-
# module.bulk_upload_contact_lookup_table.dynamodb_read_policy_document,
10-
# data.aws_iam_policy_document.reporting_ses.json,
11-
# data.aws_iam_policy.aws_lambda_vpc_access_execution_role.policy,
12-
# ]
13-
#
14-
# lambda_environment_variables = {
15-
# APPCONFIG_APPLICATION = module.ndr-app-config.app_config_application_id
16-
# APPCONFIG_ENVIRONMENT = module.ndr-app-config.app_config_environment_id
17-
# APPCONFIG_CONFIGURATION = module.ndr-app-config.app_config_configuration_profile_id
18-
# WORKSPACE = terraform.workspace
19-
#
20-
# REPORT_BUCKET_NAME = module.ndr-report-store.bucket_id
21-
# CONTACT_TABLE_NAME = module.bulk_upload_contact_lookup_table.table_name
22-
#
23-
# PRM_MAILBOX_EMAIL = data.aws_ssm_parameter.prm_mailbox_email.value
24-
# SES_FROM_ADDRESS = local.reporting_ses_from_address_value
25-
# SES_CONFIGURATION_SET = aws_ses_configuration_set.reporting.name
26-
# }
27-
#
28-
# is_gateway_integration_needed = false
29-
# is_invoked_from_gateway = false
30-
# }
1+
module "report-distribution-lambda" {
2+
source = "./modules/lambda"
3+
name = "ReportDistribution"
4+
handler = "handlers.report_distribution_handler.lambda_handler"
5+
lambda_timeout = 300
6+
7+
iam_role_policy_documents = [
8+
module.ndr-report-store.s3_read_policy_document,
9+
module.bulk_upload_contact_lookup_table.dynamodb_read_policy_document,
10+
data.aws_iam_policy_document.reporting_ses.json,
11+
data.aws_iam_policy.aws_lambda_vpc_access_execution_role.policy,
12+
]
13+
14+
lambda_environment_variables = {
15+
APPCONFIG_APPLICATION = module.ndr-app-config.app_config_application_id
16+
APPCONFIG_ENVIRONMENT = module.ndr-app-config.app_config_environment_id
17+
APPCONFIG_CONFIGURATION = module.ndr-app-config.app_config_configuration_profile_id
18+
WORKSPACE = terraform.workspace
19+
20+
REPORT_BUCKET_NAME = module.ndr-report-store.bucket_id
21+
CONTACT_TABLE_NAME = module.bulk_upload_contact_lookup_table.table_name
22+
23+
PRM_MAILBOX_EMAIL = data.aws_ssm_parameter.prm_mailbox_email.value
24+
SES_FROM_ADDRESS = module.ses.report_email_address
25+
SES_CONFIGURATION_SET = aws_ses_configuration_set.reporting.name
26+
}
27+
28+
is_gateway_integration_needed = false
29+
is_invoked_from_gateway = false
30+
}

infrastructure/lambda-send-feedback.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ module "send-feedback-lambda" {
105105
depends_on = [
106106
aws_api_gateway_rest_api.ndr_doc_store_api,
107107
module.send-feedback-gateway,
108-
module.ndr-feedback-mailbox,
108+
module.ses,
109109
module.ndr-app-config
110110
]
111111
}
Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,28 @@
1-
# module "ses-feedback-monitor-lambda" {
2-
# source = "./modules/lambda"
3-
# name = "SesFeedbackMonitor"
4-
# handler = "handlers.ses_feedback_monitor_handler.lambda_handler"
5-
# lambda_timeout = 60
6-
#
7-
# iam_role_policy_documents = [
8-
# data.aws_iam_policy_document.ses_feedback_s3_put.json,
9-
# data.aws_iam_policy_document.reporting_ses.json,
10-
# data.aws_iam_policy.aws_lambda_vpc_access_execution_role.policy,
11-
# ]
12-
#
13-
# lambda_environment_variables = {
14-
# APPCONFIG_APPLICATION = module.ndr-app-config.app_config_application_id
15-
# APPCONFIG_ENVIRONMENT = module.ndr-app-config.app_config_environment_id
16-
# APPCONFIG_CONFIGURATION = module.ndr-app-config.app_config_configuration_profile_id
17-
# WORKSPACE = terraform.workspace
18-
#
19-
# SES_FEEDBACK_BUCKET_NAME = module.ses-feedback-store.bucket_id
20-
# SES_FEEDBACK_PREFIX = "ses-feedback/"
21-
# PRM_MAILBOX_EMAIL = data.aws_ssm_parameter.prm_mailbox_email.value
22-
# SES_FROM_ADDRESS = local.reporting_ses_from_address_value
23-
# ALERT_ON_EVENT_TYPES = "BOUNCE,REJECT"
24-
# }
25-
#
26-
# is_gateway_integration_needed = false
27-
# is_invoked_from_gateway = false
28-
#
29-
# depends_on = [
30-
# module.ses-feedback-store
31-
# ]
32-
# }
1+
module "ses-feedback-monitor-lambda" {
2+
source = "./modules/lambda"
3+
name = "SesFeedbackMonitor"
4+
handler = "handlers.ses_feedback_monitor_handler.lambda_handler"
5+
lambda_timeout = 60
6+
7+
iam_role_policy_documents = [
8+
data.aws_iam_policy_document.ses_feedback_s3_put.json,
9+
data.aws_iam_policy_document.reporting_ses.json,
10+
data.aws_iam_policy.aws_lambda_vpc_access_execution_role.policy,
11+
]
12+
13+
lambda_environment_variables = {
14+
APPCONFIG_APPLICATION = module.ndr-app-config.app_config_application_id
15+
APPCONFIG_ENVIRONMENT = module.ndr-app-config.app_config_environment_id
16+
APPCONFIG_CONFIGURATION = module.ndr-app-config.app_config_configuration_profile_id
17+
WORKSPACE = terraform.workspace
18+
19+
SES_FEEDBACK_BUCKET_NAME = module.ses-feedback-store.bucket_id
20+
SES_FEEDBACK_PREFIX = "ses-feedback/"
21+
PRM_MAILBOX_EMAIL = data.aws_ssm_parameter.prm_mailbox_email.value
22+
SES_FROM_ADDRESS = module.ses.report_email_address
23+
ALERT_ON_EVENT_TYPES = "BOUNCE,REJECT"
24+
}
25+
26+
is_gateway_integration_needed = false
27+
is_invoked_from_gateway = false
28+
}

infrastructure/modules/ses/README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,26 @@ module "ses_identity" {
4242

4343
| Name | Type |
4444
|------|------|
45+
| [aws_route53_record.dmarc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
4546
| [aws_route53_record.ndr_ses_dkim_record](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
47+
| [aws_route53_record.ses_mail_from_mx](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
48+
| [aws_route53_record.ses_mail_from_spf](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
4649
| [aws_ses_domain_dkim.ndr_dkim](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_dkim) | resource |
4750
| [aws_ses_domain_identity.ndr_ses](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_identity) | resource |
4851
| [aws_ses_domain_identity_verification.ndr_ses_domain_verification](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_identity_verification) | resource |
52+
| [aws_ses_domain_mail_from.reporting](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_mail_from) | resource |
4953

5054
## Inputs
5155

5256
| Name | Description | Type | Default | Required |
5357
|------|-------------|------|---------|:--------:|
5458
| <a name="input_domain"></a> [domain](#input\_domain) | The root domain name to be registered with SES and used for verification. | `string` | n/a | yes |
55-
| <a name="input_domain_prefix"></a> [domain\_prefix](#input\_domain\_prefix) | The subdomain or prefix used to construct the full SES identity domain. | `string` | n/a | yes |
56-
| <a name="input_enable"></a> [enable](#input\_enable) | Whether to enable the creation of SES identity, DKIM, and DNS records. | `bool` | n/a | yes |
59+
| <a name="input_is_sandbox"></a> [is\_sandbox](#input\_is\_sandbox) | Whether the workspace being created is a sandbox. | `bool` | n/a | yes |
5760
| <a name="input_zone_id"></a> [zone\_id](#input\_zone\_id) | The Route53 hosted zone ID where DNS verification records will be created. | `string` | n/a | yes |
5861

5962
## Outputs
6063

61-
No outputs.
64+
| Name | Description |
65+
|------|-------------|
66+
| <a name="output_report_email_address"></a> [report\_email\_address](#output\_report\_email\_address) | n/a |
6267
<!-- END_TF_DOCS -->

infrastructure/modules/ses/main.tf

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,65 @@
11
resource "aws_ses_domain_identity" "ndr_ses" {
2-
domain = var.domain
3-
count = var.enable ? 1 : 0
2+
domain = var.is_sandbox ? "${terraform.workspace}.dev.${var.domain}" : "${terraform.workspace}.${var.domain}"
43
}
54

65
resource "aws_ses_domain_dkim" "ndr_dkim" {
7-
domain = aws_ses_domain_identity.ndr_ses[0].domain
6+
domain = aws_ses_domain_identity.ndr_ses.domain
87

9-
count = var.enable ? 1 : 0
10-
depends_on = [aws_ses_domain_identity.ndr_ses[0]]
8+
depends_on = [aws_ses_domain_identity.ndr_ses]
119
}
1210

1311
resource "aws_route53_record" "ndr_ses_dkim_record" {
12+
count = 3
13+
1414
zone_id = var.zone_id
15-
name = "${aws_ses_domain_dkim.ndr_dkim[0].dkim_tokens[count.index]}._domainkey.${var.domain_prefix}"
15+
name = var.is_sandbox ? "${aws_ses_domain_dkim.ndr_dkim.dkim_tokens[count.index]}._domainkey.${terraform.workspace}.dev" : "${aws_ses_domain_dkim.ndr_dkim.dkim_tokens[count.index]}._domainkey.${terraform.workspace}"
1616
type = "CNAME"
1717
ttl = 1800
18-
records = ["${aws_ses_domain_dkim.ndr_dkim[0].dkim_tokens[count.index]}.dkim.amazonses.com"]
18+
records = ["${aws_ses_domain_dkim.ndr_dkim.dkim_tokens[count.index]}.dkim.amazonses.com"]
1919

20-
count = var.enable ? 3 : 0
21-
depends_on = [aws_ses_domain_dkim.ndr_dkim[0]]
20+
depends_on = [aws_ses_domain_dkim.ndr_dkim]
2221
}
2322

2423
resource "aws_ses_domain_identity_verification" "ndr_ses_domain_verification" {
25-
domain = aws_ses_domain_identity.ndr_ses[0].domain
24+
domain = aws_ses_domain_identity.ndr_ses.domain
25+
26+
depends_on = [aws_route53_record.ndr_ses_dkim_record]
27+
}
28+
29+
resource "aws_ses_domain_mail_from" "reporting" {
30+
domain = aws_ses_domain_identity.ndr_ses.domain
31+
mail_from_domain = "mail.${aws_ses_domain_identity.ndr_ses.domain}"
32+
33+
behavior_on_mx_failure = "UseDefaultValue"
34+
}
35+
36+
resource "aws_route53_record" "ses_mail_from_mx" {
37+
zone_id = var.zone_id
38+
name = "mail.${aws_ses_domain_identity.ndr_ses.domain}"
39+
type = "MX"
40+
ttl = 600
41+
42+
records = [
43+
"10 feedback-smtp.eu-west-2.amazonses.com"
44+
]
45+
}
46+
47+
resource "aws_route53_record" "ses_mail_from_spf" {
48+
zone_id = var.zone_id
49+
name = "mail.${aws_ses_domain_identity.ndr_ses.domain}"
50+
type = "TXT"
51+
ttl = 600
52+
53+
records = [
54+
"v=spf1 include:amazonses.com -all"
55+
]
56+
}
57+
58+
resource "aws_route53_record" "dmarc" {
59+
zone_id = var.zone_id
60+
name = "_dmarc.${aws_ses_domain_identity.ndr_ses.domain}"
61+
type = "TXT"
62+
ttl = 300
2663

27-
count = var.enable ? 1 : 0
28-
depends_on = [aws_route53_record.ndr_ses_dkim_record[0]]
64+
records = ["v=DMARC1; p=none; adkim=s; aspf=s"]
2965
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
moved {
2+
from = aws_ses_domain_identity.ndr_ses[0]
3+
to = aws_ses_domain_identity.ndr_ses
4+
}
5+
6+
moved {
7+
from = aws_ses_domain_dkim.ndr_dkim[0]
8+
to = aws_ses_domain_dkim.ndr_dkim
9+
}
10+
11+
moved {
12+
from = aws_ses_domain_identity_verification.ndr_ses_domain_verification[0]
13+
to = aws_ses_domain_identity_verification.ndr_ses_domain_verification
14+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
output "report_email_address" {
2+
value = "ndr-reports@${aws_ses_domain_identity.ndr_ses.domain}"
3+
}

0 commit comments

Comments
 (0)