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

feat: Allow multiple domains in one cert #137

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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) | Extr adomain to be used for the tests | `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
71 changes: 65 additions & 6 deletions examples/complete-dns-validation/main.tf
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
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, ".")

region = "us-east-1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this region, too.


zone_id = try(data.aws_route53_zone.this[0].zone_id, aws_route53_zone.this[0].zone_id)
}

Expand All @@ -32,8 +35,7 @@ module "acm" {
source = "../../"

providers = {
aws.acm = aws,
aws.dns = aws
aws = aws.acm
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While your change is valid, please revert to show that there can be two distinct providers passed to the module.

}

domain_name = local.domain_name
Expand All @@ -60,11 +62,13 @@ module "acm" {
################################################################

provider "aws" {
alias = "route53"
alias = "route53"
region = local.region
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert all changes not necessary for your PR.

}

provider "aws" {
alias = "acm"
alias = "acm"
region = local.region
}

module "acm_only" {
Expand Down Expand Up @@ -103,3 +107,58 @@ module "route53_records_only" {

acm_certificate_domain_validation_options = module.acm_only.acm_certificate_domain_validation_options
}

##########################################################
# Example 3 (use multiple domains in the same certificate):
# Generate an ACM certificate for multiple domains, useful
# to be used in CloudFront which only supports one ACM
# certificate.
##########################################################

provider "aws" {
region = local.region
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove region as it is not important for this example.

}

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.domain_name}",
"alerts.${local.domain_name}",
"*.alerts.${local.extra_domain}",
"new.sub.${local.extra_domain}",
"*.${local.extra_domain}",
"alerts.${local.extra_domain}",
local.extra_domain,
"*.${local.extra_domain}"
]

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)
}

tags = {
Name = local.domain_name
Extra_Domain = local.extra_domain
}
}
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 = "Extr adomain to be used for the tests"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description = "Extr adomain to be used for the tests"
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 @@ -17,6 +17,7 @@ module "wrapper" {
create_route53_records = try(each.value.create_route53_records, var.defaults.create_route53_records, true)
validation_record_fqdns = try(each.value.validation_record_fqdns, var.defaults.validation_record_fqdns, [])
zone_id = try(each.value.zone_id, var.defaults.zone_id, "")
zones = try(each.value.zones, var.defaults.zones, {})
tags = try(each.value.tags, var.defaults.tags, {})
dns_ttl = try(each.value.dns_ttl, var.defaults.dns_ttl, 60)
acm_certificate_domain_validation_options = try(each.value.acm_certificate_domain_validation_options, var.defaults.acm_certificate_domain_validation_options, {})
Expand Down