Add first pass SES stuff

This commit is contained in:
Erik Stambaugh 2024-01-22 19:27:29 -08:00
parent fa236fa0b6
commit 911e0fc68d
7 changed files with 155 additions and 7 deletions

View file

@ -34,6 +34,9 @@ config.mk: config.mk.in
.s3_iam_credentials: terraform/.s3_id terraform/.s3_secret .s3_iam_credentials: terraform/.s3_id terraform/.s3_secret
cat $^ > $@ cat $^ > $@
.ses_iam_credentials: terraform/.ses_id terraform/.ses_secret
cat $^ > $@
terraform/.s3_id terraform/.s3_secret: terraform terraform/.s3_id terraform/.s3_secret: terraform

View file

@ -27,7 +27,7 @@ inventory.yaml: inventory.tmpl.yaml sedline
SEDLINE = SEDLINE =
sedline: terraform_sedline config_sedline s3_sedline sedline: terraform_sedline config_sedline secret_sedline
config_sedline: $(addprefix __sed_,$(shell grep '^[0-9A-Z_]' ../config.mk | awk '{print $$1}')) config_sedline: $(addprefix __sed_,$(shell grep '^[0-9A-Z_]' ../config.mk | awk '{print $$1}'))
@ -37,9 +37,11 @@ __sed_%:
$(eval SEDLINE := $$(SEDLINE) -e 's/{{$*}}/$($*)/') $(eval SEDLINE := $$(SEDLINE) -e 's/{{$*}}/$($*)/')
# FIXME: this is awful because it's all in the clear # FIXME: this is awful because it's all in the clear
s3_sedline: secret_sedline:
$(eval SEDLINE := $$(SEDLINE) -e 's/{{S3_IAM_ID}}/$(shell head -1 ../.s3_iam_credentials)/') $(eval SEDLINE := $$(SEDLINE) -e 's/{{S3_IAM_ID}}/$(shell head -1 ../.s3_iam_credentials)/')
$(eval SEDLINE := $$(SEDLINE) -e 's/{{S3_IAM_SECRET}}/$(shell tail -1 ../.s3_iam_credentials)/') $(eval SEDLINE := $$(SEDLINE) -e 's/{{S3_IAM_SECRET}}/$(shell tail -1 ../.s3_iam_credentials)/')
$(eval SEDLINE := $$(SEDLINE) -e 's/{{SES_IAM_ID}}/$(shell head -1 ../.ses_iam_credentials)/')
$(eval SEDLINE := $$(SEDLINE) -e 's/{{SES_IAM_SECRET}}/$(shell tail -1 ../.ses_iam_credentials)/')
# FIXME: DRY this target # FIXME: DRY this target

View file

@ -20,6 +20,8 @@ social:
s3_hostname: "s3.{{AWS_REGION}}.amazonaws.com" s3_hostname: "s3.{{AWS_REGION}}.amazonaws.com"
s3_iam_id: {{S3_IAM_ID}} s3_iam_id: {{S3_IAM_ID}}
s3_iam_secret: {{S3_IAM_SECRET}} s3_iam_secret: {{S3_IAM_SECRET}}
ses_iam_id: {{SES_IAM_ID}}
ses_iam_secret: {{SES_IAM_SECRET}}
#smtp_server: #smtp_server:
otp_secret: otp_secret:

View file

@ -48,11 +48,16 @@ OTP_SECRET={{otp_secret}}
# Sending mail # Sending mail
# ------------ # ------------
#SMTP_SERVER=#{#{smtp_server#}#} SMTP_SERVER=email-smtp.{{aws_region}}.amazonaws.com
SMTP_PORT=25 SMTP_PORT=465
SMTP_FROM_ADDRESS=Mastodon <notifications@{{domain_name}}> SMTP_FROM_ADDRESS=Mastodon <notifications@{{domain_name}}>
SMTP_AUTH_METHOD=none SMTP_LOGIN={{ses_iam_id}}
SMTP_PASSWORD={{ses_iam_secret}}
SMTP_ENABLE_STARTTLS_AUTO=false
SMTP_TLS=true
SMTP_AUTH_METHOD=plain
SMTP_OPENSSL_VERIFY_MODE=none SMTP_OPENSSL_VERIFY_MODE=none
SMTP_ENABLE_STARTTLS=never
## File storage (optional) ## File storage (optional)
## ----------------------- ## -----------------------

View file

