To give a specific case (though I’m seeking a general answer), say I’m using DNS validation to validate a x509 cert generate via AWS’s ACM service:
resource "aws_acm_certificate" "example" {
domain_name = "sub.example.com"
subject_alternative_names = ["sub.region.example.com"]
validation_method = "DNS"
lifecycle { create_before_destroy = true }
}
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
zone_id = data.aws_route53_zone.emsicloud.zone_id
}
}
allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = each.value.zone_id
}
resource "aws_acm_certificate_validation" "example" {
certificate_arn = aws_acm_certificate.example.arn
validation_record_fqdns = [for record in aws_route53_record.example : record.fqdn]
}
Okay, this works, but those DNS records should not exist after the validation is finished and the aws_acm_certificate_validation
should not exist after those DNS records are deleted.
Now I run into the problem: terraform seems to go to significant lengths to prevent me from automating the correct sequnce of operation for handling those resource. If make the resources be created when aws_acm_certificate.example.status=="PENDING_VALIDATION"
and then destroyed when that becomes ISSUED
, then all I should need to do is keep applying the config until it stabilizes. But I get an error message to the effect of:
The "count/for_each" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
What is the intended way for terraform to deal with this sort of resource, where it should only exist at all during particular stages of deployment and then be removed? Or more generally; what is the proper way to deal with a case where the number of resource to be created can only be determined by inspection of the external result of applying other parts of the configuration?
I’m well aware that the terraform philosophy is that configurations should describe only the static end state and an apply should jump right to it. However in some cases, including this one, reality doesn’t allow that; the only way to get to the proper end state is to walk thought a number of intermediate steps.
Currently I’m working around this by manually manipulating a variable, but that’s error prone as people who don’t know about it will do the wrong thing regardless of what defaults I set.
Another option would be to do all that work in a provisioner, but then I lose all the advantages of terraform with regards to the the associated resources.
Another solution I have reason to suspect would work would be something disgusting like:
variable "pending_validation" { default = false }
resource "local_file" "foo" {
content = "pending_validation=${(aws_acm_certificate.example.status == "PENDING_VALIDATION")}"
filename = "pending_validation.auto.tfvars"
}
and then switch everything based on var.pending_validation
.
Does terraform really have no answer to this uses case?