Invalid key when creating local from map

Here is my variable gh_runners


gh_runners = {
  gh_runner_ubuntu_1 = {
    app_name        = "foobar-runner-1",
    ami             = "ami-0b5df848226550db1" # Ubuntu 22.04
    key_name        = "mykey",
    instance_type   = "t2.small",
    runner_id       = "foobar-runner-1",
    runner_name     = "foobar-runner-1",
    github_repo_url = "https://github.com/MyRepo/foobar",
    labels          = ["self-hosted", "foobar-runner-1", "aws"]
    start_time      = "cron(0 7 * * ?)" # 07:00 UTC
    stop_time       = "cron(0 23 * * ?)" # 23:00 UTC
  }
  gh_runner_ubuntu_2 = {
    app_name        = "foobar-runner-1",
    ami             = "ami-0b5df848226550db1" # Ubuntu 22.04
    key_name        = "mykey",
    instance_type   = "t2.small",
    runner_id       = "foobar-runner-2",
    runner_name     = "foobar-runner-2",
    github_repo_url = "https://github.com/MyRepo/foobar",
    labels          = ["self-hosted", "foobar-runner-2", "aws"]
    start_time      = "cron(0 7 * * ?)" # 07:00 UTC
    stop_time       = "cron(0 23 * * ?)" # 23:00 UTC
  }
}

I am trying to construct the following local

    resource_policies = {
      for k in var.gh_runners : k => {
        effect = "Allow",
        principals = {
          AWS = {
            identifiers = [format("arn:aws:iam::%s:role/%s_github_runners_role", var.aws_account_id, k)]
          }
        },
        actions = [
          "secretsmanager:GetSecretValue",
          "secretsmanager:DescribeSecret",
          "secretsmanager:ListSecretVersionIds",
          "secretsmanager:UpdateSecret"
        ]
      }
    }

Why does this break as follows:

 Error: Invalid object key
│
│   on secret.tf line 25, in locals:
│   24:     resource_policies = {
│   25:       for k in var.gh_runners : k => {
│   26:         effect = "Allow",
│   27:         principals = {
│   28:           AWS = {
│   29:             identifiers = [format("arn:aws:iam::%s:role/%s_github_runners_role", var.aws_account_id, k)]
│   30:           }
│   31:         },
│   32:         actions = [
│   33:           "secretsmanager:GetSecretValue",
│   34:           "secretsmanager:DescribeSecret",
│   35:           "secretsmanager:ListSecretVersionIds",
│   36:           "secretsmanager:UpdateSecret"
│   37:         ]
│   38:       }
│   39:     }
│
│ The key expression produced an invalid result: string required.

I have also tried to use string keys, i.e.

gh_runners = {
  "gh_runner_ubuntu_1" = {

same result…

It breaks because you just told Terraform to try to use

as an object key!

You have written

and believe that k will take on the keys of var.gh_runners, but actually in Terraform this means k takes on the values.

You need to write something like

      for k, v in var.gh_runners : k => {

Actually I did the following:

    resource_policies = {
      for k in keys(var.gh_runners) : k => {
        effect = "Allow",
        principals = {
          AWS = {
            identifiers = [format("arn:aws:iam::%s:role/%s_github_runners_role", var.aws_account_id, k)]
          }
        },
        actions = [
          "secretsmanager:GetSecretValue",
          "secretsmanager:DescribeSecret",
          "secretsmanager:ListSecretVersionIds",
          "secretsmanager:UpdateSecret"
        ]
      }
    }