terraform:有没有办法动态创建 iam 策略语句?

Posted

技术标签:

【中文标题】terraform:有没有办法动态创建 iam 策略语句?【英文标题】:terraform: is there a way to create iam policy statements dynamically? 【发布时间】:2020-09-22 19:42:06 【问题描述】:

地形版本: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 变量并更改了主体和条件中的值

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。我需要设置的是信任实体而不是权限,这就是为什么我必须使用假设_iam_role。假设__role_policy 没有列出,所以我想知道是否有一种方法可以在一个策略中创建主体声明? 【参考方案1】:

您只需要一个策略,因此您不应在策略中使用 count 参数。 你想要的是多个语句,就像这样

data "aws_iam_policy_document" "example" 
  statement 
    # ...
  
  statement 
    # ...
  

现在您可以直接对其进行硬编码(也许这是测试它是否有效的良好开端)。如果你想从一个变量动态生成它,你需要一个dynamic-block,如下所述: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"
            
    
  

不过,我认为“动态”仅在 TF 0.12 之后才可用。

【讨论】:

以上是关于terraform:有没有办法动态创建 iam 策略语句?的主要内容,如果未能解决你的问题,请参考以下文章