当没有循环存在时,terraform destroy会产生循环错误

时间:2019-06-09 12:48:10

标签: terraform terraform-provider-gcp terraform0.12+

Terraform版本

Terraform v0.12.1

Terraform配置文件

main.tf在我的根提供商中:

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}"
}

这里的模块“ organization-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}"
}

然后使用模块“ 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.
}

最后是“项目信息”模块:

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}"
}

调试输出

完成terraform destroy -auto-approve之后,我得到:

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

terraform graph -verbose -draw-cycles -type=plan-destroy给了我这张图: image 来源:

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"
        }
}

预期行为

这个想法是使用组织,项目和堆栈级别的模块来设置命名约定,这些约定可以在所有资源中重复使用。 Organisation-info加载组织信息,有关项目的project-info,而stack-info根据当前工作空间确定要定位的项目。

我在模块中省略了许多其他逻辑,以使它们在此问题上保持干净。

根据terraform没有周期,destroy应该可以正常工作。

实际行为

我们得到了我上面发布的周期,即使terraform没有显示周期。

复制步骤

  1. 如上所示,设置三个模块organisation-infoproject-infostack-info
  2. 如上所述设置根提供商。
  3. terraform init
  4. terraform destroy(如果您先申请似乎没关系)

其他上下文

奇怪的是,如果我在stack-info中注释掉此输出,则循环停止:

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

这似乎很奇怪……我既不明白为什么输出变量应该有所作为,也为什么在没有循环的情况下为什么会出现循环错误。

奇怪的是,terraform plan -destroy仅显示terraform destroy而不显示周期。

我的蜘蛛绒般的感觉告诉我邪恶已经到来。

感谢任何能够告诉我发生了什么,这是否是错误以及可能的解决方法的人。

1 个答案:

答案 0 :(得分:0)

在我的情况下,相同的循环错误是因为 3 个 key:pair 中的一个 key:pair 是 map 类型变量在 variables.tf 内预期的一个模块,它没有在 main.tf 中声明,也没有在任何地方声明。