Я собираюсь вырвать себе волосы из-за этого. Все мои экземпляры имеют тег с именем «Data» и одно из следующих значений «Data»: «foo = yes, bar = yes», «foo = yes, bar = no», «foo = no, bar. = yes "," foo = no, bar = no ", я хочу запустить --query
который возвращает InstanceId для любого экземпляра, имеющего значение тега" Data ", содержащее" foo = yes ". Так что-то вроде
aws --region us-east-1 ec2 describe-instances --query 'Reservations[].Instances[].[?contains(Tags[?Key==`Data`].Value, `foo=yes` == `true`)].InstanceId'
Но это не работает.
Это, конечно, непросто! Мне удалось это с помощью следующего выражения:
"Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId"
Это длинный, так что я собираюсь разбить его по частям. Для начала воспользуемся этими примерами данных:
{
"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"}
]
}
]}]
}
Сначала мы хотим получить список экземпляров, поэтому начнем с 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"
}
]
Теперь нам нужны теги, у которых есть Ключ со значением «Данные»: .Tags[?Key == 'Data']
для полного выражения Reservations[].Instances[].Tags[?Key == 'Data']
и результата:
[
[
{
"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"
}
]
]
Теперь мы также хотим, чтобы значение этого тега содержало «foo = yes», поэтому мы добавляем условие && contains(Value, 'foo=yes')
для полного выражения Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')]
и результата:
[
[
{
"Value": "foo=yes,bar=no",
"Key": "Data"
}
],
[
{
"Value": "foo=yes,bar=yes",
"Key": "Data"
}
],
[],
[]
]
Хорошо, теперь давайте сгладим этот список с помощью []
для полного выражения Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]
и результата:
[
{
"Value": "foo=yes,bar=no",
"Key": "Data"
},
{
"Value": "foo=yes,bar=yes",
"Key": "Data"
}
]
Хорошо, теперь у нас есть нужные нам теги, но нам нужны полные данные экземпляра. Итак, давайте переместим этот фильтр тегов обратно в качестве фильтра для экземпляров. Таким образом, теперь полное выражение выглядит как Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]]
с результатом:
[
[
{
"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[?Key == 'Data' && contains(Value, 'foo=yes')][]
вернет null
, ложное значение.
Теперь все, что осталось сделать, это сгладить этот список и выбрать идентификаторы экземпляров с помощью [].InstanceId
для полного выражения "Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId"
и результата:
[
"id-target1",
"id-target2"
]
И мы закончили!
Вау, круто! Шаг Tags[?Key == 'Data' && contains(Value, 'foo=yes')]
- вот где я сошел с рельсов. Спасибо!
* Обновить *
Для моих целей гораздо более простым подходом был следующий подход (это то, что я получаю от доступа к потоку, датированному 2+ годами назад):
--filter "Name=tag:aws:cloudformation:stack-name,Values=*$1*"
* Исходное сообщение *
Это больше не работает. Он работал до последнего шага, когда [? Tags был заменен на .Tags ... когда я запускаю его для своего варианта использования, я получаю пустой набор (после успешного получения того, что я ожидал от
Reservations[].Instances[].Tags[?Key == 'aws:cloudformation:stack-name' && contains(Value, 'target')][]
Самый полезный комментарий
Это, конечно, непросто! Мне удалось это с помощью следующего выражения:
Это длинный, так что я собираюсь разбить его по частям. Для начала воспользуемся этими примерами данных:
Сначала мы хотим получить список экземпляров, поэтому начнем с
Reservations[].Instances[]
:Теперь нам нужны теги, у которых есть Ключ со значением «Данные»:
.Tags[?Key == 'Data']
для полного выраженияReservations[].Instances[].Tags[?Key == 'Data']
и результата:Теперь мы также хотим, чтобы значение этого тега содержало «foo = yes», поэтому мы добавляем условие
&& contains(Value, 'foo=yes')
для полного выраженияReservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')]
и результата:Хорошо, теперь давайте сгладим этот список с помощью
[]
для полного выраженияReservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]
и результата:Хорошо, теперь у нас есть нужные нам теги, но нам нужны полные данные экземпляра. Итак, давайте переместим этот фильтр тегов обратно в качестве фильтра для экземпляров. Таким образом, теперь полное выражение выглядит как
Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]]
с результатом:Чтобы объяснить немного больше,
?
проверяет истинное значение. Для тех экземпляров, у которых нет подходящего тега,?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]
вернетnull
, ложное значение.Теперь все, что осталось сделать, это сгладить этот список и выбрать идентификаторы экземпляров с помощью
[].InstanceId
для полного выражения"Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId"
и результата:И мы закончили!