如何使用Terraform动态生成sudoers文件并创建K8s ConfigMap
实现方案
问题根因
- 原方案对模板数据源和ConfigMap都配置了count循环,会生成与用户数量相同的多份ConfigMap,每份ConfigMap仅包含单个用户的sudo权限,不符合单sudoers文件包含所有用户权限的需求
- 模板未实现列表遍历逻辑,无法批量生成多用户的权限条目
步骤1:优化变量定义(variables.tf)
明确变量类型为字符串列表,符合Terraform类型规范:
variable "members_new" { type = list(string) default = ["username1", "username2", "username3"] }
步骤2:编写模板文件(tpl/sudoers.tpl)
使用Terraform模板的for循环语法批量生成用户权限行:
# This file MUST be edited with the 'visudo' command as root. # # Please consider adding local content in /etc/sudoers.d/ instead of # directly modifying this file. # # See the man page for details on how to write a sudoers file. # Defaults env_reset Defaults mail_badpass Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin" # Host alias specification # User alias specification # Cmnd alias specification Cmnd_Alias USRCMDS = /usr/sbin/service ssh restart, /usr/bin/passwd # User privilege specification root ALL=(ALL:ALL) ALL # Members of the admin group may gain root privileges %admin ALL=(ALL) ALL # Allow members of group sudo to execute any command %sudo ALL=(ALL:ALL) ALL # See sudoers(5) for more information on "#include" directives: #includedir /etc/sudoers.d %{ for user in users ~} ${user} ALL=(root) NOPASSWD: /usr/sbin/service ssh restart, /usr/bin/passwd ${user} %{ endfor ~}
步骤3:调整Terraform主逻辑
废弃count循环,直接用templatefile函数渲染模板,仅生成1份ConfigMap:
resource "kubernetes_config_map" "f1ai_sudoers" { depends_on = [helm_release.project] metadata { name = "sudoers-cm" namespace = kubernetes_namespace.project.metadata.0.name } data = { "sudoers" = templatefile("${path.module}/tpl/sudoers.tpl", { users = var.members_new }) } }
注意事项
将该ConfigMap挂载到节点/容器的/etc/sudoers路径时,需要确保文件权限为0440、所有者为root:root,否则sudo会触发权限校验报错。
内容的提问来源于stack exchange,提问作者Kishor Yerrabothu
相关产品推荐
相关产品推荐