@ -67,7 +67,7 @@ module "sg" {
}, },
{ {
rule = "https-443-tcp" rule = "https-443-tcp"
cidr_blocks = "${chomp(data.http.myip.body)}/32" cidr_blocks = "${chomp(data.http.myip.response_body)}/32"
} }
] ]
} }

View file

@ -13,7 +13,7 @@ output "s3_bucket_name" {
value = module.s3_bucket.s3_bucket_id value = module.s3_bucket.s3_bucket_id
} }
output "my_ip" { output "my_ip" {
value = "${chomp(data.http.myip.body)}" value = "${chomp(data.http.myip.response_body)}"
} }
#output "aws_route53_zone" { #output "aws_route53_zone" {

136
terraform/ses.tf Normal file
View file

@ -0,0 +1,136 @@
## - verification
resource "aws_ses_domain_identity" "social" {
domain = local.domain_name
}
module "ses_zone_records" {
# count = local.route53_zone == "" ? 0 : 1
source = "terraform-aws-modules/route53/aws//modules/records"
version = "~> 2.0"
zone_name = keys(module.zone.route53_zone_zone_id)[0]
records = [
{
name = "_amazonses.${aws_ses_domain_identity.social.id}"
type = "TXT"
ttl = "600"
records = [ aws_ses_domain_identity.social.verification_token ]
},
{
name = local.domain_name
type = "MX"
ttl = "600"
records = ["10 feedback-smtp.${local.aws_region}.amazonses.com"]
},
# SPF
{
name = aws_ses_domain_mail_from.social.mail_from_domain
type = "TXT"
ttl = "600"
records = [ "v=spf1 include:amazonses.com -all" ]
},
{
name = local.domain_name
type = "TXT"
ttl = "600"
records = [ "v=spf1 include:amazonses.com -all" ]
},
# DKIM
{
name = "${aws_ses_domain_dkim.social.dkim_tokens[0]}._domainkey"
type = "CNAME"
ttl = "600"
records = ["${aws_ses_domain_dkim.social.dkim_tokens[0]}.dkim.amazonses.com"]
},
{
name = "${aws_ses_domain_dkim.social.dkim_tokens[1]}._domainkey"
type = "CNAME"
ttl = "600"
records = ["${aws_ses_domain_dkim.social.dkim_tokens[1]}.dkim.amazonses.com"]
},
{
name = "${aws_ses_domain_dkim.social.dkim_tokens[2]}._domainkey"
type = "CNAME"
ttl = "600"
records = ["${aws_ses_domain_dkim.social.dkim_tokens[2]}.dkim.amazonses.com"]
},
]
depends_on = [module.zone]
}
resource "aws_ses_domain_identity_verification" "social" {
domain = aws_ses_domain_identity.social.id
depends_on = [ module.ses_zone_records ]
}
resource "aws_ses_domain_dkim" "social" {
domain = aws_ses_domain_identity.social.domain
}
## - mx record
resource "aws_ses_domain_mail_from" "social" {
domain = aws_ses_domain_identity.social.domain
mail_from_domain = "bounce.${aws_ses_domain_identity.social.domain}"
}
#resource "aws_route53_record" "mx_receive" {
# count = var.enable_incoming_email_record ? 1 : 0
#
# name = data.aws_route53_zone.domain.name
# zone_id = var.zone_id
# type = "MX"
# ttl = "600"
# records = concat(["10 inbound-smtp.${data.aws_region.current.name}.amazonaws.com"], var.additional_incoming_email_records)
#}
## SMTP credentials
resource "random_pet" "smtp" {}
resource "aws_iam_user" "ses" {
name = "smtp-${random_pet.smtp.id}"
}
resource "aws_iam_user_policy_attachment" "send_mail" {
policy_arn = aws_iam_policy.send_mail.arn
user = aws_iam_user.ses.name
}
resource "aws_iam_policy" "send_mail" {
name = "social-send-mail"
policy = data.aws_iam_policy_document.send_mail.json
}
data "aws_iam_policy_document" "send_mail" {
statement {
actions = ["ses:SendRawEmail"]
resources = ["*"]
}
}
resource "aws_iam_access_key" "ses" {
user = aws_iam_user.ses.name
}
resource "local_file" "ses_secret" {
filename = ".ses_secret"
content = "${aws_iam_access_key.ses.secret}\n"
}
resource "local_file" "ses_id" {
filename = ".ses_id"
content = "${aws_iam_access_key.ses.id}\n"
}