Aws-cli: Je veux filtrer les instances en faisant correspondre une sous-chaîne d'une valeur de balise

Créé le 29 sept. 2016  ·  3Commentaires  ·  Source: aws/aws-cli

Je suis sur le point de m'arracher les cheveux pour ça. Toutes mes instances ont une balise nommée "Data", et la valeur de "Data" l'une des suivantes : "foo=yes,bar=yes", "foo=yes,bar=no", "foo=no,bar =yes", "foo=no,bar=no", je veux exécuter un --query qui renvoie l'InstanceId pour toute instance qui a une valeur de balise "Data" qui contient "foo=yes". Donc quelque chose comme

aws --region us-east-1 ec2 describe-instances --query 'Reservations[].Instances[].[?contains(Tags[?Key==`Data`].Value, `foo=yes` == `true`)].InstanceId'

Mais cela ne fonctionne pas.

guidance

Commentaire le plus utile

C'est certainement délicat ! J'ai réussi avec l'expression suivante :

"Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId"

C'est long, alors je vais le décomposer, morceau par morceau. Pour commencer, utilisons ces exemples de données :

{
    "Reservations": [{"Instances": [
        {
            "InstanceId": "id-target1",
            "Tags": [
                {"Key": "Data", "Value": "foo=yes,bar=no"},
                {"Key": "Name", "Value": "target"}
            ]
        },
        {
            "InstanceId": "id-target2",
            "Tags": [
                {"Key": "Data", "Value": "foo=yes,bar=yes"},
                {"Key": "Name", "Value": "target"}
            ]
        },
        {
            "InstanceId": "id-invalid1",
            "Tags": [
                {"Key": "Data", "Value": "foo=no,bar=no"},
                {"Key": "Name", "Value": "invalid"}
            ]
        },
        {
            "InstanceId": "id-invalid2",
            "Tags": [
                {"Key": "Data", "Value": "foo=no,bar=yes"},
                {"Key": "Name", "Value": "invalid"}
            ]
        }
    ]}]
}

Tout d'abord, nous voulons obtenir la liste des instances, nous commençons donc par Reservations[].Instances[] :

[
  {
    "Tags": [
      {
        "Value": "foo=yes,bar=no",
        "Key": "Data"
      },
      {
        "Value": "target",
        "Key": "Name"
      }
    ],
    "InstanceId": "id-target1"
  },
  {
    "Tags": [
      {
        "Value": "foo=yes,bar=yes",
        "Key": "Data"
      },
      {
        "Value": "target",
        "Key": "Name"
      }
    ],
    "InstanceId": "id-target2"
  },
  {
    "Tags": [
      {
        "Value": "foo=no,bar=no",
        "Key": "Data"
      },
      {
        "Value": "invalid",
        "Key": "Name"
      }
    ],
    "InstanceId": "id-invalid1"
  },
  {
    "Tags": [
      {
        "Value": "foo=no,bar=yes",
        "Key": "Data"
      },
      {
        "Value": "invalid",
        "Key": "Name"
      }
    ],
    "InstanceId": "id-invalid2"
  }
]

Maintenant, nous voulons les balises qui ont une clé avec la valeur "Data" : .Tags[?Key == 'Data'] pour l'expression complète Reservations[].Instances[].Tags[?Key == 'Data'] et le résultat :

[
  [
    {
      "Value": "foo=yes,bar=no",
      "Key": "Data"
    }
  ],
  [
    {
      "Value": "foo=yes,bar=yes",
      "Key": "Data"
    }
  ],
  [
    {
      "Value": "foo=no,bar=no",
      "Key": "Data"
    }
  ],
  [
    {
      "Value": "foo=no,bar=yes",
      "Key": "Data"
    }
  ]
]

Maintenant, nous voulons également que la valeur de cette balise contienne "foo=yes", nous ajoutons donc la condition && contains(Value, 'foo=yes') pour l'expression complète Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')] et le résultat :

[
  [
    {
      "Value": "foo=yes,bar=no",
      "Key": "Data"
    }
  ],
  [
    {
      "Value": "foo=yes,bar=yes",
      "Key": "Data"
    }
  ],
  [],
  []
]

Très bien, aplatissons maintenant cette liste avec [] pour l'expression complète Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')][] et le résultat :

[
  {
    "Value": "foo=yes,bar=no",
    "Key": "Data"
  },
  {
    "Value": "foo=yes,bar=yes",
    "Key": "Data"
  }
]

Bon, maintenant nous avons les balises que nous voulons, mais ce que nous voulons, les données d'instance complètes. Déplaçons donc ce filtre de balises en tant que filtre sur les instances. L'expression complète est donc maintenant Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]] avec le résultat :

[
  [
    {
      "Tags": [
        {
          "Value": "foo=yes,bar=no",
          "Key": "Data"
        },
        {
          "Value": "target",
          "Key": "Name"
        }
      ],
      "InstanceId": "id-target1"
    },
    {
      "Tags": [
        {
          "Value": "foo=yes,bar=yes",
          "Key": "Data"
        },
        {
          "Value": "target",
          "Key": "Name"
        }
      ],
      "InstanceId": "id-target2"
    }
  ]
]

Pour expliquer un peu plus, ? vérifie une valeur véridique. Pour les instances qui n'ont pas la balise appropriée, ?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][] renverra null , une valeur fausse.

Il ne reste plus qu'à aplatir cette liste et à sélectionner les identifiants d'instance avec [].InstanceId pour l'expression complète "Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId" et le résultat :

[
  "id-target1",
  "id-target2"
]

Et nous avons terminé !

