如何处理 eks 假设政策的列表

How to handle lists for eks assume policy

作为升级的一部分,我有 2 个 eks 集群。我想处理假设策略,使其可以访问两个 eks 集群。两个集群都在同一个 AWS 账户中。

我希望我的政策看起来像下面的政策。这样我们就不会更新任何角色,而只会更新处理两个集群的假设策略。

locals.tf

  eks_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::11111111111:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/yyyyyyyyyyyyyyyyyy",
        "Federated": "arn:aws:iam::11111111111:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/yyyyyyyyyyyyyyyyyy"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.eks.us-east-1.amazonaws.com/id/xxxxxxxxxxxxxx:sub": "system:serviceaccount:%s:%s",
          "oidc.eks.us-east-1.amazonaws.com/id/xxxxxxxxxxxxx:sub": "system:serviceaccount:%s:%s"
        }
      }
    }
  ]
}
EOF

Launcher = "作业启动器"

Role.tf

resource "aws_iam_role" "launcher" {
  name               = local.Launcher
  assume_role_policy = format(local.eks_policy, "my-namepsace", local.Launcher)
  tags = {
    terraform = "true"
    owner     = "stg"
  }
}

所以我在locals.tf

中这样尝试过
  count = length(var.federated)

      eks_policy = <<EOF
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::11111111111:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/${join(",",${element(var.federated, count.index)})}",
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "oidc.eks.us-east-1.amazonaws.com/id/${join(",", ${element(var.federated, count.index)})}:sub": "system:serviceaccount:%s:%s"
            }
          }
        }
      ]
    }

但我收到一个错误,因为无法在 locals.tf 中使用计数, 谁能帮我一下。

更新2:

我们如何得到这样的东西

"Condition": {
        "StringEquals": {
          "oidc.eks.us-east-1.amazonaws.com/id/xxxxxxxxxxxxx:sub": "system:serviceaccount:ihr-system:ihr-system-external-dns18",
          "oidc.eks.us-east-1.amazonaws.com/id/yyyyyyyyyyyyy:sub": "system:serviceaccount:ihr-system:ihr-system-external-dns"
        }
      }

我试过了,

联合 = [ "xxxxxxxxxxxxxxxxxxxxxxxxx", “yyyyyyyyyyyyyyyyyyyyy” ]

    Condition : {
      "StringEquals" : {
        join("",[for oidc in local.federated:"oidc.eks.us-east-1.amazonaws.com/id/${oidc}:sub:","system:serviceaccount:%s:%s"])
    }

getting syntax error near in , local expected and another error got ',' or '}' expected got '"system:serviceaccount.."'

for oidc in local.federated

Terraform format 函数要求每个占位符都有一个参数。来自文档:

The specification is a string that includes formatting verbs that are introduced with the % character. The function call must then have one additional argument for each verb sequence in the specification. The verbs are matched with consecutive arguments and formatted as directed, as long as each given argument is convertible to the type required by the format verb.

话虽如此,您需要提供四个参数,即使在您的情况下它们是相同的局部变量:

format(local.eks_policy, "my-namepsace", local.Launcher, "my-namepsace", local.Launcher)

根据您的用例,您还可以考虑使用配置定义对象列表并使用循环构建策略语句以准备最终字符串。

更新 1

动态生成的示例可能如下所示,其中任何帐户都可以从变量 local.params:

中承担角色
locals {
  # key = account ID, value could be whatever
  params = {
    "1111" = { foo = "bar" },
    "2222" = { x = "y" }
  }

  assume_role_str = jsonencode({
    # skipped beginning for brevity
    Effect = "Allow",
    Principal = {
      Federated: [ for account in keys(local.params): "arn:aws:iam::11111111111:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/:${account}" ]
    }
  })
}