diff --git a/.github/workflows/validate-codeowners.yml b/.github/workflows/validate-codeowners.yml index 70f829e..4b4a226 100644 --- a/.github/workflows/validate-codeowners.yml +++ b/.github/workflows/validate-codeowners.yml @@ -10,6 +10,7 @@ jobs: steps: - name: "Checkout source code at current commit" uses: actions/checkout@v2 + # Leave pinned at 0.7.1 until https://github.com/mszostok/codeowners-validator/issues/173 is resolved - uses: mszostok/codeowners-validator@v0.7.1 if: github.event.pull_request.head.repo.full_name == github.repository name: "Full check of CODEOWNERS" diff --git a/README.md b/README.md index 227c76b..b11f0be 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,6 @@ Available targets: | Name | Type | |------|------| | [aws_acm_certificate.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource | -| [aws_acm_certificate_validation.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation) | resource | | [aws_route53_record.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | [aws_route53_zone.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source | @@ -192,7 +191,7 @@ Available targets: | [process\_domain\_validation\_options](#input\_process\_domain\_validation\_options) | Flag to enable/disable processing of the record to add to the DNS zone to complete certificate validation | `bool` | `true` | no | | [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | | [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | -| [subject\_alternative\_names](#input\_subject\_alternative\_names) | A list of domains that should be SANs in the issued certificate | `list(string)` | `[]` | no | +| [subject\_alternative\_names](#input\_subject\_alternative\_names) | A list of domains that should be SANs in the issued certificate | `any` |
[
{}
]
| no | | [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no | | [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no | | [ttl](#input\_ttl) | The TTL of the record to add to the DNS zone to complete certificate validation | `string` | `"300"` | no | @@ -205,11 +204,7 @@ Available targets: | Name | Description | |------|-------------| -| [arn](#output\_arn) | The ARN of the certificate | -| [domain\_validation\_options](#output\_domain\_validation\_options) | CNAME records that are added to the DNS zone to complete certificate validation | -| [id](#output\_id) | The ID of the certificate | -| [validation\_certificate\_arn](#output\_validation\_certificate\_arn) | Certificate ARN from the `aws_acm_certificate_validation` resource | -| [validation\_id](#output\_validation\_id) | The ID of the certificate validation | +| [unique\_zones](#output\_unique\_zones) | n/a | diff --git a/docs/terraform.md b/docs/terraform.md index 81a2725..442ed4d 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -23,7 +23,6 @@ | Name | Type | |------|------| | [aws_acm_certificate.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource | -| [aws_acm_certificate_validation.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation) | resource | | [aws_route53_record.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | [aws_route53_zone.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source | @@ -51,7 +50,7 @@ | [process\_domain\_validation\_options](#input\_process\_domain\_validation\_options) | Flag to enable/disable processing of the record to add to the DNS zone to complete certificate validation | `bool` | `true` | no | | [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | | [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | -| [subject\_alternative\_names](#input\_subject\_alternative\_names) | A list of domains that should be SANs in the issued certificate | `list(string)` | `[]` | no | +| [subject\_alternative\_names](#input\_subject\_alternative\_names) | A list of domains that should be SANs in the issued certificate | `any` |
[
{}
]
| no | | [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no | | [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no | | [ttl](#input\_ttl) | The TTL of the record to add to the DNS zone to complete certificate validation | `string` | `"300"` | no | @@ -64,9 +63,5 @@ | Name | Description | |------|-------------| -| [arn](#output\_arn) | The ARN of the certificate | -| [domain\_validation\_options](#output\_domain\_validation\_options) | CNAME records that are added to the DNS zone to complete certificate validation | -| [id](#output\_id) | The ID of the certificate | -| [validation\_certificate\_arn](#output\_validation\_certificate\_arn) | Certificate ARN from the `aws_acm_certificate_validation` resource | -| [validation\_id](#output\_validation\_id) | The ID of the certificate validation | +| [unique\_zones](#output\_unique\_zones) | n/a | diff --git a/main.tf b/main.tf index 9984a78..86d5e0a 100644 --- a/main.tf +++ b/main.tf @@ -7,13 +7,22 @@ locals { all_domains = concat( [var.domain_name], - var.subject_alternative_names + [for name in var.subject_alternative_names : name["names"]] ) - domain_to_zone = { - for domain in local.all_domains : - domain => join(".", slice(split(".", domain), 1, length(split(".", domain)))) + + unique_zones = distinct(values(local.domain_to_zones)) + domain_to_zones = { + for zone in var.subject_alternative_names : zone.zone_to_lookup => zone.names } - unique_zones = distinct(values(local.domain_to_zone)) + zones = keys(local.domain_to_zones) +} + + +data "aws_route53_zone" "default" { + for_each = local.process_domain_validation_options ? toset(local.zones) : toset([]) + zone_id = var.zone_id + name = try(length(var.zone_id), 0) == 0 ? (var.zone_name == "" ? each.key : var.zone_name) : null + private_zone = local.private_enabled } resource "aws_acm_certificate" "default" { @@ -21,7 +30,7 @@ resource "aws_acm_certificate" "default" { domain_name = var.domain_name validation_method = local.public_enabled ? var.validation_method : null - subject_alternative_names = var.subject_alternative_names + subject_alternative_names = flatten([for name in var.subject_alternative_names : name["names"]]) certificate_authority_arn = var.certificate_authority_arn options { @@ -35,11 +44,15 @@ resource "aws_acm_certificate" "default" { } } -data "aws_route53_zone" "default" { - for_each = local.process_domain_validation_options ? toset(local.unique_zones) : toset([]) - zone_id = var.zone_id - name = try(length(var.zone_id), 0) == 0 ? (var.zone_name == "" ? each.key : var.zone_name) : null - private_zone = local.private_enabled +# data "aws_route53_zone" "default" { +# for_each = local.process_domain_validation_options ? toset(local.unique_zones) : toset([]) +# zone_id = var.zone_id +# name = try(length(var.zone_id), 0) == 0 ? (var.zone_name == "" ? each.key : var.zone_name) : null +# private_zone = local.private_enabled +# } + +output "unique_zones" { + value = data.aws_route53_zone.default } resource "aws_route53_record" "default" { @@ -50,7 +63,7 @@ resource "aws_route53_record" "default" { type = dvo.resource_record_type } } - zone_id = data.aws_route53_zone.default[local.domain_to_zone[each.key]].id + zone_id = data.aws_route53_zone.default[local.domain_to_zones[each.value.name]].id ttl = var.ttl allow_overwrite = true name = each.value.name @@ -58,8 +71,8 @@ resource "aws_route53_record" "default" { records = [each.value.record] } -resource "aws_acm_certificate_validation" "default" { - count = local.process_domain_validation_options && var.wait_for_certificate_issued ? 1 : 0 - certificate_arn = join("", aws_acm_certificate.default.*.arn) - validation_record_fqdns = [for record in aws_route53_record.default : record.fqdn] -} +# resource "aws_acm_certificate_validation" "default" { +# count = local.process_domain_validation_options && var.wait_for_certificate_issued ? 1 : 0 +# certificate_arn = join("", aws_acm_certificate.default.*.arn) +# validation_record_fqdns = [for record in aws_route53_record.default : record.fqdn] +# } diff --git a/outputs.tf b/outputs.tf index 14a97bd..9912dcd 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,25 +1,28 @@ -output "id" { - value = join("", aws_acm_certificate.default.*.id) - description = "The ID of the certificate" -} +# output "id" { +# value = join("", aws_acm_certificate.default.*.id) +# description = "The ID of the certificate" +# } -output "arn" { - value = join("", aws_acm_certificate.default.*.arn) - description = "The ARN of the certificate" -} +# output "arn" { +# value = join("", aws_acm_certificate.default.*.arn) +# description = "The ARN of the certificate" +# } -output "domain_validation_options" { - value = aws_acm_certificate.default.*.domain_validation_options - description = "CNAME records that are added to the DNS zone to complete certificate validation" -} +# output "domain_validation_options" { +# value = aws_acm_certificate.default.*.domain_validation_options +# description = "CNAME records that are added to the DNS zone to complete certificate validation" +# } -output "validation_id" { - value = join("", aws_acm_certificate_validation.default.*.id) - description = "The ID of the certificate validation" -} +# output "validation_id" { +# value = join("", aws_acm_certificate_validation.default.*.id) +# description = "The ID of the certificate validation" +# } -output "validation_certificate_arn" { - value = join("", aws_acm_certificate_validation.default.*.certificate_arn) - description = "Certificate ARN from the `aws_acm_certificate_validation` resource" -} +# output "validation_certificate_arn" { +# value = join("", aws_acm_certificate_validation.default.*.certificate_arn) +# description = "Certificate ARN from the `aws_acm_certificate_validation` resource" +# } +# output "unique_zones" { +# value = local.unique_zones +# } \ No newline at end of file diff --git a/variables.tf b/variables.tf index defee1e..3564b6a 100644 --- a/variables.tf +++ b/variables.tf @@ -32,17 +32,6 @@ variable "ttl" { description = "The TTL of the record to add to the DNS zone to complete certificate validation" } -variable "subject_alternative_names" { - type = list(string) - default = [] - description = "A list of domains that should be SANs in the issued certificate" - - validation { - condition = length([for name in var.subject_alternative_names : name if can(regex("[A-Z]", name))]) == 0 - error_message = "All SANs must be lower-case." - } -} - variable "zone_name" { type = string default = "" @@ -66,3 +55,14 @@ variable "certificate_authority_arn" { default = null description = "ARN of an ACM PCA" } + +variable "subject_alternative_names" { + type = any + default = [{}] + description = "A list of domains that should be SANs in the issued certificate" + + validation { + condition = length([for name in var.subject_alternative_names : name if can(regex("[A-Z]", name))]) == 0 + error_message = "All SANs must be lower-case." + } +} \ No newline at end of file