如何用Terraform在多命名空间生成相同内容的Kubernetes Secret
使用Terraform创建多命名空间的Docker认证Secret
要实现你的需求,核心是通过Terraform的for_each遍历镜像仓库和命名空间的组合,同时正确生成符合Kubernetes要求的Docker认证配置并编码。以下是完整实现方案:
步骤1:预计算认证配置与实例组合
首先定义局部值,提前生成每个镜像仓库的编码后配置,以及所有需要创建Secret的(仓库+命名空间)组合:
locals { # 预计算每个镜像仓库的Docker config JSON的Base64编码 registry_auth_configs = { for reg in var.container_registries : reg.name => { encoded_config = base64encode(jsonencode({ auths = { # 为每个hostname生成认证条目 for hostname in reg.hostnames : hostname => { auth = base64encode("${reg.username}:${reg.password}") } } })) } } # 展开所有需要创建Secret的实例:每个仓库对应每个命名空间 secret_targets = flatten([ for reg in var.container_registries : [ for ns in reg.namespaces : { registry = reg.name namespace = ns # 自定义Secret名称,替换点号避免Kubernetes命名冲突 secret_name = "container-registry-${replace(reg.name, ".", "-")}" } ] ]) }
步骤2:创建Kubernetes Secret资源
使用kubernetes_secret资源,通过for_each遍历所有目标实例,自动在指定命名空间创建符合要求的Secret:
resource "kubernetes_secret" "docker_registry" { # 用仓库+命名空间作为唯一键,确保每个实例独立管理 for_each = { for target in local.secret_targets : "${target.registry}-${target.namespace}" => target } metadata { name = each.value.secret_name namespace = each.value.namespace } # 指定Secret类型为Docker认证配置 type = "kubernetes.io/dockerconfigjson" # 合并必填字段与额外指定的键,值统一使用预计算的编码配置 data = merge( { ".dockerconfigjson" = local.registry_auth_configs[each.value.registry].encoded_config }, { # 遍历当前仓库的addl_keys,生成对应的键值对 for key in [for reg in var.container_registries : reg.addl_keys if reg.name == each.value.registry][0] : key => local.registry_auth_configs[each.value.registry].encoded_config } ) }
关键细节说明
- 认证配置生成:
auth字段是用户名:密码的Base64编码,外层的.dockerconfigjson是整个配置JSON的Base64编码,完全符合Kubernetes的要求。 - 多命名空间遍历:通过
flatten和嵌套for表达式,将每个仓库的命名空间列表展开为独立实例,确保每个命名空间下都生成对应的Secret。 - 额外键处理:使用
merge函数将必填的.dockerconfigjson和addl_keys指定的键合并,所有键的值都复用同一个编码后的配置。 - 空值兼容:如果
addl_keys为空列表,代码仍能正常运行,只会生成.dockerconfigjson字段。
内容的提问来源于stack exchange,提问作者brovoca
相关产品推荐
相关产品推荐

