2017-07-19 3 views
2

Je crée une instance AWS RDS avec différentes CMK KMS selon que l'environnement est Production ou Non-Production. J'ai donc deux ressources qui utilisent le nombre de terraform si:Interpolation de Terraform dans les sorties

count = "${var.bluegreen == "nonprod" ? 1 : 0}" 

Cela tourne une instance RDS avec des clés différentes KMS avec des adresses différentes. J'ai besoin de capturer ce point de terminaison (ce que je fais avec terraform show après la fin de la construction) alors pourquoi cela ne fonctionne pas dans Terraform?

output "rds_endpoint" { 
    value = "${var.bluegreen == "nonprod" ? aws_db_instance.rds_nonprod.address : aws_db_instance.rds_prod.address}" 
} 
+1

Je sais comment contourner ce problème - kms_key_id = "$ {var.bluegreen ==" nonprod "? Arn: aws: kms: eu-ouest-2: 1234567890: key/foo": "arn: aws: kms : eu-west-2: 1234567890: clé/barre "}" dans une seule ressource aws_db_instance réduisant la ressource aws_db_instance à une (à partir de deux). – Chris

Répondre

1

Il est une erreur pour accéder aux attributs d'une ressource qui a count = 0, et malheureusement Terraformez vérifie actuellement les deux « côtés » d'une condition au cours de son étape de contrôle, de sorte que des expressions comme cela peut échouer. Parallèlement à cela, il existe un comportement actuel selon lequel les erreurs dans les sorties ne sont pas explicitement affichées, car les sorties peuvent être remplies lorsque l'état n'est pas encore terminé (par exemple en raison de l'utilisation de -target). Ces ennuis tous résument à beaucoup de confusion dans ce cas. Au lieu d'utiliser une expression conditionnelle dans ce cas, il est préférable d'utiliser "expressions splat", qui évalue à une liste vide dans le cas count = 0. Cela ressemble à quelque chose comme ce qui suit:

output "rds_endpoint" { 
    value = "${element(concat(aws_db_instance.rds_nonprod.*.address, aws_db_instance.rds_prod.*.address), 0)}" 
} 

Cela prend le premier élément d'une liste créée par concaténant toutes les adresses nonprod et toutes les adresses de prod. En raison de la façon dont vous avez configuré count sur ces blocs de ressources, la liste résultante ne comportera qu'un seul élément et prendra donc simplement cet élément. En général, pour déboguer des problèmes avec des sorties, il peut être utile d'évaluer les expressions dans terraform console, ou ailleurs dans une config, pour contourner la limitation que les erreurs sont silencieusement ignorées sur les sorties.

+0

Bonne réponse, je n'avais pas considéré les "expressions splat". D'après votre réponse, puis-je supposer qu'une autre méthode est disponible pour la façon dont j'ai utilisé? Je demande comme j'ai vu un comportement inattendu de cette méthode - par exemple une ressource de règle de groupe de sécurité aws étant détruite lors d'une seconde exécution lorsque la comparaison de comptage devrait être la même (bluegreen est toujours nonprod). – Chris

+0

En effet, la fonction 'element' présente des défis: si vous lui passez une valeur de même partielle, son résultat est calculé car le noyau de Terraform traite toutes les fonctions de manière conservatrice. Dans ce cas, je ne m'attendais pas à des problèmes car cela ressemblait plus à une situation de type «l'un ou l'autre», mais cela devient délicat si vous créez un tas de ressources corrélées avec 'count.index' connectant entre elles. Tant que 'bluegreen' reste sur 'nonprod', les choses devraient être stables. –