You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Terraform为AWS SFTP服务器用户绑定多个SSH密钥

问题

需要为AWS SFTP服务器的多个用户创建并绑定多个唯一SSH密钥,模块调用时通过对象映射传递用户和SSH密钥信息:

module "users" {
  source = "../../sftp_user"
  users = {
    "user1" = {
      region     = "us-east-1",
      server_id  = module.sftp_server.server_id,
      (...其他参数),
      public_keys = ["ssh key 1", "ssh key 2", "ssh key 3"]
     },
     "user2" = {(...参数)}
   }
}

当前的资源块仅能为每个用户绑定第一个SSH密钥:

resource "aws_transfer_ssh_key" "sshkeysattachment" {
  for_each = var.users
  server_id = each.value.server_id
  user_name = each.key
  body = each.value.public_keys[0]                   # 仅获取第一个SSH密钥
  depends_on = [aws_transfer_user.users]             # 确保用户已创建完成
}

尝试同时使用count和for_each时触发Terraform报错:

The "count" and "for_each" meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of resources to be created.

尝试的错误代码如下:

resource "aws_transfer_ssh_key" "sshkeysattachment" {
  for_each = {
    for user, config in var.users : 
      "${user}-${count.index}" => config if length(config.public_keys) > 0 
  }

  count     = length(each.value.public_keys)
  server_id = each.value.server_id
  user_name = each.key

  body = each.value.public_keys[count.index]

  depends_on = [aws_transfer_user.user]
}

需要实现为每个用户绑定其对应的所有SSH密钥。

解决方案

要实现每个用户绑定所有SSH密钥,需要先将用户与密钥的组合扁平化为一个唯一的键值对集合,再用for_each遍历这个集合,避免同时使用count和for_each。

具体代码如下:

resource "aws_transfer_ssh_key" "sshkeysattachment" {
  # 扁平化用户和密钥的组合:生成格式为"用户名-密钥索引"的唯一键
  for_each = flatten([
    for user_name, user_config in var.users : [
      for idx, pub_key in user_config.public_keys : {
        key         = "${user_name}-${idx}"
        server_id   = user_config.server_id
        user        = user_name
        public_key  = pub_key
      }
    ]
  ])

  server_id = each.value.server_id
  user_name = each.value.user
  body      = each.value.public_key

  depends_on = [aws_transfer_user.users]
}

代码说明

  1. 扁平化处理:通过嵌套的for表达式,遍历每个用户的所有SSH密钥,为每个密钥生成一个包含server_id、user_name、public_key的对象,并用${user_name}-${idx}作为唯一标识键。
  2. for_each遍历:将扁平化后的列表转换为适合for_each的映射(Terraform会自动将列表转换为以元素key字段为键的映射),确保每个SSH密钥对应一个独立的aws_transfer_ssh_key资源。
  3. 避免冲突:这种方式完全依赖for_each,无需使用count,规避了两者互斥的问题,同时保证每个资源实例的唯一标识。

内容的提问来源于stack exchange,提问作者Satyam Raj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 16:40:11