Terraform and the chicken and egg problem

The chicken and egg problem

I write a lot on Terraform because I like the tool very much. This time I thought it would be good to show a situation where Terraform is not necessarily the best tool for the job. The diagram below illustrates the problem.

A needs B and B needs A. If the relationship is mandatory it will be impossible to provision these resources because we have a chicken and egg problem. However, in our example, if A doesn’t need B from the beginning, we can provision A then B and add the link to B afterwards. The issue is then how do you do it in Terraform ? Once the resource A is provisonned, how do you add automatically the link to B ?

The example

To illustrate this, we will use F5 BIG-IP and the below diagram.

  1. We want to create a route domain but it needs a vlan
  2. We want to create a vlan but it needs a partition
  3. We want to create a partition but it needs a route domain

What will help us in this case is that the route domain doesn’t require a vlan, we will be able to add the vlan to the route domain afterwards. The steps will be :

  1. Create a route domain
  2. Create a partition and associate it to a route domain
  3. Create a vlan and associate it to the partition
  4. Modify the route domain to add the vlan

We see that we need 4 steps and the last step is to modify the first resource.

How to do it with Terraform ?

Manual approach

We can do it manually by changing the code and pushing a second time the configuration to production but it doesn’t seem to be the more efficient approach.

The workaround approach

Currently with the bigip Terraform provider, the only resource available is the “bigip_net_vlan” resource. We can however use the “bigip_command” resource to simulate the missing resources but without keeping a real state. We also need to add the depends_on attribute if we want Terraform to respect the creation steps.

We see with this example that we need an extra resource/command to add the missing element in our first resource (step 4). In this example this is possible because we use a resource to simulate a manual action. With this approach we are not keeping a proper state of any infrastructure, we don’t really have dependencies and thus we lose the main benefit of the tool.

The new resource approach

Another option could be to develop a specific resource that takes care of the 4 steps needed to create the environment. This resource will take care of all the API call for the 3 components in the background but as the Provider Design Principles documentation states :

A Terraform resource should be a declarative representation of single component

There is probably a reason for that. Having a single resource managing 3 components and their dependancies come with the associate complexity.

Netmemo’s take

The purpose of this example was to illustrate a use case where Terraform is not necessarily the best tool for the job. Sometimes what we have to provision hasn’t be designed for a tool like Terraform. Thus it can be more complex to develop resources to manage it. In this kind of situation other tools where you can define steps or programming languages might be more suitable.

Related