terraform destroy produces cycle error when no cycles present

你。 提交于 2020-01-02 12:26:54

问题


Terraform Version

Terraform v0.12.1

Terraform Configuration Files

main.tf in my root provider:

provider "google" {}

module "organisation_info" {
  source           = "../../modules/organisation-info"
  top_level_domain = "smoothteam.fi"
  region           = "us-central1"
}

module "stack_info" {
  source            = "../../modules/stack-info"
  organisation_info = "${module.organisation_info}"
}

Here's module 'organisation-info':

variable "top_level_domain" {}
variable "region" {}

data "google_organization" "organization" {
  domain = "${var.top_level_domain}"
}

locals {
  organization_id    = "${data.google_organization.organization.id}"
  ns = "${replace("${var.top_level_domain}", ".", "-")}-"
}

output "organization_id" {
  value = "${local.organization_id}"
}

output "ns" {
  value = "${local.ns}"
}

Then module 'stack-info':

variable "organisation_info" {
  type        = any
  description = "The organisation-scope this environment exists in."
}

module "project_info" {
  source            = "../project-info"
  organisation_info = "${var.organisation_info}"
  name              = "${local.project}"
}

locals {
  # Use the 'default' workspace for the 'staging' stack.
  name = "${terraform.workspace == "default" ? "staging" : terraform.workspace}"
  # In the 'production' stack, target the production project. Otherwise, target the staging project.
  project = "${local.name == "production" ? "production" : "staging"}"
}

output "project" {
  value = "${module.project_info}" # COMMENTING THIS OUTPUT REMOVES THE CYCLE.
}

And finally, the 'project-info' module:

variable "organisation_info" {
  type        = any
}
variable "name" {}

data "google_project" "project" {
  project_id = "${local.project_id}"
}

locals {
  project_id = "${var.organisation_info.ns}${var.name}"
}

output "org" {
  value = "${var.organisation_info}"
}

Debug Output

After doing terraform destroy -auto-approve, I get:

Error: Cycle: module.stack_info.module.project_info.local.project_id, module.stack_info.output.project, module.stack_info.module.project_info.data.google_project.project (destroy), module.organisation_info.data.google_organization.organization (destroy), module.stack_info.var.organisation_info, module.stack_info.module.project_info.var.organisation_info, module.stack_info.module.project_info.output.org

And terraform graph -verbose -draw-cycles -type=plan-destroy gives me this graph:

Source:
digraph {
        compound = "true"
        newrank = "true"
        subgraph "root" {
                "[root] module.organisation_info.data.google_organization.organization" [label = "module.organisation_info.data.google_organization.organization", shape = "box"]
                "[root] module.stack_info.module.project_info.data.google_project.project" [label = "module.stack_info.module.project_info.data.google_project.project", shape = "box"]
                "[root] provider.google" [label = "provider.google", shape = "diamond"]
                "[root] module.organisation_info.data.google_organization.organization" -> "[root] module.stack_info.module.project_info.data.google_project.project"
                "[root] module.organisation_info.data.google_organization.organization" -> "[root] provider.google"
                "[root] module.stack_info.module.project_info.data.google_project.project" -> "[root] provider.google"
        }
}

Expected Behavior

The idea is to use modules at the org, project and stack levels to set up naming conventions that can be re-used across all resources. Organisation-info loads organisation info, project-info about projects, and stack-info determines which project to target based on current workspace.

I have omitted a bunch of other logic in the modules in order to keep them clean for this issue.

According to terraform there are no cycles, and destroy should work fine.

Actual Behavior

We get the cycle I posted above, even though terraform shows no cycles.

Steps to Reproduce

  1. Set up the three modules, organisation-info, project-info, and stack-info as shown above.
  2. Set up a root provider as shown above.
  3. terraform init
  4. terraform destroy (it doesn't seem to matter if you've applied first)

Additional Context

The weird thing is that if I comment out this output in stack-info, the cycle stops:

output "project" {
  value = "${module.project_info}" # IT'S THIS... COMMENTING THIS OUT REMOVES THE CYCLE.
}

This seems really weird... I neither understand why outputting a variable should make a difference, nor why I'm getting a cycle error when there's no cycle.

Oddly, terraform plan -destroy does not reveal the cycle, only terraform destroy.

My spidey sense tells me evil is afoot.

Appreciate anyone who can tell me what's going on, whether this is a bug, and perhaps how to work around.

来源:https://stackoverflow.com/questions/56514719/terraform-destroy-produces-cycle-error-when-no-cycles-present

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!