Cycle dependency in plan

Hi @cdenneen,

The trick here is that the count and for_each arguments themselves create dependencies, and so the nodes in the graph are for the resource blocks themselves, not the dynamic instances you’re declaring using count.

Terraform needs to know when is the appropriate time to evaluate the count argument, so therefore it needs to build the dependency graph before it’s evaluated the count argument, and therefore the graph must be cycle-free regardless of what value count ends up having in the end.

I think @maxb’s idea of splitting into two configurations would be the most robust, since then you can ensure the cluster is up and running before trying to do anything with it.

I’m not familiar with this module so I’m not sure if there’s a more “surgical” option that would allow this to all be in one configuration. I think regardless of the dependencies of the data resource there is still the fundamental problem here that Terraform will need to configure the Kubernetes provider before asking it to create any plans, and some features of the Kubernetes provider require access to the server during planning in order to fetch dynamic schema, so they cannot possibly work before the cluster is running.

However, one general rule I’ll share – even though I’m not 100% sure if it will help in this case – is that a single Terraform configuration should typically not include both a resource block and a data block that refer to the same object. From what you’ve described it sounds like your call to the EKS module is indirectly declaring a resource "aws_eks_cluster" block, but you’re also using a data "aws_eks_cluster" block to access the same object, and in that situation you need to take a lot of care to describe the correct order to Terraform; treating the entire module as a dependency isn’t sufficient because (as @maxb pointed out) the module uses the Kubernetes provider itself and so there is no valid order of operations here.

I think this module has a somewhat tricky design in that it seems to expect the calling module to define a provider configuration that itself depends on the output of the module. If the module is written very carefully then that can work in principle because Terraform treats each individual input variable and output value as a separate dependency node, so a module author can carefully design a module to have essentially two independent dependency chains, but if you use module-level depends_on then you’d effectively break that because you force Terraform to treat everything in the module together as a dependency.

The “complete” example shows using the outputs of the module to configure the Kubernetes provider for other parts of the module to use, and so I think the author intended for this module to be one of those “two separate dependency chains” designs, which means that you will need to avoid doing anything which forces Terraform to treat the entire module together as a single dependency node. Perhaps you can adapt that example from the module’s repository to get a working solution within a single module.