Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Functionality for adding external domain to the site #4

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
19 changes: 8 additions & 11 deletions examples/default/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,21 @@ provider "aws" {

provider "aws" {
region = "us-east-1"
alias = "certificate_provider"
alias = "certificate_provider"
}

data "aws_vpc" "main" {
default = true
}

data "aws_subnet_ids" "main" {
vpc_id = data.aws_vpc.main.id
resource "aws_route53_zone" "main" {
name = "example.com"
}

module "static-example" {
source = "../../"
source = "../../"
providers = {
aws.certificate_provider = aws.certificate_provider
}
name_prefix = "static-example"
hosted_zone_name = "example.com"
site_name = "static-example.example.com"
name_prefix = "static-example"
domain_zones = {
"static-example.example.com" = aws_route53_zone.main.id
}
}

4 changes: 4 additions & 0 deletions examples/default/versions.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@

terraform {
required_version = ">= 0.12"

required_providers {
aws = ">= 2.65.0"
}
}
64 changes: 43 additions & 21 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,60 @@
# ------------------------------------------------------------------------------
provider "aws" {
# Module expects aws.certificate_provider set to us-east-1 to be passed in via the "providers" argument
alias = "certificate_provider"
alias = "certificate_provider"
}

data "aws_caller_identity" "current-account" {}

locals {
validation_options_by_domain_name = { for opt in aws_acm_certificate.cert_website.domain_validation_options : opt.domain_name => opt }
all_domains_static = { for obj in concat([var.domain_name], var.subject_alternative_names) : obj.name => obj }
all_domains_dynamic = { for name, v in local.all_domains_static : name => merge(v, {
/*
// NOTE: `domain_validation_options` may reference stale data due to issues with the AWS provider,
// so we default to a known value if this is the case.
*/
validation_options = lookup(local.validation_options_by_domain_name, name, values(local.validation_options_by_domain_name)[0])
zone_id = data.aws_route53_zone.zone[name].id
})
}
}

data "aws_route53_zone" "zone" {
for_each = local.all_domains_static
name = each.value.zone
}

resource "aws_acm_certificate" "cert_website" {
domain_name = var.site_name
validation_method = "DNS"
provider = aws.certificate_provider
tags = var.tags
domain_name = var.domain_name.name
validation_method = "DNS"
provider = aws.certificate_provider
subject_alternative_names = [for obj in var.subject_alternative_names : obj.name]
tags = var.tags

lifecycle {
create_before_destroy = true
}
}

data "aws_route53_zone" "main" {
name = var.hosted_zone_name
}

resource "aws_route53_record" "cert_website_validation" {
name = aws_acm_certificate.cert_website.domain_validation_options.0.resource_record_name
type = aws_acm_certificate.cert_website.domain_validation_options.0.resource_record_type
zone_id = data.aws_route53_zone.main.id
records = [aws_acm_certificate.cert_website.domain_validation_options.0.resource_record_value]
ttl = 60
depends_on = [aws_acm_certificate.cert_website]
for_each = local.all_domains_static
name = local.all_domains_dynamic[each.key].validation_options.resource_record_name
type = local.all_domains_dynamic[each.key].validation_options.resource_record_type
records = [local.all_domains_dynamic[each.key].validation_options.resource_record_value]
zone_id = local.all_domains_dynamic[each.key].zone_id
ttl = 60
allow_overwrite = true
}

resource "aws_acm_certificate_validation" "main" {
certificate_arn = aws_acm_certificate.cert_website.arn
validation_record_fqdns = [aws_route53_record.cert_website_validation.fqdn]
provider = aws.certificate_provider
validation_record_fqdns = values(aws_route53_record.cert_website_validation).*.fqdn
timeouts {
create = var.certificate_validation_timeout
}
}

data "aws_s3_bucket" "website_bucket" {
Expand Down Expand Up @@ -82,7 +104,7 @@ resource "aws_cloudfront_distribution" "s3_distribution" {
enabled = true
is_ipv6_enabled = true
default_root_object = "index.html"
aliases = [aws_acm_certificate.cert_website.domain_name]
aliases = sort(keys(local.all_domains_static))

custom_error_response {
error_code = 404
Expand Down Expand Up @@ -136,11 +158,11 @@ resource "aws_cloudfront_distribution" "s3_distribution" {
}
}

resource "aws_route53_record" "wwww_a" {
name = "${var.site_name}."
type = "A"
zone_id = data.aws_route53_zone.main.id

resource "aws_route53_record" "www_a" {
for_each = local.all_domains_static
name = "${each.key}."
type = "A"
zone_id = data.aws_route53_zone.zone[each.key].id
alias {
name = aws_cloudfront_distribution.s3_distribution.domain_name
zone_id = aws_cloudfront_distribution.s3_distribution.hosted_zone_id
Expand Down
24 changes: 15 additions & 9 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ variable "name_prefix" {
type = string
}

variable "hosted_zone_name" {
description = "The name of the hosted zone in which to register this site"
type = string
}

variable "bucket_versioning" {
description = "(Optional) Enable versioning. Once you version-enable a bucket, it can never return to an unversioned state. You can, however, suspend versioning on that bucket."
type = bool
Expand All @@ -23,9 +18,14 @@ variable "tags" {
default = {}
}

variable "site_name" {
description = "The name of the certificate and address for the site"
type = string
variable "domain_name" {
description = "A map containing a domain and name of the associated hosted zone. The domain will be associated with the CloudFront distribution and ACM certificate."
type = map(string)
}

variable "subject_alternative_names" {
description = "A list of maps containing domains and names of their associated hosted zones. The domains will be associated with the CloudFront distribution and ACM certificate."
type = list(map(string))
}

variable "use_external_bucket" {
Expand All @@ -38,4 +38,10 @@ variable "website_bucket" {
description = "(Optional) The name of an existing bucket to use - if not set the module will create a bucket"
type = string
default = ""
}
}

variable "certificate_validation_timeout" {
description = "(Optional) How long to wait for the certificate to be issued."
type = string
default = "45m"
}
5 changes: 4 additions & 1 deletion versions.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

terraform {
required_version = ">= 0.12"

required_providers {
aws = ">= 2.65.0"
}
}