Skip to content

Commit a2e4af9

Browse files
rodrigoAguirre1rodrigo.aguirre
andauthored
feat(multiple-hosted-zones): the zones variable was added to support multiple hosted zones (#7)
* feat(multiple-hosted-zones): the zone_id variable was modified to support a hosted zone id list. * feat(multiple-hosted-zones): deleting test variables. * feat(multiple-hosted-zones): deleting test variables. * feat(multiple-hosted-zones): fix multiple hosted zones. * feat(multiple-hosted-zones): terraform format. * feat(multiple-hosted-zones): adding multiple hosted zone example. * feat(multiple-hosted-zones): adding comments in multiple hosted zone example. --------- Co-authored-by: rodrigo.aguirre <[email protected]>
1 parent 4ebd6c7 commit a2e4af9

File tree

5 files changed

+130
-24
lines changed

5 files changed

+130
-24
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# ---------------------------------------------------------------------------------------------------------------------
2+
# Example (use multiple domains in the same certificate):
3+
# Generate an ACM certificate for multiple domains, useful
4+
# to be used in CloudFront which only supports one ACM
5+
# certificate.
6+
# ---------------------------------------------------------------------------------------------------------------------
7+
8+
# REF: https://github.com/terraform-aws-modules/terraform-aws-acm/pull/137
9+
10+
locals {
11+
zone_id = try(data.aws_route53_zone.this[0].zone_id, aws_route53_zone.this[0].zone_id)
12+
}
13+
14+
provider "aws" {
15+
region = var.aws_region
16+
}
17+
18+
# If you already have the hosted zones, they can be used to test this example.
19+
# Just set the use_existing_route53_zone variable as true and configure the
20+
# domain_name and extra_domain variables with the correspond values.
21+
data "aws_route53_zone" "this" {
22+
count = var.use_existing_route53_zone ? 1 : 0
23+
24+
name = var.domain_name
25+
private_zone = false
26+
}
27+
28+
data "aws_route53_zone" "extra" {
29+
count = var.use_existing_route53_zone ? 1 : 0
30+
31+
name = var.extra_domain
32+
private_zone = false
33+
}
34+
35+
# If you need to deploy also the hosted zones for test the example, then
36+
# set the use_existing_route53_zone variable as false. This way, the example will
37+
# create both hosted zones, using the domain_name and extra_domain values.
38+
resource "aws_route53_zone" "this" {
39+
count = !var.use_existing_route53_zone ? 1 : 0
40+
41+
name = var.domain_name
42+
}
43+
44+
resource "aws_route53_zone" "extra" {
45+
count = !var.use_existing_route53_zone ? 1 : 0
46+
47+
name = var.extra_domain
48+
}
49+
50+
module "acm_multi_domain" {
51+
source = "../../modules/acm/"
52+
53+
domain_name = var.domain_name
54+
zone_id = local.zone_id
55+
56+
subject_alternative_names = [
57+
"*.alerts.${var.domain_name}",
58+
"new.sub.${var.domain_name}",
59+
"*.${var.domain_name}",
60+
"alerts.${var.domain_name}",
61+
"*.alerts.${var.extra_domain}",
62+
"new.sub.${var.extra_domain}",
63+
"*.${var.extra_domain}",
64+
"alerts.${var.extra_domain}",
65+
var.extra_domain,
66+
"*.${var.extra_domain}"
67+
]
68+
69+
# Each extra subdomain must be mapped to the correct zone id.
70+
# If not, the module creates the records using the zone_id variable (not the
71+
# extra domain zone id) and the validation will fail.
72+
zones = {
73+
(var.extra_domain) = try(data.aws_route53_zone.extra[0].zone_id, aws_route53_zone.extra[0].zone_id),
74+
"alerts.${local.extra_domain}" = try(data.aws_route53_zone.extra[0].zone_id, aws_route53_zone.extra[0].zone_id),
75+
"new.sub.${local.extra_domain}" = try(data.aws_route53_zone.extra[0].zone_id, aws_route53_zone.extra[0].zone_id)
76+
}
77+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
variable "use_existing_route53_zone" {
2+
description = "Use existing (via data source) or create new zone (will fail validation, if zone is not reachable)"
3+
type = bool
4+
default = true
5+
}
6+
7+
variable "domain_name" {
8+
description = "Domain to be used for the tests"
9+
type = string
10+
default = "terraform-aws-modules.modules.tf"
11+
}
12+
13+
variable "extra_domain" {
14+
description = "Extr adomain to be used for the tests"
15+
type = string
16+
default = "extra.terraform-aws-modules.modules.tf"
17+
}
18+
19+
variable "aws_region" {
20+
description = "The AWS Region where this VPC will exist."
21+
type = string
22+
default = "us-east-1"
23+
}

modules/acm/main.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ resource "aws_acm_certificate" "this" {
5454
resource "aws_route53_record" "validation" {
5555
count = var.create_certificate && var.validation_method == "DNS" && var.validate_certificate ? length(local.distinct_domain_names) : 0
5656

57-
zone_id = var.zone_id
57+
zone_id = lookup(var.zones, element(local.validation_domains, count.index)["domain_name"], var.zone_id)
5858
name = element(local.validation_domains, count.index)["resource_record_name"]
5959
type = element(local.validation_domains, count.index)["resource_record_type"]
6060
ttl = var.dns_ttl
@@ -73,5 +73,5 @@ resource "aws_acm_certificate_validation" "this" {
7373

7474
certificate_arn = aws_acm_certificate.this[0].arn
7575

76-
validation_record_fqdns = aws_route53_record.validation.*.fqdn
76+
validation_record_fqdns = aws_route53_record.validation[*].fqdn
7777
}

modules/acm/outputs.tf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
output "acm_certificate_arn" {
22
description = "The ARN of the certificate"
3-
value = element(concat(aws_acm_certificate_validation.this.*.certificate_arn, aws_acm_certificate.this.*.arn, [""]), 0)
3+
value = element(concat(aws_acm_certificate_validation.this[*].certificate_arn, aws_acm_certificate.this[*].arn, [""]), 0)
44
}
55

66
output "acm_certificate_domain_validation_options" {
77
description = "A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used."
8-
value = flatten(aws_acm_certificate.this.*.domain_validation_options)
8+
value = flatten(aws_acm_certificate.this[*].domain_validation_options)
99
}
1010

1111
output "acm_certificate_validation_emails" {
1212
description = "A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used."
13-
value = flatten(aws_acm_certificate.this.*.validation_emails)
13+
value = flatten(aws_acm_certificate.this[*].validation_emails)
1414
}
1515

1616
output "validation_route53_record_fqdns" {
1717
description = "List of FQDNs built using the zone domain and name."
18-
value = aws_route53_record.validation.*.fqdn
18+
value = aws_route53_record.validation[*].fqdn
1919
}
2020

2121
output "distinct_domain_names" {

modules/acm/variables.tf

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,12 @@ variable "certificate_transparency_logging_preference" {
2828
default = true
2929
}
3030

31-
variable "domain_name" {
32-
description = "A domain name for which the certificate should be issued"
33-
type = string
34-
default = ""
35-
}
36-
37-
variable "subject_alternative_names" {
38-
description = "A list of domains that should be SANs in the issued certificate"
39-
type = list(string)
40-
default = []
41-
}
42-
4331
variable "validation_method" {
4432
description = "Which method to use for validation. DNS or EMAIL are valid, NONE can be used for certificates that were imported into ACM and then into Terraform."
4533
type = string
4634
default = "DNS"
4735
}
4836

49-
variable "zone_id" {
50-
description = "The ID of the hosted zone to contain this record."
51-
type = string
52-
default = ""
53-
}
54-
5537
variable "tags" {
5638
description = "A mapping of tags to assign to the resource"
5739
type = map(string)
@@ -63,3 +45,27 @@ variable "dns_ttl" {
6345
type = number
6446
default = 60
6547
}
48+
49+
variable "zone_id" {
50+
description = "The ID of the hosted zone to contain this record. Required when validating via Route53"
51+
type = string
52+
default = ""
53+
}
54+
55+
variable "zones" {
56+
description = "Map containing the Route53 Zone IDs for additional domains."
57+
type = map(string)
58+
default = {}
59+
}
60+
61+
variable "domain_name" {
62+
description = "A domain name for which the certificate should be issued"
63+
type = string
64+
default = ""
65+
}
66+
67+
variable "subject_alternative_names" {
68+
description = "A list of domains that should be SANs in the issued certificate"
69+
type = list(string)
70+
default = []
71+
}

0 commit comments

Comments
 (0)