Reputation: 5056
I'm creating a public certificate using Amazon Certificate Manager (ACM) using Terraform. The code looks like this:
resource "aws_acm_certificate" "wc_mydomain_com" {
domain_name = "*.mydomain.com"
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}
this code correctly creates a new certificate for that domain. I only need to check the DNS key and value that I need to use to validate it. This is a manual task.
This certificate needs to be attached to an Application Load Balancer (ALB), so I would use something like this:
resource "aws_lb_listener_certificate" "wc_mydomain_com_attachment" {
listener_arn = <REFERENCE TO HTTPS LISTENER>
certificate_arn = aws_acm_certificate.wc_mydomain_com.arn
}
This code works correctly if the certificate above has been validated. Alas, since validation is a manual task, a lot of time this code fails with an error because, I think, I can't attach an invalid certificate to the listener. This is the error:
Error: creating ELB (Elastic Load Balancing) Listener Certificate: operation error Elastic Load Balancing v2: AddListenerCertificates, https response error StatusCode: 400, RequestID: XXX, api error UnsupportedCertificate: The certificate 'arn:aws:acm:[REGION]:[ACCOUNT ID]:certificate/[ID]' must have a fully-qualified domain name, a supported signature, and a supported key size.
I tried many solutions:
The idea was to put a count
in wc_mydomain_com_attachment
but it turned into an error since the count value can't be established during the plan. What can I do?
I want only to deactivate the assignment of the certificate to the listener if the certificate is not validated.
Upvotes: 0
Views: 537
Reputation: 1937
The way I currently handle this situation of conditionally attaching a certificate to an Application Load Balancer (ALB) based on whether the certificate has been validated in AWS Certificate Manager (ACM), is by using the aws_acm_certificate_validation
resource in Terraform. This resource allows you to wait until the ACM certificate is validated before proceeding with the attachment.
To do this, keep the creation of your certificate as is, but add the validation step explicitly.
resource "aws_acm_certificate" "wc_mydomain_com" {
domain_name = "*.mydomain.com"
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}
resource "aws_route53_record" "cert_validation" {
zone_id = "<ZONE_ID>"
name = aws_acm_certificate.wc_mydomain_com.domain_validation_options.0.resource_record_name
type = aws_acm_certificate.wc_mydomain_com.domain_validation_options.0.resource_record_type
records = [aws_acm_certificate.wc_mydomain_com.domain_validation_options.0.resource_record_value]
ttl = 60
}
resource "aws_acm_certificate_validation" "wc_mydomain_com_validated" {
certificate_arn = aws_acm_certificate.wc_mydomain_com.arn
validation_record_fqdns = [aws_route53_record.cert_validation.fqdn]
}
Make sure you replace <ZONE_ID>
with the actual ID of the Route53 zone where you want to create the DNS record for validation.
Next thing you want to do is to utilize the depends_on
argument in your aws_lb_listener_certificate
resource to ensure that it only tries to attach the certificate after validation is complete.
resource "aws_lb_listener_certificate" "wc_mydomain_com_attachment" {
listener_arn = <REFERENCE TO HTTPS LISTER>
certificate_arn = aws_acm_certificate.wc_mydomain_com.arn
depends_on = [aws_acm_setup.wc_mydomain_com_validated]
}
Replace <REFERENCE TO HTTPS LISTENER>
with the actual ARN of the HTTPS listener where you want to attach the certificate.
Here’s a summary of the modifications I made to your setup :
aws_acm_certificate
resource.aws_acm_certificate_validation
resource ensures that Terraform waits for the DNS validation to complete before marking the certificate as validated.depends_on
attribute in the aws_lb_listener_certificate
resource, Terraform ensures that it only attempts to attach the certificate to the ALB after it has been validated.This setup should eliminate the issue of trying to attach an unvalidated certificate to the ALB, and I confirm that it works for me.
Hope it helps or gives you an idea you can work with.
Upvotes: 0