From 328bcde534e3cd5193f2f5bf65cae551de4316da Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 10:58:34 +0100 Subject: [PATCH 01/16] Add bucket name namespace for ordering STS buckets --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 19a4b9f..a161c50 100644 --- a/main.tf +++ b/main.tf @@ -3,7 +3,7 @@ data "aws_caller_identity" "current" {} locals { policydomain = "mta-sts.${var.domain}" policyhash = md5(format("%s%s%s", join("", var.mx), var.mode, var.max_age)) - bucketname = "${data.aws_caller_identity.current.account_id}.${var.domain}" + bucketname = "mta-sts.${data.aws_caller_identity.current.account_id}.${var.domain}" } provider "aws" { From dfb8f08d36adce5feff96b3182638ef4f355adfd Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 11:00:29 +0100 Subject: [PATCH 02/16] Remove provider and pass from parent TF --- main.tf | 5 ----- 1 file changed, 5 deletions(-) diff --git a/main.tf b/main.tf index a161c50..5ab7e42 100644 --- a/main.tf +++ b/main.tf @@ -6,11 +6,6 @@ locals { bucketname = "mta-sts.${data.aws_caller_identity.current.account_id}.${var.domain}" } -provider "aws" { - alias = "useast1" - region = "us-east-1" -} - resource "aws_acm_certificate" "cert" { domain_name = local.policydomain validation_method = "DNS" From ce0ab14f3d149894029e7666dacbca62363635ed Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 11:04:06 +0100 Subject: [PATCH 03/16] Add provider to aws_caller_identity --- main.tf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 5ab7e42..5e9937e 100644 --- a/main.tf +++ b/main.tf @@ -1,4 +1,6 @@ -data "aws_caller_identity" "current" {} +data "aws_caller_identity" "current" { + provider = aws.account +} locals { policydomain = "mta-sts.${var.domain}" From 5ecbbba25b17870d938b33998c26eed3ff5afa65 Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 11:58:05 +0100 Subject: [PATCH 04/16] Add provider argument to all resources --- main.tf | 57 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/main.tf b/main.tf index 5e9937e..9556da6 100644 --- a/main.tf +++ b/main.tf @@ -16,15 +16,17 @@ resource "aws_acm_certificate" "cert" { } data "aws_route53_zone" "zone" { - zone_id = var.zone_id + zone_id = var.zone_id + provider = aws.useast1 } resource "aws_route53_record" "cert_validation" { - name = tolist(aws_acm_certificate.cert.domain_validation_options)[0].resource_record_name - type = tolist(aws_acm_certificate.cert.domain_validation_options)[0].resource_record_type - zone_id = data.aws_route53_zone.zone.id - records = [tolist(aws_acm_certificate.cert.domain_validation_options)[0].resource_record_value] - ttl = 60 + name = tolist(aws_acm_certificate.cert.domain_validation_options)[0].resource_record_name + type = tolist(aws_acm_certificate.cert.domain_validation_options)[0].resource_record_type + zone_id = data.aws_route53_zone.zone.id + records = [tolist(aws_acm_certificate.cert.domain_validation_options)[0].resource_record_value] + ttl = 60 + provider = aws.useast1 } resource "aws_acm_certificate_validation" "cert" { @@ -34,8 +36,9 @@ resource "aws_acm_certificate_validation" "cert" { } resource "aws_s3_bucket" "policybucket" { - bucket = local.bucketname - acl = "private" + bucket = local.bucketname + acl = "private" + provider = aws.account } resource "aws_s3_bucket_object" "mtastspolicyfile" { @@ -47,6 +50,7 @@ mode: ${var.mode} ${join("", formatlist("mx: %s\n", var.mx))}max_age: ${var.max_age} EOF content_type = "text/plain" + provider = aws.account } locals { @@ -54,6 +58,7 @@ locals { } resource "aws_cloudfront_distribution" "s3_distribution" { + provider = aws.account origin { domain_name = aws_s3_bucket.policybucket.bucket_regional_domain_name origin_id = local.s3_origin_id @@ -99,10 +104,12 @@ resource "aws_cloudfront_distribution" "s3_distribution" { } resource "aws_cloudfront_origin_access_identity" "policybucketoai" { - comment = "OAI for MTA-STS policy bucket (${var.domain})" + comment = "OAI for MTA-STS policy bucket (${var.domain})" + provider = aws.account } data "aws_iam_policy_document" "s3_policy" { + provider = aws.account statement { actions = ["s3:GetObject"] resources = ["${aws_s3_bucket.policybucket.arn}/*"] @@ -115,14 +122,16 @@ data "aws_iam_policy_document" "s3_policy" { } resource "aws_s3_bucket_policy" "policybucketpolicy" { - bucket = aws_s3_bucket.policybucket.id - policy = data.aws_iam_policy_document.s3_policy.json + bucket = aws_s3_bucket.policybucket.id + policy = data.aws_iam_policy_document.s3_policy.json + provider = aws.account } resource "aws_route53_record" "cloudfrontalias" { - name = local.policydomain - type = "A" - zone_id = data.aws_route53_zone.zone.id + name = local.policydomain + type = "A" + zone_id = data.aws_route53_zone.zone.id + provider = aws.account alias { evaluate_target_health = true @@ -132,11 +141,12 @@ resource "aws_route53_record" "cloudfrontalias" { } resource "aws_route53_record" "smtptlsreporting" { - zone_id = data.aws_route53_zone.zone.id - name = "_smtp._tls.${var.domain}" - type = "TXT" - ttl = "300" - count = length(var.reporting_email) > 0 ? 1 : 0 + zone_id = data.aws_route53_zone.zone.id + name = "_smtp._tls.${var.domain}" + type = "TXT" + ttl = "300" + count = length(var.reporting_email) > 0 ? 1 : 0 + provider = aws.account records = [ "v=TLSRPTv1;rua=mailto:${var.reporting_email}", @@ -144,10 +154,11 @@ resource "aws_route53_record" "smtptlsreporting" { } resource "aws_route53_record" "mtastspolicydns" { - zone_id = data.aws_route53_zone.zone.id - name = "_mta-sts.${var.domain}" - type = "TXT" - ttl = "300" + zone_id = data.aws_route53_zone.zone.id + name = "_mta-sts.${var.domain}" + type = "TXT" + ttl = "300" + provider = aws.account records = [ "v=STSv1; id=${local.policyhash}", From df834de5ae65e9aac20361deea1c777501862ead Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:03:14 +0100 Subject: [PATCH 05/16] =?UTF-8?q?Add=20aws=5Fs3=5Fbucket=5Facl=20resource?= =?UTF-8?q?=20to=20resolve=20warning.=20Resolves=20TF=20warning:=20Argumen?= =?UTF-8?q?t=20is=20deprecated=20in=20resource=20"aws=5Fs3=5Fbucket"=20"po?= =?UTF-8?q?licybucket":=20=E2=94=82=20=20=20=20=20acl=20=20=20=20=20=20=3D?= =?UTF-8?q?=20"private"=20Use=20the=20aws=5Fs3=5Fbucket=5Facl=20resource?= =?UTF-8?q?=20instead?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.tf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.tf b/main.tf index 9556da6..8444dfb 100644 --- a/main.tf +++ b/main.tf @@ -37,6 +37,11 @@ resource "aws_acm_certificate_validation" "cert" { resource "aws_s3_bucket" "policybucket" { bucket = local.bucketname + provider = aws.account +} + +resource "aws_s3_bucket_acl" "policybucket_acl" { + bucket = aws_s3_bucket.policybucket.id acl = "private" provider = aws.account } From 354b253be31d0a522721d7fac62709f8534676e6 Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:05:50 +0100 Subject: [PATCH 06/16] Add provider configuration_aliases --- versions.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/versions.tf b/versions.tf index 241ac05..a54e008 100644 --- a/versions.tf +++ b/versions.tf @@ -4,6 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" + configuration_aliases = [ aws.account, aws.useast1 ] } } } From bca72a5df4635c51e067bf2b2f9908f04124afb0 Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:10:21 +0100 Subject: [PATCH 07/16] =?UTF-8?q?Replace=20aws=5Fs3=5Fbucket=5Fobject=20du?= =?UTF-8?q?e=20to=20deprecation=20Resolves=20warning:=20Argument=20is=20de?= =?UTF-8?q?precated=20in=20resource=20"aws=5Fs3=5Fbucket=5Fobject"=20"mtas?= =?UTF-8?q?tspolicyfile":=20=E2=94=82=20=20=20key=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=3D=20".well-known/mta-sts.txt"=20Use=20the=20aws=5Fs3=5F?= =?UTF-8?q?object=20resource=20instead?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 8444dfb..ccc7137 100644 --- a/main.tf +++ b/main.tf @@ -46,7 +46,7 @@ resource "aws_s3_bucket_acl" "policybucket_acl" { provider = aws.account } -resource "aws_s3_bucket_object" "mtastspolicyfile" { +resource "aws_s3_object" "mtastspolicyfile" { key = ".well-known/mta-sts.txt" bucket = aws_s3_bucket.policybucket.id content = < Date: Tue, 2 Aug 2022 12:20:16 +0100 Subject: [PATCH 08/16] Removing zone_id input variable since not required Previously, zone name and ID were both passed in. Since using aws_route53_zone data source anyway, can drop one. Now looking up using domain name. --- README.md | 1 - main.tf | 2 +- variables.tf | 5 ----- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index 0aa7320..e4be3e0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ This module assumes AWS Account with access to Route53, CloudFront, S3, and ACM, ```terraform module "mtastspolicy_examplecom" { source = "github.com/ukncsc/terraform-aws-mtasts" - zone_id = "Z00AAAAAAA0A0A" domain = "example.com" mx = ["mail.example.com"] mode = "testing" diff --git a/main.tf b/main.tf index ccc7137..531b85a 100644 --- a/main.tf +++ b/main.tf @@ -16,7 +16,7 @@ resource "aws_acm_certificate" "cert" { } data "aws_route53_zone" "zone" { - zone_id = var.zone_id + name = var.domain provider = aws.useast1 } diff --git a/variables.tf b/variables.tf index 1198fca..d2afd0e 100644 --- a/variables.tf +++ b/variables.tf @@ -1,8 +1,3 @@ -variable "zone_id" { - type = string - description = "Route53 zone hosting the domain MTA-STS/TLS-RPT is being deployed for." -} - variable "domain" { type = string description = "The domain MTA-STS/TLS-RPT is being deployed for." From 252577a31badc37394cbdc102e709340b89ac770 Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:45:30 +0100 Subject: [PATCH 09/16] Update readme with secondary provider details. --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index e4be3e0..8b7b674 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,36 @@ This consists of using CloudFront/S3 with a Custom Domain to host the MTA-STS po ## How to use this Module This module assumes AWS Account with access to Route53, CloudFront, S3, and ACM, which also hosts the DNS (in Route53) for the domain you wish to deploy MTA-STS/TLS-RPT. +The providers are defined here to allow resources to be provisioned in both `us-east-1` and a local region (`eu-west-2` in this example). This method also allows additional providers to be defined for additional AWS accounts / profiles, if required. ```terraform +provider "aws" { + alias = "useast1" + region = "us-east-1" + shared_config_files = ["___/.aws/conf"] + shared_credentials_files = ["___/.aws/creds"] + profile = "myprofile" +} + +provider "aws" { + alias = "myregion" + region = "eu-west-2" + shared_config_files = ["___/.aws/conf"] + shared_credentials_files = ["___/.aws/creds"] + profile = "myprofile" +} + module "mtastspolicy_examplecom" { source = "github.com/ukncsc/terraform-aws-mtasts" domain = "example.com" mx = ["mail.example.com"] mode = "testing" reporting_email = "tlsreporting@example.com" + + providers = { + aws.useast1 = aws.useast1 + aws.account = aws.myregion + } + } ``` \ No newline at end of file From d290ad7b0725e2eb0e70dc8f5f56448b6c259081 Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:57:34 +0100 Subject: [PATCH 10/16] Combine locals blocks into one and sort vars. --- main.tf | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/main.tf b/main.tf index 531b85a..32fb9b4 100644 --- a/main.tf +++ b/main.tf @@ -3,9 +3,10 @@ data "aws_caller_identity" "current" { } locals { + bucketname = "mta-sts.${data.aws_caller_identity.current.account_id}.${var.domain}" policydomain = "mta-sts.${var.domain}" policyhash = md5(format("%s%s%s", join("", var.mx), var.mode, var.max_age)) - bucketname = "mta-sts.${data.aws_caller_identity.current.account_id}.${var.domain}" + s3_origin_id = "myS3Origin" } resource "aws_acm_certificate" "cert" { @@ -58,10 +59,6 @@ EOF provider = aws.account } -locals { - s3_origin_id = "myS3Origin" -} - resource "aws_cloudfront_distribution" "s3_distribution" { provider = aws.account origin { From 41f4d61a72a70e7b85a11f81d47c83c782546e81 Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 14:03:45 +0100 Subject: [PATCH 11/16] Add default "Service" and "Domain" tags. --- main.tf | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 32fb9b4..f8e0e1d 100644 --- a/main.tf +++ b/main.tf @@ -7,12 +7,19 @@ locals { policydomain = "mta-sts.${var.domain}" policyhash = md5(format("%s%s%s", join("", var.mx), var.mode, var.max_age)) s3_origin_id = "myS3Origin" + tags = merge( + { + "Service" = "MTA-STS" + "Domain" = var.domain + }, + var.tags + ) } resource "aws_acm_certificate" "cert" { domain_name = local.policydomain validation_method = "DNS" - tags = var.tags + tags = local.tags provider = aws.useast1 } From 5a82e77fa6c83ea76400b55711a4c8728d2fec0e Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 15:39:50 +0100 Subject: [PATCH 12/16] Tag all taggable resources. --- main.tf | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/main.tf b/main.tf index f8e0e1d..b0a23d5 100644 --- a/main.tf +++ b/main.tf @@ -45,6 +45,7 @@ resource "aws_acm_certificate_validation" "cert" { resource "aws_s3_bucket" "policybucket" { bucket = local.bucketname + tags = local.tags provider = aws.account } @@ -63,11 +64,16 @@ mode: ${var.mode} ${join("", formatlist("mx: %s\n", var.mx))}max_age: ${var.max_age} EOF content_type = "text/plain" + tags = local.tags provider = aws.account } resource "aws_cloudfront_distribution" "s3_distribution" { + aliases = [local.policydomain] + enabled = true + tags = local.tags provider = aws.account + origin { domain_name = aws_s3_bucket.policybucket.bucket_regional_domain_name origin_id = local.s3_origin_id @@ -76,9 +82,6 @@ resource "aws_cloudfront_distribution" "s3_distribution" { origin_access_identity = aws_cloudfront_origin_access_identity.policybucketoai.cloudfront_access_identity_path } } - enabled = true - - aliases = [local.policydomain] default_cache_behavior { allowed_methods = ["GET", "HEAD"] From 98e2ab9a336051ab2feac374db90e3200da25eb2 Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 16:39:28 +0100 Subject: [PATCH 13/16] Add CloudFront price-class variable. --- main.tf | 9 +++++---- variables.tf | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/main.tf b/main.tf index b0a23d5..1b3fbb3 100644 --- a/main.tf +++ b/main.tf @@ -69,10 +69,11 @@ EOF } resource "aws_cloudfront_distribution" "s3_distribution" { - aliases = [local.policydomain] - enabled = true - tags = local.tags - provider = aws.account + aliases = [local.policydomain] + enabled = true + price_class = var.cf_price_class + tags = local.tags + provider = aws.account origin { domain_name = aws_s3_bucket.policybucket.bucket_regional_domain_name diff --git a/variables.tf b/variables.tf index d2afd0e..093e288 100644 --- a/variables.tf +++ b/variables.tf @@ -1,3 +1,9 @@ +variable "cf_price_class" { + type = string + default = "PriceClass_100" + description = "The price class for the MTA STS CloudFront distribution. Options: PriceClass_100 (North America and Europe), PriceClass_200 (North America, Europe, Asia, Middle East, and Africa) or PriceClass_All (all edge locations)." +} + variable "domain" { type = string description = "The domain MTA-STS/TLS-RPT is being deployed for." From 134ccb6cadb811aae44ea21c82b7b877572273c2 Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 16:40:08 +0100 Subject: [PATCH 14/16] Add CloudFront WAF ACL variable. --- main.tf | 1 + variables.tf | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/main.tf b/main.tf index 1b3fbb3..518c8c8 100644 --- a/main.tf +++ b/main.tf @@ -72,6 +72,7 @@ resource "aws_cloudfront_distribution" "s3_distribution" { aliases = [local.policydomain] enabled = true price_class = var.cf_price_class + web_acl_id = var.cf_waf_web_acl tags = local.tags provider = aws.account diff --git a/variables.tf b/variables.tf index 093e288..e9c425d 100644 --- a/variables.tf +++ b/variables.tf @@ -4,6 +4,12 @@ variable "cf_price_class" { description = "The price class for the MTA STS CloudFront distribution. Options: PriceClass_100 (North America and Europe), PriceClass_200 (North America, Europe, Asia, Middle East, and Africa) or PriceClass_All (all edge locations)." } +variable "cf_waf_web_acl" { + type = string + default = null + description = "AWS WAF web ACL to associate with the CloudFront distribution." +} + variable "domain" { type = string description = "The domain MTA-STS/TLS-RPT is being deployed for." From 7fc23a9fc77b4f7668da7ad4fa3bc769a37d815a Mon Sep 17 00:00:00 2001 From: gareth-e <53176667+ch-gareth@users.noreply.github.com> Date: Tue, 2 Aug 2022 17:07:59 +0100 Subject: [PATCH 15/16] Update S3 object inline heredoc to templatefile --- main.tf | 12 +++++++----- mta-sts.templatefile | 4 ++++ 2 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 mta-sts.templatefile diff --git a/main.tf b/main.tf index 518c8c8..d1cb90d 100644 --- a/main.tf +++ b/main.tf @@ -58,11 +58,13 @@ resource "aws_s3_bucket_acl" "policybucket_acl" { resource "aws_s3_object" "mtastspolicyfile" { key = ".well-known/mta-sts.txt" bucket = aws_s3_bucket.policybucket.id - content = < Date: Tue, 2 Aug 2022 17:18:14 +0100 Subject: [PATCH 16/16] Add optional variable examples. --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b7b674..fd6a751 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ This consists of using CloudFront/S3 with a Custom Domain to host the MTA-STS po This module assumes AWS Account with access to Route53, CloudFront, S3, and ACM, which also hosts the DNS (in Route53) for the domain you wish to deploy MTA-STS/TLS-RPT. The providers are defined here to allow resources to be provisioned in both `us-east-1` and a local region (`eu-west-2` in this example). This method also allows additional providers to be defined for additional AWS accounts / profiles, if required. +Note some variables (such as `cf_waf_web_acl`, `cf_price_class`, `mode`, `tags`, etc.) are optional. `See variables.tf` for defaults. ```terraform provider "aws" { @@ -32,7 +33,9 @@ module "mtastspolicy_examplecom" { mx = ["mail.example.com"] mode = "testing" reporting_email = "tlsreporting@example.com" - + cf_price_class = "PriceClass_200" + cf_waf_web_acl = "arn:aws:waf___" + tags = { "Terraform_source_repo" = "my-terraform-mta-sts-repo" } providers = { aws.useast1 = aws.useast1 aws.account = aws.myregion