Tous les 3 commentaires

C'est certainement délicat ! J'ai réussi avec l'expression suivante :

"Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId"

C'est long, alors je vais le décomposer, morceau par morceau. Pour commencer, utilisons ces exemples de données :

{
    "Reservations": [{"Instances": [
        {
            "InstanceId": "id-target1",
            "Tags": [
                {"Key": "Data", "Value": "foo=yes,bar=no"},
                {"Key": "Name", "Value": "target"}
            ]
        },
        {
            "InstanceId": "id-target2",
            "Tags": [
                {"Key": "Data", "Value": "foo=yes,bar=yes"},
                {"Key": "Name", "Value": "target"}
            ]
        },
        {
            "InstanceId": "id-invalid1",
            "Tags": [
                {"Key": "Data", "Value": "foo=no,bar=no"},
                {"Key": "Name", "Value": "invalid"}
            ]
        },
        {
            "InstanceId": "id-invalid2",
            "Tags": [
                {"Key": "Data", "Value": "foo=no,bar=yes"},
                {"Key": "Name", "Value": "invalid"}
            ]
        }
    ]}]
}

Tout d'abord, nous voulons obtenir la liste des instances, nous commençons donc par Reservations[].Instances[] :

[
  {
    "Tags": [
      {
        "Value": "foo=yes,bar=no",
        "Key": "Data"
      },
      {
        "Value": "target",
        "Key": "Name"
      }
    ],
    "InstanceId": "id-target1"
  },
  {
    "Tags": [
      {
        "Value": "foo=yes,bar=yes",
        "Key": "Data"
      },
      {
        "Value": "target",
        "Key": "Name"
      }
    ],
    "InstanceId": "id-target2"
  },
  {
    "Tags": [
      {
        "Value": "foo=no,bar=no",
        "Key": "Data"
      },
      {
        "Value": "invalid",
        "Key": "Name"
      }
    ],
    "InstanceId": "id-invalid1"
  },
  {
    "Tags": [
      {
        "Value": "foo=no,bar=yes",
        "Key": "Data"
      },
      {
        "Value": "invalid",
        "Key": "Name"
      }
    ],
    "InstanceId": "id-invalid2"
  }
]

Maintenant, nous voulons les balises qui ont une clé avec la valeur "Data" : .Tags[?Key == 'Data'] pour l'expression complète Reservations[].Instances[].Tags[?Key == 'Data'] et le résultat :

[
  [
    {
      "Value": "foo=yes,bar=no",
      "Key": "Data"
    }
  ],
  [
    {
      "Value": "foo=yes,bar=yes",
      "Key": "Data"
    }
  ],
  [
    {
      "Value": "foo=no,bar=no",
      "Key": "Data"
    }
  ],
  [
    {
      "Value": "foo=no,bar=yes",
      "Key": "Data"
    }
  ]
]

Maintenant, nous voulons également que la valeur de cette balise contienne "foo=yes", nous ajoutons donc la condition && contains(Value, 'foo=yes') pour l'expression complète Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')] et le résultat :

[
  [
    {
      "Value": "foo=yes,bar=no",
      "Key": "Data"
    }
  ],
  [
    {
      "Value": "foo=yes,bar=yes",
      "Key": "Data"
    }
  ],
  [],
  []
]

Très bien, aplatissons maintenant cette liste avec [] pour l'expression complète Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')][] et le résultat :

[
  {
    "Value": "foo=yes,bar=no",
    "Key": "Data"
  },
  {
    "Value": "foo=yes,bar=yes",
    "Key": "Data"
  }
]

Bon, maintenant nous avons les balises que nous voulons, mais ce que nous voulons, les données d'instance complètes. Déplaçons donc ce filtre de balises en tant que filtre sur les instances. L'expression complète est donc maintenant Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]] avec le résultat :

[
  [
    {
      "Tags": [
        {
          "Value": "foo=yes,bar=no",
          "Key": "Data"
        },
        {
          "Value": "target",
          "Key": "Name"
        }
      ],
      "InstanceId": "id-target1"
    },
    {
      "Tags": [
        {
          "Value": "foo=yes,bar=yes",
          "Key": "Data"
        },
        {
          "Value": "target",
          "Key": "Name"
        }
      ],
      "InstanceId": "id-target2"
    }
  ]
]

Pour expliquer un peu plus, ? vérifie une valeur véridique. Pour les instances qui n'ont pas la balise appropriée, ?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][] renverra null , une valeur fausse.

Il ne reste plus qu'à aplatir cette liste et à sélectionner les identifiants d'instance avec [].InstanceId pour l'expression complète "Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId" et le résultat :

[
  "id-target1",
  "id-target2"
]

Et nous avons terminé !

Wow génial! L'étape Tags[?Key == 'Data' && contains(Value, 'foo=yes')] est l'endroit où j'ai déraillé. Merci!

* mettre à jour *

Pour mes besoins, ce qui suit était une approche beaucoup plus simple (c'est ce que j'obtiens en accédant à un fil datant d'il y a plus de 2 ans):

--filter "Name=tag:aws:cloudformation:stack-name,Values=*$1*"
*message d'origine*

Cela ne semble plus fonctionner. Cela a fonctionné jusqu'à la dernière étape où [?Tags a été remplacé par .Tags .. lorsque je l'exécute pour mon cas d'utilisation, j'obtiens un ensemble vide (après avoir réussi à obtenir ce que j'attends de
Reservations[].Instances[].Tags[?Key == 'aws:cloudformation:stack-name' && contains(Value, 'target')][]

Cette page vous a été utile?
0 / 5 - 0 notes