【问题标题】:terraforming with dependant providers与依赖提供者一起改造
【发布时间】:2019-06-07 11:41:02
【问题描述】:

在我的 terraform 基础架构中,我根据参数启动了几个 Kubernetes 集群,然后使用 kubernetes 提供程序将一些标准内容安装到这些 Kubernetes 集群。

当我更改参数并且不再需要其中一个集群时,terraform 无法将其拆除,因为提供程序和资源都在模块中。但是,我没有看到替代方案,因为我在同一个模块中创建了 kubernetes 集群,并且 kubernetes 对象都是每个 kubernetes 集群。

我能想到的所有解决方案都涉及在我的 terraform 配置中添加一堆样板。我应该考虑从脚本生成我的 terraform 配置吗?


我创建了一个 git repo,它准确地显示了我遇到的问题:

https://github.com/bukzor/terraform-gke-k8s-demo

【问题讨论】:

标签: kubernetes terraform terraform-provider-kubernetes


【解决方案1】:

TL;DR

两种解决方案:

  1. 使用 Terraform 创建两个单独的模块
  2. 在创建 Kubernetes 集群的代码和 kubernetes 资源之间使用插值和depends_on:

    resource "kubernetes_service" "example" {
      metadata {
        name = "my-service"
      }
    
      depends_on = ["aws_vpc.kubernetes"]
    }
    
    resource "aws_vpc" "kubernetes" {
      ...
    }
    

销毁资源时

您遇到了依赖生命周期问题

PS:我不知道您用于创建/配置 Kubernetes 集群的代码,但我猜它看起来像这样

  1. 为 Kubernetes 集群编写代码(创建 VPC)
  2. 应用它
  3. 编写用于配置 Kubernetes 的代码(创建一个创建 ELB 的服务)
  4. 应用它
  5. 试图摧毁一切 => 错误

正在发生的事情是,通过创建 LoadBalancer Service,Kubernetes 将在 AWS 上配置 ELB。但是 Terraform 不知道这一点,并且创建的 ELB 与 Terraform 管理的任何其他资源之间没有任何联系。 所以当 terraform 试图销毁代码中的资源时,它会尝试销毁 VPC。但它不能,因为该 VPC 中有一个 terraform 不知道的 ELB。 首先要确保 Terraform “取消配置” Kubernetes 集群,然后销毁集群本身。

这里有两个解决方案:

  1. 使用不同的模块,因此没有依赖生命周期。例如,第一个模块可以是k8s-infra,另一个可以是k8s-resources。第一个管理 Kubernetes 的所有 squeleton,并且是先应用/最后销毁。第二个管理集群内部的内容,最后应用/销毁。

  2. 使用depends_on参数显式编写依赖生命周期

创建资源时

terraform apply 即使尚未应用任何内容也无法创建资源时,您也可能会遇到依赖问题。我将举一个 postgres 的另一个例子

  1. 编写代码创建 RDS PostgreSQL 服务器
  2. 通过 Terraform 应用它
  3. 编写代码,在同一模块中,使用 postgres terraform 提供程序配置该 RDS 实例
  4. 通过 Terraform 应用它
  5. 摧毁一切
  6. 尝试应用所有内容 => 错误

通过稍微调试 Terraform,我了解到所有提供程序都是在 plan / apply 开始时初始化的,所以如果一个配置无效(错误的 API 密钥/无法访问的端点),那么 Terraform 将失败。

这里的解决方案是使用plan / apply 命令的target parameter。 Terraform 只会初始化与应用的资源相关的提供者。

  1. 向 AWS 提供商应用 RDS 代码:terraform apply -target=aws_db_instance
  2. 应用一切terraform apply。由于 RDS 实例已经可访问,PostgreSQL 提供程序也可以自行启动

【讨论】:

  • 感谢您的详细回复!我终于控制了我的依赖关系图,所以我认为这不会是问题的根源。例如,如果依赖关系图(正确)显示 postgres 提供程序对 RDS 资源具有依赖关系,则不会发生 #2 中的问题。这对我有用。
  • 我的问题是您的 #1,但我不知道如何使您的任何一个解决方案都有效。 1.1) 因为我的 kubernetes 集群是相当动态的,并且我想配置所有这些集群,所以我不知道如何在没有大量手动工作的情况下使单独的模块工作:配置集群,查找并复制所有连接信息,将其插入 k8s 配置中,再次应用。
  • 1.2) 我的依赖项都是正确的,但是当我更改参数时,整个子树都会消失,包括供应商。这意味着当需要拆除 kubernetes 位时,provisioner 未配置,这会导致错误。
猜你喜欢
  • 2018-07-03
  • 2021-09-23
  • 1970-01-01
  • 2018-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
相关资源
最近更新 更多