What’s the recommended way to handle mutual (attribute) dependencies in Terraform?
I know this has been covered to death but, since there are some new Terraform features it seems to be time to ask again.
For the purposes of Federation, Okta ↔ Azure have dependencies on one another. In generic terms though, the requirements are:
Need to build 2 different resources simultaneously
a. each resource is from a different provider
b. resource attributes need to be mapped to one another
c. E.G.: A1 to B1, B2 to A2, etc.
It seems a bit early to accept that this scenario is impossible to solve; there’s usually a solution somewhere. Also, I don’t want to imply a direction based on some of the very creative solutions posted. So, let me ask another way…
What’s the HashiCorp-recommended way to handle mutual (attribute) dependencies in Terraform for this type of operation?
I think this is actually impossible - at least without an awkward workaround - because the design of Terraform as it is today, will absolutely never modify the same resource twice during an apply operation - yet creation of the mutually dependent setup in your diagram absolutely requires one of the resources to be initially created in an intermediate state that uses placeholder values instead of referencing the other resource.
The only workarounds I can think of are:
Break the dependency cycle by manually embedding some values into the configuration as literal strings - this is obviously pretty ugly and manual.
Break the dependency cycle by having at least one of the providers implement multiple Terraform resources that together manage a single underlying resource - e.g. imagine replacing resource A with a resource “A that doesn’t manage attribute 2” and a resource “manage the value of attribute 2 on an existing instance of A”. That’s less manual, but requires the provider developer to accomodate this, and the configuration author to understand why this complexity is needed by Terraform.
The typical way to solve situations like this is for one of the two providers to represent the relationship between the two objects as a separate resource type from the objects themselves, so that instead of two objects that refer to each other there are three objects where one depends on the other two.
In most reasonable cases the underlying API would already be designed in this way because it’s pretty awkward to design an API where there isn’t a clear order in which objects can be created. Of course, not all API designs are reasonable, and so in that case provider developers will need to carefully design a workaround to make it appear as if the relationship between the two objects is independent of the objects themselves, such as by making the main resource type totally ignore the field that specifies the relationship and then the relationship resource type ignore everything except the field that specifies the relationship.
If the providers haven’t been designed to support this then the best (only?) answer is to fix the providers to model this situation better.