1

我正在使用 terraform 创建 Kubernetes 命名空间。下面的示例

resource "kubernetes_namespace" "test1" {
  metadata {
    name = local.ns_name
  }

}

我正在尝试按照此链接使用 terraform 创建蓝/绿类型的部署。作为其中的一部分,我现在创建了两个 Kubernetes 集群。一个是蓝色的,另一个是绿色的,现在我有两个 kubernetes 提供程序

provider "kubernetes" {
  alias                  = "kubernetes_blue"
}

provider "kubernetes" {
  alias                  = "kubernetes_green"
}

我想了解是否有办法,我可以有一些条件kubernetes_namespace,根据标志var.enable_green_sidevar.enable_blue_side,我可以在多个 kubernetes 集群中创建相同的命名空间,而不必重复整个资源块,如下所示

resource "kubernetes_namespace" "test1" {
  metadata {
    name = local.ns_name
  }

  provider = kubernetes.kubernetes_blue  
}

resource "kubernetes_namespace" "test2" {
  metadata {
    name = local.ns_name
  }

  provider = kubernetes.kubernetes_green  
}

提前致谢。

4

2 回答 2

2

Terraform 的模型要求每个resource块都属于一个提供者配置,因此无法避免两次声明资源,但您至少可以通过将其分解到一个模块中并调用该模块两次来减少导致的重复量,而不是resource直接复制块:

provider "kubernetes" {
  alias = "blue"
}

provider "kubernetes" {
  alias = "green"
}

module "blue" {
  source = "../modules/bluegreen"

  # (any settings the module needs from the root)

  providers = {
    kubernetes = kubernetes.blue
  }
}

module "blue" {
  source = "../modules/bluegreen"

  # (any settings the module needs from the root)

  providers = {
    kubernetes = kubernetes.green
  }
}

providers块中的特殊参数module允许您为子模块提供与调用者不同的声明提供程序配置的“视图”。在上面的module "blue"块中,providers参数是说:“在这个模块实例中,任何对默认kubernetes提供者配置的引用都意味着使用kubernetes.blue来自调用者的配置”。

在模块内部,您可以只编写resource "kubernetes_...."没有任何特殊参数的普通块,因为从该模块实例的角度来看,provider这将导致它们附加到默认提供程序,并且两个模块实例中的每一个都有不同的配置绑定。

这种分解到模块中是否会有所帮助当然取决于子模块最终需要多少来自调用模块的上下文。如果您的module块最终包含几乎与您要分解的块一样多的参数,那么将块保持在顶层并避免间接resource可能会更好。resource

于 2021-04-12T18:44:22.043 回答
1

从问题中不清楚为什么您需要两个提供者定义。但是为了举例,我们可以考虑以下蓝/绿部署的常见用例:

  • 针对不同的集群
  • 针对不同的上下文

在这两种情况下,根据变量中设置的标志使用具有不同提供程序配置的单个提供程序会更容易。

考虑像这样的变量定义(使用string类型,但bool也可以使用 a):

variable "kubernetes_deployment" {
  type    = string
  default = "blue"
}

假设我想针对不同的集群:

  • cluster1 为蓝色
  • cluster2 为绿色

然后可以kubeconfig根据变量的值配置提供程序(例如使用)。为此,我们可以使用三元条件

provider "kubernetes" {
  config_path = var.kubernetes_deployment == "blue" ? "~/.kube/cluster1.config" : "~/.kube/cluster2.config"
}

resource "kubernetes_namespace" "mynamespace" {
  metadata {
    name = local.ns_name
  }

  provider = kubernetes
}

这将确保资源(在本例中为命名空间)将在“cluster1”上创建用于蓝色部署,并在“cluster2”中创建用于绿色部署。

此条件可以应用于提供者的其他配置参数。使用相同集群但不同上下文的示例:

provider "kubernetes" {
  config_path = "~/.kube/cluster1.config"
  config_context = var.kubernetes_deployment == "blue" ? "context1" : "context2"
}
于 2021-04-11T16:42:23.950 回答