【问题标题】:Terraform does not destroy a moduleTerraform 不会破坏模块
【发布时间】:2019-06-28 07:58:17
【问题描述】:

我用terraformkubernetescassandraelassandra做了一些实验,我都是用模块分隔的,但是现在我不能删除特定的模块。

我正在使用 gitlab-ci,并将 terraform 状态存储在 AWS 后端。 这意味着,每次我在 terraform 文件中更改基础架构时,在 git push 之后,基础架构都会更新为运行 terraform initterraform planterraform applygitlab-ci

我的 terraform 主文件是这样的:

# main.tf
##########################################################################################################################################
# BACKEND                                                                                                                                #
##########################################################################################################################################

terraform {
  backend "s3" {}
}

data "terraform_remote_state" "state" {
  backend = "s3"
  config {
    bucket         = "${var.tf_state_bucket}"
    dynamodb_table = "${var.tf_state_table}"
    region         = "${var.aws-region}"
    key            = "${var.tf_key}"
  }
}

##########################################################################################################################################
# Modules                                                                                                                                #
##########################################################################################################################################

# Cloud Providers: -----------------------------------------------------------------------------------------------------------------------
module "gke" {
  source    = "./gke"
  project   = "${var.gcloud_project}"
  workspace = "${terraform.workspace}"
  region    = "${var.region}"
  zone      = "${var.gcloud-zone}"
  username  = "${var.username}"
  password  = "${var.password}"
}

module "aws" {
  source   = "./aws-config"
  aws-region      = "${var.aws-region}"
  aws-access_key  = "${var.aws-access_key}"
  aws-secret_key  = "${var.aws-secret_key}"
}

# Elassandra: ----------------------------------------------------------------------------------------------------------------------------
module "k8s-elassandra" {
  source   = "./k8s-elassandra"

  host     = "${module.gke.host}"
  username = "${var.username}"
  password = "${var.password}"

  client_certificate     = "${module.gke.client_certificate}"
  client_key             = "${module.gke.client_key}"
  cluster_ca_certificate = "${module.gke.cluster_ca_certificate}"
}

# Cassandra: ----------------------------------------------------------------------------------------------------------------------------
 module "k8s-cassandra" { 
   source   = "./k8s-cassandra"

   host     = "${module.gke.host}"
   username = "${var.username}"
   password = "${var.password}"

   client_certificate     = "${module.gke.client_certificate}"
   client_key             = "${module.gke.client_key}"
   cluster_ca_certificate = "${module.gke.cluster_ca_certificate}"
 }

这是我的目录树:

.
├── aws-config
│   ├── terraform_s3.tf
│   └── variables.tf
├── gke
│   ├── cluster.tf
│   ├── gcloud_access_key.json
│   ├── gcp.tf
│   └── variables.tf
├── k8s-cassandra
│   ├── k8s.tf
│   ├── limit_ranges.tf
│   ├── quotas.tf
│   ├── services.tf
│   ├── stateful_set.tf
│   └── variables.tf
├── k8s-elassandra
│   ├── k8s.tf
│   ├── limit_ranges.tf
│   ├── quotas.tf
│   ├── services.tf
│   ├── stateful_set.tf
│   └── variables.tf
├── main.tf
└── variables.tf

我在这里被屏蔽了:

->我要删除模块k8s-cassandra

  • 如果我评论删除main.tf (module "k8s-cassandra" {...) 中的模块,我会收到此错误:

地形计划... 获取状态锁。这可能需要一些时间... 释放状态锁。这可能需要一些时间...

错误:module.k8s-cassandra.kubernetes_stateful_set.cassandra:module.k8s-cassandra.provider.kubernetes 的配置不存在;所有操作都需要提供程序配置块

  • 如果我在 terraform initterraform plan 之间插入 terraform destroy -target=module.k8s-cassandra -auto-approve 仍然无法正常工作。

有人可以帮帮我吗? 谢谢:)

【问题讨论】:

  • kubernetes 提供程序在哪里定义?
  • @SomeGuyOnAComputer,我在两个文件中都定义了 k8s.tf,provider "kubernetes" { version="~> 1.5.0" host="${var.host}" username="$ {var.username}" password="${var.password}" client_certificate="${base64decode(var.client_certificate)}" client_key="${base64decode(var.client_key)}" cluster_ca_certificate="${base64decode(var .cluster_ca_certificate)}" } 资源 "kubernetes_namespace" "terraform-elassandra-namespace" { 元数据 { 注释 { name = "terraform-elassandra-namespace" } 标签 { app = "elassandra" } name = "terraform-elassandra-namespace" } }
  • 尝试只在父main.tf定义它
  • 如果你注释了代码,取消注释,然后对目标进行 terraform destroy,然后注释代码,你应该被设置...
  • 是否有任何代码可以将资源引用到module.k8s-cassandra.XXX

标签: kubernetes terraform


【解决方案1】:

此错误消息的含义是 Terraform 依赖 provider "kubernetes" 模块内的 provider "kubernetes" 块来配置 AWS 提供程序。通过从源代码中删除模块,您已经隐式删除了该配置,因此无法删除状态中已经存在的现有对象 - 执行此操作所需的提供程序配置不存在。

虽然 Terraform 允许在子模块中使用 provider 块以获得灵活性,但文档建议将所有这些块保留在根模块中,并使用 providers 映射按名称将提供程序配置传递给子模块,或者通过自动继承名字。

provider "kubernetes" {
  # global kubernetes provider config
}

module "k8s-cassandra" {
  # ...module arguments...

  # provider "kubernetes" is automatically inherited by default, but you
  # can also set it explicitly:
  providers = {
    "kubernetes" = "kubernetes"
  }
}

要摆脱您已经遇到的冲突情况,答案是暂时恢复module "k8s-cassandra" 块,然后使用-target 在删除它之前销毁它正在管理的对象选项:

terraform destroy -target module.k8s-cassandra

一旦该模块管理的所有对象都被销毁并从状态中删除,您就可以安全地从配置中删除 module "k8s-cassandra" 块。

为了防止这种情况再次发生,你应该在这里对根模块和子模块进行返工,使提供者配置都在根模块中,子模块只继承从根传入的提供者配置。有关详细信息,请参阅文档中的 Providers Within Modules

【讨论】:

    猜你喜欢
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 2022-10-07
    • 2018-12-14
    相关资源
    最近更新 更多