如何在Terraform模块中遍历K8s多目录下的YAML清单文件?
在Terraform模块中遍历指定目录下的所有Kubernetes YAML文件
要在provisioning-aks模块的main.tf中遍历根目录k8s/elk和k8s/ingest下的所有YAML文件,你可以借助Terraform的fileset函数配合for_each批量创建kubernetes_manifest资源,具体实现分两种场景:
场景1:所有YAML都是单文档格式
如果每个YAML文件只包含一个Kubernetes资源定义,直接使用以下代码:
resource "kubernetes_manifest" "k8s_resources" { # 遍历k8s/elk和k8s/ingest下的所有.yaml文件 for_each = fileset(path.root, "k8s/{elk,ingest}/*.yaml") manifest = yamldecode(file("${path.root}/${each.key}")) }
代码说明:
path.root:指向Terraform项目的根目录(即包含根main.tf的目录),由于provisioning-aks模块在modules子目录下,必须通过根路径才能访问到k8s目录。fileset(path.root, "k8s/{elk,ingest}/*.yaml"):匹配k8s/elk和k8s/ingest下所有.yaml后缀的文件,返回包含文件相对路径的集合。for_each:基于文件集合创建多个kubernetes_manifest实例,每个文件对应一个独立资源,避免重复或遗漏。
场景2:存在多文档YAML文件(单个文件包含多个资源)
如果有的YAML文件用---分隔多个Kubernetes资源定义,需要先拆分文档再创建资源:
# 先获取所有目标YAML文件的路径 locals { k8s_yaml_files = fileset(path.root, "k8s/{elk,ingest}/*.yaml") # 拆分所有多文档YAML,将每个文档转为独立的资源项 k8s_manifests = flatten([ for file_path in local.k8s_yaml_files : [ for doc_idx, doc in enumerate(yamldecode(file("${path.root}/${file_path}"))) : { id = "${file_path}-${doc_idx}" content = doc } ] ]) } # 遍历拆分后的所有文档创建资源 resource "kubernetes_manifest" "k8s_resources" { for_each = { for m in local.k8s_manifests : m.id => m.content } manifest = each.value }
代码说明:
locals.k8s_manifests:通过嵌套循环读取每个YAML文件,拆分其中的多文档,为每个文档生成唯一ID(文件路径+文档索引),确保资源实例不重复。flatten:将嵌套列表转为一维列表,方便后续遍历。
注意事项
- 确保所有YAML文件都是有效的Kubernetes资源定义,否则
yamldecode会解析失败。 - 如果不同文件中存在同名同命名空间的Kubernetes资源,部署时会触发冲突,需提前检查文件内容。
- 若需要包含子子目录,可将
fileset的匹配模式改为k8s/{elk,ingest}/**/*.yaml。
内容的提问来源于stack exchange,提问作者Jinx59
相关产品推荐
相关产品推荐

