1
votes

Comment insérer une variable dans une stratégie AWS dans terraform

J'ai une politique définie dans terraform pour les ressources AWS comme ceci:

device-status-policy = <<EOF
{"Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:Connect", "Resource": "$SOMEVAR/device-status-qa*" }, { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Receive", "iot:Subscribe" ] }
   EOF

Je voudrais que la partie Ressource soit une variable, comme ceci (psuedo-code)

device-status-policy = <<EOF
{"Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:Connect", "Resource": "arn:aws:iot:us-west-2:foobaraccountid:client/device-status-qa*" }, { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Receive", "iot:Subscribe" ] }
   EOF

Toute aide est appréciée. Merci.


0 commentaires

3 Réponses :


2
votes

Remplacez $ SOMEVAR par $ {SOMEVAR} .

Veuillez consulter la syntaxe d'interpolation de chaîne Terraform . < / p>

De plus, je recommande vivement d'utiliser la source de données aws_iam_policy_document pour définir les politiques IAM, au lieu des documents ici.


0 commentaires

3
votes

La seule option raisonnable que je choisirais est la suivante:

Créer un fichier par exemple policy.tpl avec le contenu suivant:

device-status-policy = templatefile("file.tpl", { SOMEVAR = var.your_terraform_variable})

Ce fichier de politique contient la variable dont vous avez besoin.

Ensuite, vous la référencez simplement et passez la variable de la manière suivante:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "${SOMEVAR}/device-status-qa*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish",
        "iot:Receive",
        "iot:Subscribe"
      ]
    }
  ]
}

J'espère que cela aide


3 commentaires

Pourquoi considérez-vous que c'est la seule option raisonnable? Pourquoi ne pas utiliser terraform.io/docs/providers/aws/d/iam_policy_document .html


La source de données est une autre ressource que vous devez configurer. Même si cela fonctionne, il détecte souvent des changements lors de l'exécution d'un plan terraform alors qu'en fait il est inchangé. Avec l'approche / la fonction de fichier de modèles qui a été introduite dans TF 0.12, vous n'obtenez pas ce problème et pour moi c'est une manière plus propre de passer des paramètres.


Ce n'est pas du tout ainsi que fonctionne cette source de données. Il ne lit pas du tout une ressource externe. Il s'agit simplement d'un moyen de définir des stratégies AWS IAM dans HCL.



3
votes

L'interpolation de chaîne à l'aide de la syntaxe $ {...} est le plus petit changement par rapport à une chaîne JSON littérale, mais elle court le risque de rencontrer des difficultés pour produire une syntaxe JSON correcte si, par exemple, les chaînes insérées contiennent des barres obliques inverses et des guillemets que l'analyseur JSON pourrait mal interpréter.

La fonction jsonencode de Terraform peut être un bon compromis, car Terraform a une syntaxe d'objet très similaire à JSON et donc la capacité de comprendre rapidement quelle structure JSON elle produit est préservée tout en autorisant les expressions Terraform arbitraires, dont les résultats seront automatiquement encodés en utilisant la syntaxe JSON correcte:

  device-status-policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": "iot:Connect",
        "Resource": "${SOMEVAR}/device-status-qa*"
      },
      {
        "Effect": "Allow",
        "Action": [ "iot:Publish", "iot:Receive", "iot:Subscribe" ]
      }
    ]
  })

Notez que le ci-dessus utilise une forme variante de la syntaxe d'objet du langage Terraform qui utilise des deux points au lieu de signes égal; les deux sont valides, et l'utilisation de deux points ici aide l'entrée à ressembler à JSON et facilite donc l'adaptation du JSON que vous avez déjà écrit (comme je l'ai fait ici) sans beaucoup de réécriture.

Cependant, le " La séquence $ {SOMEVAR} / device-status-qa * " est comprise par Terraform comme une expression de modèle entre guillemets plutôt que comme une chaîne littérale, elle évaluera donc SOMEVAR et inclura le résultat dans la valeur Resource avant de sérialiser la chaîne résultante entière en utilisant la syntaxe JSON. Bien que cela semble peu probable dans ce cas particulier, si le résultat SOMEVAR était une chaîne contenant un ", alors le codage JSON l'échapperait automatiquement en tant que \" code > pour vous assurer que le résultat est une syntaxe valide.

Pour les structures de données plus volumineuses où il améliore la lisibilité, les factoriser dans un fichier séparé, la documentation de la templatefile function comprend quelques exemples de appelant jsonencode depuis l'intérieur d'un modèle externe également , avec des résultats similaires.


2 commentaires

Merci d'avoir pris le temps de tout expliquer. J'ai marqué ceci comme la réponse.


Il existe une source de données spécifique pour définir les stratégies AWS IAM via HCL, que je recommanderais sur jsonencode : terraform.io/docs/providers/aws/d/iam_policy_document.html