A technique for the conditional creation of resources is to have a line immediately after the one with name of the resource like:
count = var.create_resource ? 1 : 0
However, for a resource that contains a for_each loop this does not work.
Is there a way of coding a resource that includes a for_each loop in such away that the resources only get created if a boolean variable is set to true ?.
The key thing about for_each is that it declares one resource instance for each element in the map (or set) assigned to it.
Building on that, the key to your question is to make sure that the for_each map has zero elements in the cases where you want to create nothing. If you have a sort of “all or nothing” situation – where you’ll disable all of the elements together in the “off” case – then a relatively concise way to write it is to write a for expression with an if clause that always evaluates to true only if your condition is enabled:
for_each = { for k, v in var.some_map : k => v if var.enabled }
Typically when writing an expression like this the if clause would contain a reference to k and/or v, but since this is an “all or nothing” situation the result depends only on some external flag and doesn’t vary for each element.
If you do want to vary the behavior by element then you can certainly do that too. For example:
for_each = {
for k, v in var.some_map : k => v
if contains(var.enabled_keys, k)
}
(the above is assuming that var.enabled_keys is a set(string) value containing the keys of the var.some_map elements that ought to be enabled, just as a contrived example of an item-specific condition.)
In reality there is no such thing as “conditional create”, just the ability to choose the number of resources to create (we just happen to only choose zero or one). Therefore there has to be a way to handle the count/for_each creating more than 1 resource - hence the change to either [1] or [“something”].
So in short, no adding count of for_each would adjust the resource name, but you could easily update any existing resource using terraform state mv
I added count to an aws_instance (e.g. bastionaws1) to allow conditional creation, so I need to terraform import new bastionaws1[0] linked resources and remove old ones (basrionaws1). I correctly imported aws_instance, the instance has attached ENI so I also imported resource network_interface. On terraform plan I get that instance will be replaced becouse network_interface force replacement:
It would be very useful if terraform could handle single element list as a single normal resource. This could simplify later adoption of conditional resources creation avoiding complex, risky and boring refactoring.
I’m trying to do something similar, but I’m not sure I can apply these examples to my code. I have a terraform script that will create multiples website based upon the contents of a json file which I’m loading as a local variable. I want to add a value to the json file to control if a site is created in the production environment.