So this is an interesting one, and I am not sure how to go about it. I believe it could be a bug in the implementation, but figured I would ask the community first.
I recently opened [Bug]: aws_batch_compute_environment: launch_template version known after apply does not ForceNew · Issue #37440 · hashicorp/terraform-provider-aws · GitHub because we are seeing that launch_template
updates do not properly trigger a replacement for the immutable field in an aws_batch_compute_environment
.
Our solution when we came across this bug was to use replace_triggered_by
, which fixed the issue for the state calling the module that was running into issues.
However, we now have issues with other states using the batch module–ones that DO NOT have a launch template.
My question is–is there a way to set replace_triggered_by
to evaluate conditionally if the resource exists, but ignore it if it doesnt? Here is some example code to help provide a clearer picture:
resource "aws_batch_compute_environment" "default" {
for_each = var.compute_environments
dynamic "launch_template" {
for_each = contains(["EC2", "SPOT"], lookup(each.value, "compute_type", var.compute_type)) && length(lookup(each.value, "launch_template", var.launch_template)) > 0 ? [aws_launch_template.default[each.key]] : []
content {
launch_template_id = launch_template.value.id
version = launch_template.value.default_version
}
}
lifecycle {
replace_triggered_by = [aws_launch_template.default[each.key]]
}
}
resource "aws_launch_template" "default" {
for_each = {
for k, v in var.compute_environments : k => lookup(v, "launch_template", var.launch_template) if length(lookup(v, "launch_template", var.launch_template)) > 0
}
# ... removed for brevity
}
With the above code, we create launch templates and associate them with the batch compute environment if and only if the user calling the module specifies a launch template. Otherwise, we leave it blank, as AWS does not require a launch template for a batch compute environment.
The issue here is that when we have a state that DOES NOT have launch templates, we get an error because replace_triggered_by
is pointing at an object that does not exist. The error is:
╷
│ Error: no change found for aws_launch_template.default["foo"] in module.batch
│
│
╵
Is this expected behavior? Is there a way to avoid this and have Terraform only evaluate the replace_triggered_by
when the object inside exists? I tried various expressions but they are not allowed inside the lifecycle block.
Thanks in advance for any support you can provide!