Skip to content

Commit

Permalink
feat: Allow multiple domains in a single certificate (#149)
Browse files Browse the repository at this point in the history
Co-authored-by: Andres Montalban <[email protected]>
  • Loading branch information
alemarmed and amontalban authored Aug 13, 2024
1 parent f421377 commit 54e5422
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ No modules.
| <a name="input_validation_timeout"></a> [validation\_timeout](#input\_validation\_timeout) | Define maximum timeout to wait for the validation to complete | `string` | `null` | no |
| <a name="input_wait_for_validation"></a> [wait\_for\_validation](#input\_wait\_for\_validation) | Whether to wait for the validation to complete | `bool` | `true` | no |
| <a name="input_zone_id"></a> [zone\_id](#input\_zone\_id) | The ID of the hosted zone to contain this record. Required when validating via Route53 | `string` | `""` | no |
| <a name="input_zones"></a> [zones](#input\_zones) | Map containing the Route53 Zone IDs for additional domains. | `map(string)` | `{}` | no |

## Outputs

Expand Down
9 changes: 8 additions & 1 deletion examples/complete-dns-validation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,26 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Source | Version |
|------|--------|---------|
| <a name="module_acm"></a> [acm](#module\_acm) | ../../ | n/a |
| <a name="module_acm_multi_domain"></a> [acm\_multi\_domain](#module\_acm\_multi\_domain) | ../../ | n/a |
| <a name="module_acm_only"></a> [acm\_only](#module\_acm\_only) | ../../ | n/a |
| <a name="module_route53_records_only"></a> [route53\_records\_only](#module\_route53\_records\_only) | ../../ | n/a |

## Resources

| Name | Type |
|------|------|
| [aws_route53_zone.extra](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource |
| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource |
| [aws_route53_zone.extra](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source |
| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source |

## Inputs

No inputs.
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_domain"></a> [domain](#input\_domain) | Domain to be used for the tests | `string` | `"terraform-aws-modules.modules.tf"` | no |
| <a name="input_extra_domain"></a> [extra\_domain](#input\_extra\_domain) | Extra domain to be used in acm\_multi\_domain module | `string` | `"extra.terraform-aws-modules.modules.tf"` | no |
| <a name="input_use_existing_route53_zone"></a> [use\_existing\_route53\_zone](#input\_use\_existing\_route53\_zone) | Use existing (via data source) or create new zone (will fail validation, if zone is not reachable) | `bool` | `true` | no |

## Outputs

Expand Down
48 changes: 46 additions & 2 deletions examples/complete-dns-validation/main.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
locals {
# Use existing (via data source) or create new zone (will fail validation, if zone is not reachable)
use_existing_route53_zone = true
use_existing_route53_zone = var.use_existing_route53_zone

domain = "terraform-aws-modules.modules.tf"
domain = var.domain
extra_domain = var.extra_domain

# Removing trailing dot from domain - just to be sure :)
domain_name = trimsuffix(local.domain, ".")
Expand Down Expand Up @@ -103,3 +104,46 @@ module "route53_records_only" {

acm_certificate_domain_validation_options = module.acm_only.acm_certificate_domain_validation_options
}

###############################################################################
# Example 3:
# Single certificate with multiple domains from different Route53 hosted zones.
# Useful when using the certificate for CloudFront, which only support a
# single certificate per distribution.
###############################################################################

data "aws_route53_zone" "extra" {
count = local.use_existing_route53_zone ? 1 : 0

name = local.extra_domain
private_zone = false
}

resource "aws_route53_zone" "extra" {
count = !local.use_existing_route53_zone ? 1 : 0

name = local.extra_domain
}

module "acm_multi_domain" {
source = "../../"

domain_name = local.domain_name
zone_id = local.zone_id

subject_alternative_names = [
"*.alerts.${local.domain_name}",
"new.sub.${local.domain_name}",
local.extra_domain,
"*.alerts.${local.extra_domain}",
"new.sub.${local.extra_domain}",
]

validation_method = "DNS"

zones = {
(local.extra_domain) = try(data.aws_route53_zone.extra[0].zone_id, aws_route53_zone.extra[0].zone_id),
"alerts.${local.extra_domain}" = try(data.aws_route53_zone.extra[0].zone_id, aws_route53_zone.extra[0].zone_id),
"new.sub.${local.extra_domain}" = try(data.aws_route53_zone.extra[0].zone_id, aws_route53_zone.extra[0].zone_id)
}
}
17 changes: 17 additions & 0 deletions examples/complete-dns-validation/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
variable "use_existing_route53_zone" {
description = "Use existing (via data source) or create new zone (will fail validation, if zone is not reachable)"
type = bool
default = true
}

variable "domain" {
description = "Domain to be used for the tests"
type = string
default = "terraform-aws-modules.modules.tf"
}

variable "extra_domain" {
description = "Extra domain to be used in acm_multi_domain module"
type = string
default = "extra.terraform-aws-modules.modules.tf"
}
2 changes: 1 addition & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ resource "aws_acm_certificate" "this" {
resource "aws_route53_record" "validation" {
count = (local.create_certificate || local.create_route53_records_only) && var.validation_method == "DNS" && var.create_route53_records && (var.validate_certificate || local.create_route53_records_only) ? length(local.distinct_domain_names) : 0

zone_id = var.zone_id
zone_id = lookup(var.zones, element(local.validation_domains, count.index)["domain_name"], var.zone_id)
name = element(local.validation_domains, count.index)["resource_record_name"]
type = element(local.validation_domains, count.index)["resource_record_type"]
ttl = var.dns_ttl
Expand Down
6 changes: 6 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ variable "zone_id" {
default = ""
}

variable "zones" {
description = "Map containing the Route53 Zone IDs for additional domains."
type = map(string)
default = {}
}

variable "tags" {
description = "A mapping of tags to assign to the resource"
type = map(string)
Expand Down
1 change: 1 addition & 0 deletions wrappers/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ module "wrapper" {
validation_timeout = try(each.value.validation_timeout, var.defaults.validation_timeout, null)
wait_for_validation = try(each.value.wait_for_validation, var.defaults.wait_for_validation, true)
zone_id = try(each.value.zone_id, var.defaults.zone_id, "")
zones = try(each.value.zones, var.defaults.zones, {})
}

0 comments on commit 54e5422

Please sign in to comment.