web-dev-qa-db-fra.com

Comment vérifier si une chaîne contient une sous-chaîne en interpolation terraforme?

Comment vérifiez-vous si une chaîne terraform contient une autre chaîne?

Par exemple, je veux traiter spécialement les espaces de travail terraform avec "tmp" dans le nom (par exemple, permettre la suppression d'instances rds sans instantané), donc quelque chose comme ceci:

locals
{
  is_tmp = "${"tmp" in terraform.workspace}"
}

Pour autant que je sache, la fonction d'interpolation substr ne fait pas cela.

11
JDiMatteo

Vous pouvez indirectement rechercher des sous-chaînes en utilisant replace , par ex.

locals
{
  is_tmp = "${replace(terraform.workspace, "tmp", "") != terraform.workspace}"
}
19
JDiMatteo

Pour terraform 0.12.xx, apparemment, vous êtes censé utiliser regexall pour ce faire.

Dans le manuel de terraform 0.12.XX:

[ https://www.terraform.io/docs/configuration/functions/regexall.html] [1]

Extrait pertinent: regexall peut également être utilisé pour tester si une chaîne particulière correspond à un modèle donné, en testant si la longueur de la liste résultante des correspondances est supérieur à zéro.

Exemple du manuel:

> length(regexall("[a-z]+", "1234abcd5678efgh9"))
2

> length(regexall("[a-z]+", "123456789")) > 0
false

L'exemple appliqué à votre cas dans la syntaxe terraform 0.12.xx devrait ressembler à:

locals
{
  is_tmp = length(regexall(".*tmp.*", terraform.workspace)) > 0
}

Il indique également spécifiquement dans le manuel de ne pas utiliser "regex" mais plutôt d'utiliser regexall.

Si le modèle donné ne correspond pas du tout, l'expression régulière soulève une erreur. Pour tester si un modèle donné correspond à une chaîne, utilisez regexall et testez que le résultat a une longueur supérieure à zéro.

Comme indiqué ci-dessus, cela est dû au fait que vous obtiendrez une erreur d'exception lorsque vous essayez de l'utiliser dans les versions ultérieures de 0.12.xx qui sont maintenant disponibles lorsque vous exécutez le plan. C'est ainsi que j'ai découvert cela et pourquoi j'ai posté la nouvelle réponse ici.

6
Isaac Egglestone

Utilisez remplacer (chaîne, rechercher, remplacer) comme dans l'extrait de code:

// string contains ABBA = result is ABBA
output "match" {
  value = "${ replace("xxxABBAyyy", "/(?:.*)(ABBA)(?:.*)/", "$1") }"
}
// string doesn't contain ABBA = result is original string
output "no_match" {
  value = "${ replace("xxxBABAyyy", "/(?:.*)(ABBA)(?:.*)/", "$1")}"
}
// string contains ABBA (ingorecase) = result is AbBA
output "equals_ignorecase" {
  value = "${ replace("xxxAbBAyyy", "/(?:.*)((?i)ABBA)(?:.*)/", "$1")}"
}

Une sortie de terraform apply est:

Outputs:

equals_ignorecase = AbBA
match = ABBA
no_match = xxxBABAyyy
0
Denis Kalinin

Comme @MechaStorm Avec Terrafor 0.12.7+, vous pouvez utiliser regex pour faire quoi pour retourner une valeur booléenne si votre chaîne contient une sous-division particulière

locals {
  is_tmp = contains(regex("^(?:.*(tmp))?.*$",terraform.workspace),"tmp")
}

La requête d'expression régulière renvoie une liste de groupes de capture pour tous les caractères avant tmp, tmp s'il est trouvé, tous les caractères après tmp. Contient ensuite recherche "tmp" dans la liste et retourne vrai ou faux. J'utilise ce type de connexion dans ma propre terraform.

0
Scott Heath

Dans la terraform 0.12.7, nous avons maintenant regex . Cela peut aider à simplifier du code et à le rendre lisible pour certains (peut-être?)

> regex("[a-z]+", "53453453.345345aaabbbccc23454")
aaabbbccc
0
MechaStorm