Scott McArron
Scott McArron

Reputation: 41

How to write conditional explicit dependency in Terraform

In my module, I want to be able to force the creation of Resource A before Resource B, but only if Resource A is actually created.

Take this scenario for example. When we deploy a vnet into Azure, Azure automatically creates a Network Watcher and RG for that vnet region if one does not already exist in the subscription. This creates a problem where resources are created that are not managed by Terraform. If you initiate a destroy of that pipeline and then redeploy with the same code, it will error out that the Network Watcher already exists. This is sub-optimal and not good DevOps practice.

To get around this, we coded the creation of the Network Watcher and RG into our TF network module. This allows full control over the resource, especially important in the case of deploying multiple vnets to a single region within the same subscription in Azure where subsequent vnet deployments do NOT create additional Network Watchers but use the existing one created by the first module call.

The Network Watcher is also important to control in code so that we can automatically deploy NSG Flow Logs and such.

The problem we're having with this is with larger deployments with many resources. Sometimes, when the vnet is deployed, it takes too long for Terraform to get around to creating the Network Watcher and Azure gets to it first. Of course, when this happens Terraform errors out that the resources already exists and the pipeline fails wreaking havoc.

It would be incredibly simple to get around this issue by simply creating the Network Watcher before the vnet, for example with using the depends_on resource. However, we still have to account for calling the module where the Network Watcher already exists, so we can't code that explicit dependency in the module. And my understanding is that the depends_on resource does not support conditionals like what we're in need of.

Anyone have any ideas how to make a conditional explicit dependency? Or otherwise force the creation order of conditional resources in TF? This seems like a massive gap with HCL.

Upvotes: 1

Views: 3585

Answers (1)

Martin Atkins
Martin Atkins

Reputation: 74084

Dependencies in Terraform are resolved as the very first step before evaluating any expressions, so there are no "conditional" dependencies in Terraform.

However, depending on a resource that has count = 0 or for_each set to an empty map will cause a dependency only on the evaluation of the count or for_each expression of that target resource, after which Terraform will see that there's no further work to do for that resource because it has no instances.

It sounds like you are encountering a race condition between actions explicitly planned in Terraform and actions implicitly carried out by Azure itself. Objects should either be managed directly by Terraform or managed indirectly by another system, and never both at the same time. The correct solution to this problem is to resolve that race condition by deciding which system ought to be responsible for creating this object and ensuring that no other system creates it.

Upvotes: 2

Related Questions