-
Notifications
You must be signed in to change notification settings - Fork 9.5k
aws_acm_certificate_validation - add simple example of an ACM validation with a wildcard alternate name #16913
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
Comments
I went through this today and I ended up with a solution that doesn't require declaring a local variable in advance. Instead, it leverages the fact that AWS ACM will generate the same validation data for both resource "cloudflare_record" "certificate_validation" {
for_each = {
for dvo in aws_acm_certificate.example.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
# Skips the domain if it doesn't contain a wildcard
if length(regexall("\\*\\..+", dvo.domain_name)) > 0
}
zone_id = cloudflare_zone.example.id
name = each.value.name
value = each.value.record
type = each.value.type
ttl = 1
proxied = false
} Notes
|
@renehernandez's was a nice solution, I was able to overcome the first limitation by checking if the wildcard domain exists in the certificate instead of checking if resource "aws_route53_record" "default" {
for_each = {
for dvo in aws_acm_certificate.default.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
// Skips the validation record if the certificate contains a wildcard for the same domain. Needed because AWS returns the same validation records for the wildcard domain.
if contains(concat([aws_acm_certificate.default.domain_name], tolist(aws_acm_certificate.default.subject_alternative_names)), "*.${dvo.domain_name}") == false
}
allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = data.aws_route53_zone.acm[each.key].zone_id
} Arguably, the whole contains and concat part is not the most readable. |
My solution, using locals:
|
Came up with a simpler workaround, using resource "aws_route53_record" "example" {
for_each = {
for dvo in aws_acm_certificate.example.domain_validation_options : dvo.resource_record_name => {
record = dvo.resource_record_value
type = dvo.resource_record_type
}...
}
allow_overwrite = true
name = each.key
records = [each.value[0].record]
ttl = 60
type = each.value[0].type
zone_id = aws_route53_zone.example.zone_id
} Since the ellipsis ( |
Alternatively, you can put if !startswith(dvo.domain_name, "*") In the resource "aws_route53_record" "example" {
for_each = {
for dvo in aws_acm_certificate.example.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
if !startswith(dvo.domain_name, "*")
}
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = aws_route53_zone.example.zone_id
} |
Community Note
Description
TL:DR; please add a simple example of how to create ACM certificate validation with a wildcard alternate name.
Motivation
Cloudfront only supports one ACM certificate per distribution, as per: https://aws.amazon.com/premiumsupport/knowledge-center/associate-ssl-certificates-cloudfront/
That means, in order to use a HTTPS/SSL protected CF distribution with multiple domains, you need a cert that is valid for both the root domain (e.g.
example.com
) and the wildcard domains (.e.g.*.example.com
).Note that the simple and obvious
for_each
solution from the current documentation doesn't work out of the box for a certificate with a wildcard SAN. AWS generates two separate validation options for the root and wildcard with exactly the same CNAME. The example from the documentation will then then fail when TF tries to create theaws_route53_record
because of the duplicate CNAME values.Problem
Because of changes and problems with cert validation over Terraform's history, it's difficult to find a simple example of how to use TF for this fairly basic requirement - there's a bunch of old/stale information out there going all the way back to doing stuff like calling
flatten()
with string interpolation from back when 0.11 was current.By "changes and problems" - I'm talking about the "instability of domain_validation_options" when AWS messed up and changed the implementation so the options were listed in unstable order for a while (causing TF to want to re-create certificates unnecessarily). And then there was the change-over from list to set in v3.x of the provider. All these issues have left a whole lot of "maybe try this" solutions for old versions of TF littered around the place (Github issue repositories, stack overflow, etc.)
Proposed solution
It would be valuable to the community if there was a simple example of how to use TF to achieve this in the documentation.
If there is no way to do this with Terraform currently - it would be helpful to call that explicitly out for users in the doco.
Since this is the only way to use a single Cloudfront distribution with wildcards, it's intuitive to expect it would be simple to do it with TF.
Please note this is not intended to be a criticism of the TF API in this area - the whole API on the AWS-side seems weird and janky to me (returning duplicate CNAMEs, for example). But if TF does have a solution for this, I think it would save both users and TF developers a bunch of time and frustration if the solution were documented as an example.
Sorry about the length of this; pretty sure the actual example, if it exists, would be shorter than this description. Think of the effort I took to write all this as evidence of how frustrating this is.
New or Affected Resource(s)
Potential Terraform Configuration
Sorry, I have no idea. I can't figure out what it should look like or find a simple example - that's why I think one should be added.
My current approach is trying to learn the new (*)
for_each
syntax to see if I can somehow filter out one of the duplicate domain_validation_options.(*) new to me anyway - I've hit this whole issue while trying to upgrade from TF v0.12 with AWS provider 2.x - incredibly frustrating and kind of worrying since I mangled the route53 records for my previous certificate.
Edit:
I figured it out for my use-case. Here's an article I wrote about managing multiple wild-carded domains, the example could easily be further reduced and added to the doco: https://kopi.cloud/blog/2021/terraform-aws_acm_certificate-wildcards/
References
Here's a random example I found that seems relevant, though I don't know if it works or not.
azavea/terraform-aws-acm-certificate#3
The text was updated successfully, but these errors were encountered: