51

The Terraform docs for some weird reason do not explain what "Error: Cycle" means. I've looked everywhere but there is no mention of it on the official docs. (Turns out it is well-known term, a circular dependency, that someone apparently renamed thinking it would make them sound cool...)

Juan Jimenez
  • 717
  • 1
  • 6
  • 12

1 Answers1

62

As part of Terraform's work, it analyzes the dependencies between your resource blocks, data blocks, and other configuration constructs in order to determine a suitable order to process them so that the necessary input data will be available.

For example, consider the following contrived simple configuration:

resource "null_resource" "foo" {
}

resource "null_resource" "bar" {
  triggers = {
    foo = null_resource.foo.id
  }
}

Terraform will analyze the above and notice that the configuration of null_resource.bar contains a reference to null_resource.foo, and therefore the operations related to null_resource.foo must happen before null_resource.bar. We can visualize that as a graph where an arrow represents "must happen after", or "depends on":

a box for null_resource.foo and a box for null_resource.bar, with an arrow pointing from the latter to the former

  • Operations for null_resource.bar must happen after operations for null_resource.foo.

Consider now what happens if we modify that configuration like this:

resource "null_resource" "foo" {
  triggers = {
    bar = null_resource.bar.id
  }
}

resource "null_resource" "bar" {
  triggers = {
    foo = null_resource.foo.id
  }
}

Now null_resource.foo also refers to null_resource.bar. There are now two "must happen after" relationships implied by this configuration:

a box for null_resource.foo and a box for null_resource.bar, with an arrow pointing from the latter to the former, with arrows pointing in both directions between them

  • Operations for null_resource.bar must happen after operations for null_resource.foo.
  • Operations for null_resource.foo must happen after operations for null_resource.bar.

The two statements above contradict one another: null_resource.bar cannot be processed both before and after null_resource.foo. Terraform will respond to this situation by reporting a dependency cycle, using the error message you've seen:

Cycle: null_resource.foo, null_resource.bar

When Terraform returns this error, the solution is to remove at least one of the "must happen after" arrows (dependencies) from the configuration so that it's no longer contradictory. Without seeing your configuration I can't suggest what specific change might achieve that in your case, but it's likely that somewhere in your configuration you have two mutually-dependent resources like this, or perhaps a resource referring to itself.


If you are sighted, depending on how complicated your configuration is, it might help to ask Terraform to produce a graph similar to the ones I've included above in this answer, but highlighting the cycles. To do this, you can use the terraform graph command, like this:

terraform graph -draw-cycles

The output of this command is a description of the graph in the format accepted by Graphviz. If you don't have Graphviz installed on your local computer, you could instead copy-paste the output into Graphviz Online to produce a graph image. The -draw-cycles command causes Terraform to mark the arrows that are related to the cycle being reported using the color red. If you cannot visually distinguish red from black, you may wish to first edit the generated Graphviz code to replace red with some other color you can distinguish.

The graph visualization of the configuration tends to become unusable for non-trivial configurations because there are so many graphs and edges, so if your configuration has many objects it may be better to follow the dependencies through the configuration itself.

Martin Atkins
  • 2,188
  • 18
  • 19
  • 14
    Excellent answer. Thank you. I just have to wonder why they used incorrect terminology. This is not a cycle, this is a circular dependency. That would have made it much clearer. – Juan Jimenez Mar 07 '20 at 02:18
  • 1
    @JuanJimenez fwiw, I had the exact same thought before I found this answer - why not just call it a circular dependency? Might be worth filing a ticket with Hashi... – d8aninja Mar 03 '22 at 00:40
  • 1
    It seems to me that in this contect "dependency cycle" and "circular dependency" are synonyms. For me, the main problem with this error message is that it misses two important parts of a good error message: why does this matter, and what should I do about it? I expect there's probably a way to summarize what I said here into a short paragraph which gives a better clue about what it means and what to do about it. If that includes changing the terminology at the same time then great, but I don't think that's a sufficient change to make this a good error message. – Martin Atkins Mar 03 '22 at 23:09
  • It's open source. There's no motivation on their part to listen to users on this matter, so they won't do anything, and hence I don't waste my time "file tickets." – Juan Jimenez Mar 04 '22 at 01:02
  • 1
    @MartinAtkins Thank you for all the details in your answer. Very helpful. – Chris Apr 12 '22 at 11:02
  • Wonderful explaination! THanks – user977766 Jul 26 '22 at 20:40
  • @Martin Atkins: Thanks for your answer. However: not knowing null_resource, I tried you example, which 'compiles'/'apply's' with terraform v1.2.8. I know it's not your answer, but Hashi does something strange here... – JdeHaan Aug 27 '22 at 14:05