web-dev-qa-db-fra.com

mapper la liste des cartes sur une liste des valeurs de champ sélectionnées dans terraform

Si les ressources utilisent un paramètre count pour spécifier des ressources multiples dans terraform, il existe une syntaxe simple permettant de fournir une liste/un tableau de champs dédiés pour les instances de ressources.

par exemple

aws_subnet.foo.*.id

Depuis un certain nombre de versions, il est possible de déclarer des variables avec une structure complexe, par exemple des listes de cartes.

variable "data" {
  type = "list"
  default = [
    {
      id = "1"
      ...
    },
    {
      id = "10"
      ...
    }
  ]
}

Je cherche une possibilité de faire de même pour les variables que je peux faire pour les ressources multiples: projection d'un tableau sur un tableau de valeurs de champs des éléments du tableau.

Malheureusement 

var.data.*.id

ne fonctionne pas comme pour les ressources. Y a-t-il une possibilité de le faire?

7
Uwe Krüger

template_file peut vous aider.

data "template_file" "data_id" {
  count = "${length(var.data)}"
  template = "${lookup(var.data[count.index], "id")}"
}

Ensuite, vous obtenez une liste "${data.template_file.data_id.*.rendered}", dont les éléments ont la valeur "id".

Vous pouvez obtenir son élément par index comme ceci

"${data.template_file.data_id.*.rendered[0]}"

ou par élément de fonction ()

"${element(data.template_file.data_id.*.rendered, 0)}"
14
Bruce

Au moment de la rédaction de ce manuel, Terraform ne dispose pas d'une fonction de projection généralisée dans son langage d'interpolation. La "syntaxe splat" est implémentée en tant que cas particulier pour les ressources.

Bien que la structure profonde soit possible, son utilisation n’est pas encore pratique, il est donc recommandé de garder les choses relativement plates. À l'avenir, il est probable que de nouvelles fonctionnalités linguistiques seront ajoutées pour rendre ce type de choses plus utilisable.

5
Martin Atkins

Si vous avez trouvé une solution fonctionnelle utilisant le rendu de modèle pour contourner la liste des problèmes de la carte:

resource "aws_instance" "k8s_master" {
  count                       = "${var.master_count}"
  AMI                         = "${var.AMI}"
  instance_type               = "${var.instance_type}"
  vpc_security_group_ids      = ["${aws_security_group.k8s_sg.id}"]
  associate_public_ip_address = false
  subnet_id                   = "${element(var.subnet_ids,count.index % length(var.subnet_ids))}"
  user_data                   = "${file("${path.root}/files/user_data.sh")}"
  iam_instance_profile        = "${aws_iam_instance_profile.master_profile.name}"

  tags = "${merge(
    local.k8s_tags,
    map(
      "Name", "k8s-master-${count.index}",
      "Environment", "${var.environment}"
    )
  )}"
}

data "template_file" "k8s_master_names" {
  count    = "${var.master_count}"
  template = "${lookup(aws_instance.k8s_master.*.tags[count.index], "Name")}"
}

output "k8s_master_name" {
  value = [
    "${data.template_file.k8s_master_names.*.rendered}",
  ]
}

Cela se traduira par la sortie suivante:

k8s_master_name = [
    k8s-master-0,
    k8s-master-1,
    k8s-master-2
]
1
Boeboe