terraform:模块变量作为对象

terraform:模块变量作为对象,terraform,Terraform,这是我的模块代码段: inputs.tf: variable "namespace" { type = object({ metadata = object({ name = string }) }) } resource "helm_release" "spark" { name = "spark" repository = "https://charts.bitnami.com/bitnam

这是我的模块代码段:

inputs.tf

variable "namespace" {
    type = object({
        metadata = object({
            name = string
        })
    })
}
resource "helm_release" "spark" {
    name       = "spark"
    repository = "https://charts.bitnami.com/bitnami" 
    chart      = "spark"
    version    = "1.2.21"
    namespace  = var.namespace.metadata.name
}
main.tf

variable "namespace" {
    type = object({
        metadata = object({
            name = string
        })
    })
}
resource "helm_release" "spark" {
    name       = "spark"
    repository = "https://charts.bitnami.com/bitnami" 
    chart      = "spark"
    version    = "1.2.21"
    namespace  = var.namespace.metadata.name
}
如您所见,我正在尝试访问以前创建的
kubernetes\u名称空间

进入我的环境工作区:

resource "kubernetes_namespace" "this" {
    metadata {
        name = var.namespace
    }
}

module "spark" {
    source = "../modules/spark"

    namespace = kubernetes_namespace.this
    workers = 1
}
当我试图制定计划时,我收到了以下信息:

➜  development terraform plan | xclip -selection clipboard

Error: Invalid value for module argument

  on main.tf line 14, in module "spark":
  14:     namespace = kubernetes_namespace.this

The given value is not suitable for child module variable "namespace" defined
at ../modules/spark/inputs.tf:1,1-21: attribute "metadata": object required.

有什么想法吗?

您应该能够将
kubernetes_namespace.this.metadata.0.name
传递给模块,只需让模块变量获取字符串即可。这将为您提供所需的依赖链,并将事情简化一点

因此,模块的
输入.tf
应具有:

variable "namespace" {
  type = string
}
然后你这样称呼它:

resource "kubernetes_namespace" "this" {
    metadata {
        name = var.namespace
    }
}

module "spark" {
    source = "../modules/spark"

    namespace = kubernetes_namespace.this.metadata.0.name
    workers   = 1
}
variable "namespace" {
    type = object({
        metadata = list(object({
            name = string
        }))
    })
}

错误是报告您分配给
命名空间
变量的值与其类型约束不兼容

kubernetes_namespace
metadata
属性似乎被定义为对象列表,而不是单个对象,因此这里不可能进行自动类型转换。您可以在此继续的一种方法是更改变量的类型以匹配资源类型架构,如下所示:

resource "kubernetes_namespace" "this" {
    metadata {
        name = var.namespace
    }
}

module "spark" {
    source = "../modules/spark"

    namespace = kubernetes_namespace.this.metadata.0.name
    workers   = 1
}
variable "namespace" {
    type = object({
        metadata = list(object({
            name = string
        }))
    })
}
我们可以在提供程序实现中看到,只要这仍然是真的(这似乎是可能的),您就可以期望
var.namespace.metadata
为空列表或单个项目列表,您可以将其写入局部变量,以便在模块中的其他地方更容易地使用:

locals {
  namespace_name = var.namespace.metadata[0].name
}
上述操作将使
成为本地。名称空间_name
引用给定的名称空间名称,或者如果给定的名称空间没有
元数据
块,则表达式将失败,因为在这种情况下将不存在元素
[0]


仅为了访问名称空间名称,上述操作就非常复杂。如果您希望将来需要使用
kubernetes_namespace
对象的其他属性,则上述结构可能很有用,但如果您可以仅使用名称,则可以将其简化为直接使用名称空间名称的单个字符串变量:

variable "namespace_name" {
  type = string
}
…您可以让调用方担心如何获取该名称:

resource "kubernetes_namespace" "this" {
    metadata {
        name = var.namespace
    }
}

module "spark" {
    source = "../modules/spark"

    namespace_name = kubernetes_namespace.this.metadata.name
    workers        = 1
}