如何将来自 github 的 CRD 应用到具有 terraform 的集群?
How do I apply a CRD from github to a cluster with terraform?
我想用 terraform 安装 CRD,我希望这样做会很容易:
data "http" "crd" {
url = "https://raw.githubusercontent.com/kubernetes-sigs/application/master/deploy/kube-app-manager-aio.yaml"
request_headers = {
Accept = "text/plain"
}
}
resource "kubernetes_manifest" "install-crd" {
manifest = data.http.crd.body
}
但是我得到这个错误:
can't unmarshal tftypes.String into *map[string]tftypes.Value, expected
map[string]tftypes.Value
尝试使用 yamldecode
将其转换为 yaml 也不起作用,因为 yamldecode
不支持多文档 yaml 文件。
我可以使用 exec,但我在等待 kubernetes_manifest
资源被释放时已经这样做了。 kubernetes_manifest
仅支持单个资源还是可以用于从原始文本清单文件创建多个资源?
kubernetes_manifest
(强调我的)
Represents one Kubernetes resource by supplying a manifest attribute
在我看来,它不支持多资源/多文档 yaml 文件。
但是您可以手动拆分传入文档和yamldecode
它的部分:
locals {
yamls = [for data in split("---", data.http.crd.body): yamldecode(data)]
}
resource "kubernetes_manifest" "install-crd" {
count = length(local.yamls)
manifest = local.yamls[count.index]
}
不幸的是在我的机器上这然后抱怨
'status' attribute key is not allowed in manifest configuration
恰好是 11 个清单中的一个。
而且由于我对 kubernetes 一无所知,所以我不知道这意味着什么,也不知道它是否需要修复。
或者,您始终可以将 null_resource
与获取 yaml 文档的脚本一起使用,并使用 bash 工具或 python 或安装的任何工具来转换、拆分和过滤传入的内容yaml.
我使用 kubectl provider 让它工作。最终 kubernetes_manifest
应该也能正常工作,但它目前 (v2.5.0) 仍处于测试阶段并且有一些错误。此示例仅使用 kind+name,但为了完全唯一性,它还应包括 API 和命名空间参数。
resource "kubectl_manifest" "cdr" {
# Create a map { "kind--name" => yaml_doc } from the multi-document yaml text.
# Each element is a separate kubernetes resource.
# Must use \n---\n to avoid splitting on strings and comments containing "---".
# YAML allows "---" to be the first and last line of a file, so make sure
# raw yaml begins and ends with a newline.
# The "---" can be followed by spaces, so need to remove those too.
# Skip blocks that are empty or comments-only in case yaml began with a comment before "---".
for_each = {
for pair in [
for yaml in split(
"\n---\n",
"\n${replace(data.http.crd.body, "/(?m)^---[[:blank:]]*(#.*)?$/", "---")}\n"
) :
[yamldecode(yaml), yaml]
if trimspace(replace(yaml, "/(?m)(^[[:blank:]]*(#.*)?$)+/", "")) != ""
] : "${pair.0["kind"]}--${pair.0["metadata"]["name"]}" => pair.1
}
yaml_body = each.value
}
一旦 Hashicorp 修复 kubernetes_manifest
,我建议使用相同的方法。不要使用 count+element()
,因为如果元素的顺序发生变化,Terraform 将 delete/recreate 许多不需要的资源。
resource "kubernetes_manifest" "crd" {
for_each = {
for value in [
for yaml in split(
"\n---\n",
"\n${replace(data.http.crd.body, "/(?m)^---[[:blank:]]*(#.*)?$/", "---")}\n"
) :
yamldecode(yaml)
if trimspace(replace(yaml, "/(?m)(^[[:blank:]]*(#.*)?$)+/", "")) != ""
] : "${value["kind"]}--${value["metadata"]["name"]}" => value
}
manifest = each.value
}
P.S。请为多文档 yamldecode
支持 Terraform feature request。将使事情比上面的正则表达式容易得多。
我想用 terraform 安装 CRD,我希望这样做会很容易:
data "http" "crd" {
url = "https://raw.githubusercontent.com/kubernetes-sigs/application/master/deploy/kube-app-manager-aio.yaml"
request_headers = {
Accept = "text/plain"
}
}
resource "kubernetes_manifest" "install-crd" {
manifest = data.http.crd.body
}
但是我得到这个错误:
can't unmarshal tftypes.String into *map[string]tftypes.Value, expected
map[string]tftypes.Value
尝试使用 yamldecode
将其转换为 yaml 也不起作用,因为 yamldecode
不支持多文档 yaml 文件。
我可以使用 exec,但我在等待 kubernetes_manifest
资源被释放时已经这样做了。 kubernetes_manifest
仅支持单个资源还是可以用于从原始文本清单文件创建多个资源?
kubernetes_manifest
(强调我的)
Represents one Kubernetes resource by supplying a manifest attribute
在我看来,它不支持多资源/多文档 yaml 文件。
但是您可以手动拆分传入文档和yamldecode
它的部分:
locals {
yamls = [for data in split("---", data.http.crd.body): yamldecode(data)]
}
resource "kubernetes_manifest" "install-crd" {
count = length(local.yamls)
manifest = local.yamls[count.index]
}
不幸的是在我的机器上这然后抱怨
'status' attribute key is not allowed in manifest configuration
恰好是 11 个清单中的一个。
而且由于我对 kubernetes 一无所知,所以我不知道这意味着什么,也不知道它是否需要修复。
或者,您始终可以将 null_resource
与获取 yaml 文档的脚本一起使用,并使用 bash 工具或 python 或安装的任何工具来转换、拆分和过滤传入的内容yaml.
我使用 kubectl provider 让它工作。最终 kubernetes_manifest
应该也能正常工作,但它目前 (v2.5.0) 仍处于测试阶段并且有一些错误。此示例仅使用 kind+name,但为了完全唯一性,它还应包括 API 和命名空间参数。
resource "kubectl_manifest" "cdr" {
# Create a map { "kind--name" => yaml_doc } from the multi-document yaml text.
# Each element is a separate kubernetes resource.
# Must use \n---\n to avoid splitting on strings and comments containing "---".
# YAML allows "---" to be the first and last line of a file, so make sure
# raw yaml begins and ends with a newline.
# The "---" can be followed by spaces, so need to remove those too.
# Skip blocks that are empty or comments-only in case yaml began with a comment before "---".
for_each = {
for pair in [
for yaml in split(
"\n---\n",
"\n${replace(data.http.crd.body, "/(?m)^---[[:blank:]]*(#.*)?$/", "---")}\n"
) :
[yamldecode(yaml), yaml]
if trimspace(replace(yaml, "/(?m)(^[[:blank:]]*(#.*)?$)+/", "")) != ""
] : "${pair.0["kind"]}--${pair.0["metadata"]["name"]}" => pair.1
}
yaml_body = each.value
}
一旦 Hashicorp 修复 kubernetes_manifest
,我建议使用相同的方法。不要使用 count+element()
,因为如果元素的顺序发生变化,Terraform 将 delete/recreate 许多不需要的资源。
resource "kubernetes_manifest" "crd" {
for_each = {
for value in [
for yaml in split(
"\n---\n",
"\n${replace(data.http.crd.body, "/(?m)^---[[:blank:]]*(#.*)?$/", "---")}\n"
) :
yamldecode(yaml)
if trimspace(replace(yaml, "/(?m)(^[[:blank:]]*(#.*)?$)+/", "")) != ""
] : "${value["kind"]}--${value["metadata"]["name"]}" => value
}
manifest = each.value
}
P.S。请为多文档 yamldecode
支持 Terraform feature request。将使事情比上面的正则表达式容易得多。