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]
}
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]
}