web-dev-qa-db-fra.com

Terraform 0.12 imbriqué pour les boucles

J'essaie d'implémenter des boucles imbriquées à l'aide des nouvelles fonctionnalités de Terraform 0.12 afin de parcourir les utilisateurs AWS IAM, chacun pouvant avoir une ou plusieurs politiques attachées. La variable utilisée pour représenter cette liste est de type map (list (string)) et ressemble à ceci:

{
  "user 1" = [ "policy1", "policy2" ],
  "user 2" = [ "policy1" ]
}

Obtenir la liste des utilisateurs à créer est assez facile via keys(), mais comme il n'existe actuellement aucun mécanisme pour imbriquer la création de ressources en boucle dans Terraform, les attachements de stratégie doivent se produire comme une boucle singulière indépendante de chaque utilisateur. Donc, j'essaie de construire une liste d'associations utilisateur: politique à partir de l'entrée de la carte qui ressemblerait à quelque chose comme ceci sur la base de l'exemple ci-dessus:

[
  [ "user1", "policy1" ],
  [ "user1", "policy2" ],
  [ "user2", "policy1" ]
]

J'essaie de construire cette liste et de la stocker dans une variable locale comme celle-ci, où var.iam-user-policy-map Est la carte d'entrée:

locals {
  ...
  association-list = [
    for user in keys(var.iam-user-policy-map):
    [
      for policy in var.iam-user-policy-map[user]:
      [user, policy]
    ]
  ]
  ...
}

Cependant, j'obtiens des erreurs lorsque j'essaie d'accéder aux valeurs de cette liste imbriquée. J'essaie d'accéder à la partie utilisateur de l'association avec la référence local.association-list[count.index][0] Et la politique avec local.association-list[count.index][1], Mais en exécutant terraform plan, Cela génère une erreur:

Error: Incorrect attribute value type

  on main.tf line 27, in resource "aws_iam_user_policy_attachment" "test-attach":
  27:   user = local.association-list[count.index][0]

Inappropriate value for attribute "user": string required.


Error: Incorrect attribute value type

  on main.tf line 27, in resource "aws_iam_user_policy_attachment" "test-attach":
  27:   user = local.association-list[count.index][0]

Inappropriate value for attribute "user": string required.


Error: Invalid index

  on main.tf line 28, in resource "aws_iam_user_policy_attachment" "test-attach":
  28:   policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index][1]}"
    |----------------
    | count.index is 0
    | local.association-list is Tuple with 2 elements

The given key does not identify an element in this collection value.


Error: Invalid template interpolation value

  on main.tf line 28, in resource "aws_iam_user_policy_attachment" "test-attach":
  28:   policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index][1]}"
    |----------------
    | count.index is 1
    | local.association-list is Tuple with 2 elements

Cannot include the given value in a string template: string required.

Qu'est-ce que je fais mal?

10
ViggyNash

L'expression for dans votre valeur locale association-list produit une liste de listes de listes de chaînes, mais vos références s'y rapportent la traitent comme une liste de listes de chaînes.

Pour obtenir la représentation aplatie que vous vouliez, vous pouvez utiliser la fonction flatten, mais comme elle regrouperait tout autrement dans une liste plate nique, je recommanderais de faire de la valeur la plus interne un objet à la place. . (Cela rendra également les références plus claires.)

locals {
  association-list = flatten([
    for user in keys(var.iam-user-policy-map) : [
      for policy in var.iam-user-policy-map[user] : {
        user   = user
        policy = policy
      }
    ]
  ])
}

Le résultat de cette expression aura la forme suivante:

[
  { user = "user1", policy = "policy1" },
  { user = "user1", policy = "policy2" },
  { user = "user2", policy = "policy2" },
]

Vos références peuvent alors se présenter sous la forme suivante:

user = local.association-list[count.index].user
policy_arn = "arn:aws-us-gov:iam::aws:policy/${local.association-list[count.index].policy}"
11
Martin Atkins