如何使用Terraform将GitHub来源的CRD部署到Kubernetes集群
问题结论
kubernetes_manifest 资源仅支持传入单个Kubernetes资源的结构化映射作为manifest参数,不支持直接传入多文档YAML原始文本,也不支持单次创建多个资源。
报错原因
- 初始写法直接将HTTP请求返回的字符串类型YAML内容传给要求结构化映射的
manifest字段,类型不匹配,所以会触发can't unmarshal tftypes.String into *map[string]tftypes.Value报错。 yamldecode原生仅支持解析单文档YAML,你调用的YAML文件包含多个用---分隔的资源定义,所以直接解码会失败。
解决方案
方案1:拆分多文档YAML后批量创建
你可以通过Terraform内置的字符串函数拆分多文档内容,过滤无效片段后用for_each批量创建kubernetes_manifest资源,示例代码如下:
data "http" "crd" { url = "https://raw.githubusercontent.com/kubernetes-sigs/application/master/deploy/kube-app-manager-aio.yaml" request_headers = { Accept = "text/plain" } } locals { # 按多文档分隔符拆分,过滤空内容、注释片段 crd_manifests = [ for fragment in split("---", data.http.crd.body) : yamldecode(fragment) if length(regexall("^\\s*#", fragment)) == 0 && length(trimspace(fragment)) > 0 ] } # 批量创建每个资源,用apiVersion+kind+资源名作为唯一索引 resource "kubernetes_manifest" "install_crd" { for_each = { for idx, manifest in local.crd_manifests : "${manifest.apiVersion}_${manifest.kind}_${manifest.metadata.name}" => manifest } manifest = each.value }
注意需要使用2.0及以上版本的Kubernetes Provider,且提前开启kubernetes_manifest资源的使用权限。
方案2:使用kubectl Provider简化处理
如果不想手动处理多文档拆分逻辑,可以使用社区维护的kubectl Provider,直接支持传入多文档YAML原始内容,无需提前解码拆分,示例代码如下:
data "http" "crd" { url = "https://raw.githubusercontent.com/kubernetes-sigs/application/master/deploy/kube-app-manager-aio.yaml" request_headers = { Accept = "text/plain" } } resource "kubectl_manifest" "install_crd" { yaml_body = data.http.crd.body }
内容的提问来源于stack exchange,提问作者red888
相关产品推荐
相关产品推荐

