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:
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
- Set up the three modules,
organisation-info
,project-info
, andstack-info
as shown above. - Set up a root provider as shown above.
terraform init
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