-1

I want to create multiple unique SSH keys for multiple users for an AWS SFTP server. In my module call, I'm creating users and SSH keys by passing a map of objects :

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

This is how my resource block looks like for attaching SSH Keys to the user. Currently I'm only able to attach the first SSH Key with it's user :

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]                   # the first SSH key will be fetched
  depends_on = [aws_transfer_user.users]             # this confirms that the users are created first
}

I have tried using count keyword with the for_each keyword. But terraform says that :

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.

For this code :

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]
}
4
  • 1
    Please share the relevant snippet of the plan since you are describing unexpected behavior. Commented Sep 9, 2024 at 13:00
  • Hi @MatthewSchuchard I have updated the question with the code snippet that I have tried to use Commented Sep 9, 2024 at 13:14
  • Did you chek this stackoverflow.com/questions/65292840/… ? Commented Sep 9, 2024 at 16:00
  • @MedAgou thanks for the link. I did some modifications, hit some bugs/ errors and I gradually came to a solution. Commented Sep 10, 2024 at 8:19

1 Answer 1

0

I tried to flatten the map into a set of strings which will be of the form: "<username>:@:<ssh-key>" and put the set in for_each. Then, I performed split(":@:", each.value) to split the key which is inside the set and then mapping first index ([0]) to user_name and second index ([1]) to body, similar is the case for server_id as well.

resource "aws_transfer_ssh_key" "ssh_keys_attachment" {
  depends_on = [aws_transfer_user.user]
  for_each = toset(flatten([
    for user, config in var.users : [
      for key in config.public_keys : "${user}:@:${key}"
    ]
  ]))

  server_id = aws_transfer_user.user[split(":@:", each.key)[0]].server_id
  user_name = split(":@:", each.value)[0]
  body      = split(":@:", each.value)[1]
}

Reference: https://stackoverflow.com/a/65294075/15176148

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.