Search code examples
terraformoracle-cloud-infrastructure

Conditional creation of parent/child resources


I have a Terraform parent-resource that gets created conditionally, by using the count meta arg. This works fine. However, if the parent-resource doesn't get created because count is set to 0, and it has dependent child-resources, Terraform will fail. Is there a practical way to tell Terraform to ignore the children-resources, if the parent doesn't get created? The only way I can think to do it is to perform a count operation on each resource, and this seems cumbersome.

Something like this:

create_dev_compartment = 0

create_dev_subnet *skip creation*

create_dev_instance *skip creation*


create_mgt_compartment = 1

create_mgt_subnet *create resource*

create_mgt_instance *create resource*


Solution

  • The Terraform documentation has a section Chaining for_each between resources which describes declaring chains of resources that have the same (or derived) for_each expressions so that they can all repeat based on the same source information.

    The documentation doesn't include an explicit example of the equivalent pattern for count, but it follows a similar principle: the count expression for the downstream resource will derive from the value representing the upstream resource.

    Since you didn't include any Terraform code I can only show a contrived example, but here's the general idea:

    variable "manage_network" {
      type = bool
    }
    
    resource "compartment" "example" {
      count = var.manage_network ? 1 : 0
    }
    
    resource "subnet" "example" {
      count = length(compartment.example)
    
      compartment_id = compartment.example[count.index].id
    }
    
    resource "instance" "example" {
      count = length(subnet.example)
    
      subnet_id = subnet.example[count.index].id
    }
    

    In the case of chained for_each, the full object representing the corresponding upstream resource is temporarily available as each.value inside the downstream resource block. count can't carry values along with it in the same way, so the equivalent is to refer to the upstream resource directly and then index it with count.index, which exploits the fact that these resources all have the same count value and will thus all have the same indices. Currently the only possible index will be zero, because you have a maximum count of 1, but if you change count in future to specify two or more instances then the downstream resources will all grow in the same way, creating several correlated instances all at once.