Aws-cli: Ich möchte Instanzen filtern, indem ich eine Teilzeichenfolge eines Tag-Werts abgleiche

Erstellt am 29. Sept. 2016  ·  3Kommentare  ·  Quelle: aws/aws-cli

Ich bin dabei, mir die Haare auszureißen. Alle meine Instanzen haben ein Tag namens "Data" und den Wert von "Data" einer der folgenden: "foo=yes,bar=yes", "foo=yes,bar=no", "foo=no,bar =yes", "foo=no,bar=no", Ich möchte ein --query ausführen, das die InstanceId für jede Instanz zurückgibt, die einen Tag-"Data"-Wert hat, der "foo=yes" enthält. Also sowas wie

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

Aber das geht nicht.

guidance

Hilfreichster Kommentar

Das ist sicherlich eine schwierige Sache! Ich habe es mit folgendem Ausdruck geschafft:

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

Das ist lang, also werde ich es Stück für Stück auflösen. Für den Anfang verwenden wir diese Beispieldaten:

{
    "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"}
            ]
        }
    ]}]
}

Zuerst möchten wir die Instanzenliste abrufen, also beginnen wir mit 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"
  }
]

Nun wollen wir die Tags, die einen Key mit dem Wert "Data" haben: .Tags[?Key == 'Data'] für den vollständigen Ausdruck Reservations[].Instances[].Tags[?Key == 'Data'] und das Ergebnis:

[
  [
    {
      "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"
    }
  ]
]

Jetzt wollen wir auch, dass der Wert dieses Tags "foo=yes" enthält, also fügen wir die Bedingung && contains(Value, 'foo=yes') für den vollständigen Ausdruck Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')] und das Ergebnis hinzu:

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

Okay, jetzt können wir diese Liste mit [] für den vollständigen Ausdruck Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')][] und das Ergebnis reduzieren:

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

Okay, jetzt haben wir also die gewünschten Tags, aber die vollständigen Instanzdaten. Verschieben wir also diesen Tag-Filter als Filter für Instanzen zurück. Der vollständige Ausdruck lautet nun Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]] mit dem Ergebnis:

[
  [
    {
      "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"
    }
  ]
]

Um es etwas genauer zu erklären, ? prüft auf einen wahrheitsgetreuen Wert. Für die Instanzen, die nicht über das richtige Tag verfügen, wird ?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][] null , ein falscher Wert.

Jetzt müssen Sie nur noch diese Liste reduzieren und die Instanz-IDs mit [].InstanceId für den vollständigen Ausdruck "Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId" und das Ergebnis auswählen:

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

Und wir sind fertig!

Alle 3 Kommentare

Das ist sicherlich eine schwierige Sache! Ich habe es mit folgendem Ausdruck geschafft:

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

Das ist lang, also werde ich es Stück für Stück auflösen. Für den Anfang verwenden wir diese Beispieldaten:

{
    "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"}
            ]
        }
    ]}]
}

Zuerst möchten wir die Instanzenliste abrufen, also beginnen wir mit 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"
  }
]

Nun wollen wir die Tags, die einen Key mit dem Wert "Data" haben: .Tags[?Key == 'Data'] für den vollständigen Ausdruck Reservations[].Instances[].Tags[?Key == 'Data'] und das Ergebnis:

[
  [
    {
      "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"
    }
  ]
]

Jetzt wollen wir auch, dass der Wert dieses Tags "foo=yes" enthält, also fügen wir die Bedingung && contains(Value, 'foo=yes') für den vollständigen Ausdruck Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')] und das Ergebnis hinzu:

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

Okay, jetzt können wir diese Liste mit [] für den vollständigen Ausdruck Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')][] und das Ergebnis reduzieren:

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

Okay, jetzt haben wir also die gewünschten Tags, aber die vollständigen Instanzdaten. Verschieben wir also diesen Tag-Filter als Filter für Instanzen zurück. Der vollständige Ausdruck lautet nun Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]] mit dem Ergebnis:

[
  [
    {
      "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"
    }
  ]
]

Um es etwas genauer zu erklären, ? prüft auf einen wahrheitsgetreuen Wert. Für die Instanzen, die nicht über das richtige Tag verfügen, wird ?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][] null , ein falscher Wert.

Jetzt müssen Sie nur noch diese Liste reduzieren und die Instanz-IDs mit [].InstanceId für den vollständigen Ausdruck "Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId" und das Ergebnis auswählen:

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

Und wir sind fertig!

Wow cool! Der Schritt Tags[?Key == 'Data' && contains(Value, 'foo=yes')] ist der Punkt, an dem ich entgleist bin. Dankeschön!

* aktualisieren *

Für meine Zwecke war das Folgende ein viel einfacherer Ansatz (dies ist, was ich durch den Zugriff auf einen Thread vor mehr als 2 Jahren erhalte):

--filter "Name=tag:aws:cloudformation:stack-name,Values=*$1*"
* originale Nachricht *

Dies scheint nicht mehr zu funktionieren. Es hat bis zum letzten Schritt funktioniert, wo [?Tags durch .Tags ersetzt wurde
Reservations[].Instances[].Tags[?Key == 'aws:cloudformation:stack-name' && contains(Value, 'target')][]

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen