这是我的模块摘要:
inputs.tf
:
variable "namespace" {
type = object({
metadata = object({
name = string
})
})
}
main.tf
:
resource "helm_release" "spark" {
name = "spark"
repository = "https://charts.bitnami.com/bitnami"
chart = "spark"
version = "1.2.21"
namespace = var.namespace.metadata.name
}
如您所见,我正在尝试访问以前创建的kubernetes_namespace
。
进入我的环境工作区:
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.
有什么想法吗?
答案 0 :(得分:2)
错误报告您分配给namespace
变量的值与其类型约束不兼容。
metadata
的{{1}}属性似乎被定义为对象列表,而不是单个对象,因此这里不可能进行自动类型转换。您可以在此处进行操作的一种方法是更改变量的类型以匹配资源类型架构,如下所示:
kubernetes_namespace
我们可以在提供程序实现中看到this block is defined as having MaxItems: 1
,只要保持为真(这似乎很可能),您就可以期望variable "namespace" {
type = object({
metadata = list(object({
name = string
}))
})
}
是空列表或单项列表,您可以在本地变量中编写该代码,以方便在模块的其他位置使用:
var.namespace.metadata
以上内容将使locals {
namespace_name = var.namespace.metadata[0].name
}
引用给定的名称空间名称,或者如果给定的名称空间没有local.namespace_name
块,则表达式将失败,因为将没有元素{{1} }。
以上只是获得对名称空间 name 的访问的许多复杂性。如果您希望将来需要使用metadata
对象的其他属性,则上述结构可能会很有用,但是如果仅使用名称即可实现,则将其简化为一个直接使用名称空间名称的单个字符串变量:
[0]
...,您可以让呼叫者担心如何获取该名称:
kubernetes_namespace
答案 1 :(得分:1)
您应该能够改为将kubernetes_namespace.this.metadata.0.name
传递给模块,并且只需让模块变量采用字符串即可。那应该给您所需的依赖关系链,并且还可以简化一些事情。
因此您模块的inputs.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
}
答案 2 :(得分:0)
我认为您已经解决了复杂的事情。
var.namespace
中已经有了所需的东西,我会用
resource "kubernetes_namespace" "this" {
metadata {
name = var.namespace
}
}
module "spark" {
source = "../modules/spark"
namespace = var.namespace
workers = 1
}
IF ,您需要设置对模块资源的依赖关系:
https://discuss.hashicorp.com/t/tips-howto-implement-module-depends-on-emulation/2305/2
如果使用Terraform 0.12,则此模式更为简单,因为depends_on可以直接引用Terraform 0.12和更高版本中的变量:
variable "vm_depends_on" {
type = any
default = null
}
resource "azure_virtual_machine" "example" {
depends_on = [var.vm_depends_on]
# ...
}
由于此变量仅用于其依赖性而不是其值,因此我将其定义为具有any类型以获得最大的灵活性。然后,该模块的调用者可以使用vm_depends_on,其方式与一流的Depends_on元参数相同:
module "example" {
source = "..."
vm_depends_on = [module.fw_core01.firewall]
}