Terraform:是否有一种动态创建IAM策略语句的方法?

10

使用的 Terraform 版本为 0.11。

我正在运行多个 eks 集群,并尝试按照此文档在所有集群中启用基于 IAM 角色的服务帐户: https://www.terraform.io/docs/providers/aws/r/eks_cluster.html#enabling-iam-roles-for-service-accounts

当我在策略语句中硬编码集群名称并创建多个语句时,它可以工作。

data "aws_iam_policy_document" "example_assume_role_policy" {

# for cluster 1

  statement {
    actions = ["sts:AssumeRoleWithWebIdentity"]
    effect  = "Allow"

    condition {
      test     = "StringEquals"
      variable = "${replace(aws_iam_openid_connect_provider.example1.url, "https://", "")}:sub"
      values   = ["system:serviceaccount:kube-system:aws-node"]
    }

    principals {
      identifiers = ["${aws_iam_openid_connect_provider.example1.arn}"]
      type        = "Federated"
    }
  }
}

因为我有多个集群,所以我希望能够动态生成语句,因此我进行了以下更改:

我创建了一个 count 变量,并更改了 principals 和 condition 中的值。

count = "${length(var.my_eks_cluster)}" 

    condition {
      test     = "StringEquals"
      variable = "${replace(element(aws_iam_openid_connect_provider.*.url, count.index), "https://", "")}:sub"
      values   = ["system:serviceaccount:kube-system:aws-node"]
    }

    principals {
      identifiers = ["${element(aws_iam_openid_connect_provider.*.url, count.index)}"]
      type        = "Federated"
    }

Terraform现在可以找到集群,但也能生成多个策略。 然而这样是行不通的,因为在如下语法中,"assume_role_policy"不能接受列表。

resource "aws_iam_role" "example" {
  assume_role_policy = "${data.aws_iam_policy_document.example_assume_role_policy.*.json}"
  name               = "example"
}

似乎我需要在一个策略中生成多个声明(以便可以添加到一个iam_role),而不是创建多个策略。有没有人之前做过类似的事情?谢谢。

感谢 @ydaetskcoR。我需要设置的是信任实体而不是权限,这就是为什么我必须使用 assume_iam_role。assume__role_policy 不接受列表,所以我想知道是否有一种方法可以在一个策略中创建主体语句? - yla
1个回答

24

您只想要一个策略,因此在您的策略中不应使用count参数。 相反,您需要多个语句,如下所示:

data "aws_iam_policy_document" "example" {
  statement {
    # ...
  }
  statement {
    # ...
  }
}

现在你可以直接硬编码它(也许这将是测试其是否有效的好方法)。 如果您想从变量动态生成它,则需要一个 dynamic 块,如此处所述:https://www.terraform.io/docs/configuration/expressions.html

在您的情况下,可能是这样:

data "aws_iam_policy_document" "example" {
  dynamic "statement" {
    for_each = aws_iam_openid_connect_provider

    content {
      actions = ["sts:AssumeRoleWithWebIdentity"]
      effect  = "Allow"

      condition {
        test     = "StringEquals"
        variable = "${replace(statement.value.url, "https://", "")}:sub"
          values   = ["system:serviceaccount:kube-system:aws-node"]
      }

      principals {
        identifiers = ["${statement.value.arn}"]
        type        = "Federated"
      }      
    }
  }
}

我认为"dynamic"只在TensorFlow 0.12或之后版本才可用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接