From 85aeb88a31d70b4d9227a5a56af95be7fd978d49 Mon Sep 17 00:00:00 2001 From: "alexander.miehe" Date: Tue, 2 Jan 2024 13:53:16 +0100 Subject: [PATCH] PLT-0 - Allow to add additional domains and destroy resources * allow additional domains * allow to destroy resources --- README.md | 4 +++ main.tf | 72 +++++++++++++++++++++++++++++++++++++++++++++------- outputs.tf | 2 +- variables.tf | 15 +++++++++++ 4 files changed, 83 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 79e6c3b..1e82212 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ This module will create cdn endpoint with alias and SSL-certificate and optional | Name | Source | Version | |------|--------|---------| | [certificate](#module\_certificate) | github.com/terraform-aws-modules/terraform-aws-acm | v5.0.0 | +| [certificate-validations](#module\_certificate-validations) | github.com/terraform-aws-modules/terraform-aws-acm | v5.0.0 | | [cloudfront](#module\_cloudfront) | github.com/terraform-aws-modules/terraform-aws-cloudfront | v3.2.1 | ## Resources @@ -29,6 +30,7 @@ This module will create cdn endpoint with alias and SSL-certificate and optional | Name | Type | |------|------| | [aws_cloudfront_function.functions](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_function) | resource | +| [aws_route53_record.additional_records](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | [aws_route53_record.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | [aws_s3_bucket_policy.s3_origin_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource | | [null_resource.either_s3_origin_hostname_or_s3_origin_name_is_required](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | @@ -43,8 +45,10 @@ This module will create cdn endpoint with alias and SSL-certificate and optional |------|-------------|------|---------|:--------:| | [r53\_hostname](#input\_r53\_hostname) | Hostname for CloudFront alias | `string` | n/a | yes | | [r53\_zone\_id](#input\_r53\_zone\_id) | Route53 zone ID to be used for hostname and certificate validation | `string` | n/a | yes | +| [additional\_zones](#input\_additional\_zones) | Map containing the Route53 Zone IDs and hostnames for additional domains |
map(object({
zone_id = string
hostname = string
}))
| `{}` | no | | [cdn\_logging](#input\_cdn\_logging) | Prefix in s3 bucket for cdn logs | `string` | `""` | no | | [cf\_functions](#input\_cf\_functions) | The Cloud Front function configuration
{type = object{}} ie. {"viewer-request" = object{}}
*type:*
Allowed cf event types are viewer-request and viewer-response
*name:*
Name of the function
*comment:*
Description of the function
*code:*
Source code of the function
*assign:*
true for associating the function with the cf distribution,
false to remove the association. (to remove the cf function firstly set it
to false to dissociate from the cf distribution) |
map(object({
name = string
comment = string
code = string
assign = bool
}))
| `{}` | no | +| [create](#input\_create) | Whether to create the resources | `bool` | `true` | no | | [create\_origin\_access\_control](#input\_create\_origin\_access\_control) | Controls if CloudFront origin access control should be created | `bool` | `false` | no | | [create\_origin\_access\_identity](#input\_create\_origin\_access\_identity) | Controls if CloudFront origin access identity should be created | `bool` | `true` | no | | [default\_root\_object](#input\_default\_root\_object) | The object that you want CloudFront to return (for example, index.html) when an end user requests the root URL. | `string` | `null` | no | diff --git a/main.tf b/main.tf index 2ef7f07..dd10f78 100644 --- a/main.tf +++ b/main.tf @@ -1,3 +1,13 @@ +moved { + from = module.certificate.aws_route53_record.validation[0] + to = module.certificate-validations["single"].aws_route53_record.validation[0] +} + +moved { + from = aws_route53_record.this + to = aws_route53_record.this[0] +} + locals { origin_hostname_options = { use_host = var.s3_origin_hostname != "" ? var.s3_origin_hostname : null @@ -5,7 +15,7 @@ locals { } origin_hostname = local.origin_hostname_options[var.s3_origin_name != "" ? "use_name" : "use_host"] - override_origin_policy = var.override_s3_origin_policy && var.s3_origin_name != "" + override_origin_policy = var.override_s3_origin_policy && var.s3_origin_name != "" && var.create function_association = { for type, func in var.cf_functions : type => { function_arn = aws_cloudfront_function.functions[type].arn } if func.assign } @@ -33,13 +43,18 @@ locals { } }) : tomap({}) origin_oac = var.create_origin_access_control ? tomap({ - s3_origin = { + s3_origin_oac = { domain_name = data.aws_s3_bucket.s3_origin[0].bucket_domain_name origin_access_control = local.oac_key } }) : tomap({}) - target_origin_id = var.create_origin_access_control ? "s3_origin_oac" : "s3_origin" + r53_map = merge(tomap({ + single = { + zone_id = var.r53_zone_id + hostname = var.r53_hostname + } + }), var.additional_zones) } # Workaround for the input variable validation @@ -59,12 +74,32 @@ data "aws_s3_bucket" "s3_origin" { module "certificate" { source = "github.com/terraform-aws-modules/terraform-aws-acm?ref=v5.0.0" - tags = var.tags + #for_each = local.r53_map + tags = var.tags + + domain_name = local.r53_map["single"].hostname + zone_id = local.r53_map["single"].zone_id + validation_method = "DNS" + subject_alternative_names = [for s in values(local.r53_map) : s.hostname] + create_route53_records = false + create_certificate = var.create + providers = { + aws = aws.us-east-1 + } +} - domain_name = var.r53_hostname - zone_id = var.r53_zone_id - validation_method = "DNS" +module "certificate-validations" { + source = "github.com/terraform-aws-modules/terraform-aws-acm?ref=v5.0.0" + for_each = local.r53_map + tags = var.tags + domain_name = each.value.hostname + zone_id = each.value.zone_id + validation_method = "DNS" + #subject_alternative_names = [for k,s in values(var.r53_zone_hostname_map) : s.hostname if k > 0] + create_route53_records_only = true && var.create + create_certificate = false + acm_certificate_domain_validation_options = [for s in module.certificate.acm_certificate_domain_validation_options : s if s.domain_name == each.value.hostname] providers = { aws = aws.us-east-1 } @@ -73,7 +108,7 @@ module "certificate" { module "cloudfront" { source = "github.com/terraform-aws-modules/terraform-aws-cloudfront?ref=v3.2.1" tags = var.tags - aliases = [var.r53_hostname] + aliases = [for s in values(local.r53_map) : s.hostname] enabled = true is_ipv6_enabled = true @@ -81,6 +116,8 @@ module "cloudfront" { retain_on_delete = false wait_for_deployment = false + create_distribution = var.create + default_root_object = var.default_root_object create_origin_access_identity = var.create_origin_access_identity @@ -97,7 +134,7 @@ module "cloudfront" { origin = merge(local.origin_oai, local.origin_oac) default_cache_behavior = { - target_origin_id = local.target_origin_id + target_origin_id = "s3_origin_oac" viewer_protocol_policy = "redirect-to-https" allowed_methods = ["GET", "HEAD", "OPTIONS"] @@ -156,6 +193,8 @@ resource "aws_s3_bucket_policy" "s3_origin_policy" { } resource "aws_route53_record" "this" { + count = var.create ? 1 : 0 + zone_id = var.r53_zone_id name = var.r53_hostname type = "A" @@ -168,6 +207,21 @@ resource "aws_route53_record" "this" { } } +resource "aws_route53_record" "additional_records" { + for_each = var.additional_zones + + zone_id = each.value.zone_id + name = each.value.hostname + type = "A" + + alias { + zone_id = module.cloudfront.cloudfront_distribution_hosted_zone_id + name = module.cloudfront.cloudfront_distribution_domain_name + + evaluate_target_health = false + } +} + resource "aws_cloudfront_function" "functions" { for_each = var.cf_functions diff --git a/outputs.tf b/outputs.tf index df2c5dd..ff7b81d 100644 --- a/outputs.tf +++ b/outputs.tf @@ -20,5 +20,5 @@ output "cloudfront_hosted_zone_id" { output "cloudfront_alias" { description = "Alias hostname of CloudFront distribution" - value = aws_route53_record.this.fqdn + value = try(aws_route53_record.this[0].fqdn, null) } diff --git a/variables.tf b/variables.tf index 09275e8..e065e25 100644 --- a/variables.tf +++ b/variables.tf @@ -97,3 +97,18 @@ variable "create_origin_access_control" { type = bool default = false } + +variable "additional_zones" { + description = "Map containing the Route53 Zone IDs and hostnames for additional domains" + type = map(object({ + zone_id = string + hostname = string + })) + default = {} +} + +variable "create" { + description = "Whether to create the resources" + type = bool + default = true +}