terraform: есть ли способ динамически создавать операторы политики iam?

Версия Terraform: 0.11

Я запускаю несколько кластеров eks и пытаюсь включить учетную запись службы на основе ролей IAM во всех кластерах, следующих за этим документом:https://www.terraform.io/docs/providers/aws/r/eks_cluster.html

Это работает, когда я жестко кодирую имя кластера в заявлении политики и создаю несколько операторов.

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 теперь может находить кластеры, НО также генерирует несколько политик. И это не сработает, поскольку в следующем синтаксисе accept_role_policy не принимает список

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

Похоже, что вместо создания нескольких политик мне нужно сгенерировать несколько операторов в одной политике (поэтому я могу добавить к одной iam_role). Кто-нибудь делал что-то подобное раньше? Спасибо.

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.

Другие вопросы по тегам