Estoy a punto de arrancarme el pelo por esto. Todas mis instancias tienen una etiqueta llamada "Datos" y el valor de "Datos" es uno de los siguientes: "foo = yes, bar = yes", "foo = yes, bar = no", "foo = no, bar = yes "," foo = no, bar = no ", quiero ejecutar un --query
que devuelve InstanceId para cualquier instancia que tenga un valor de etiqueta" Data "que contenga" foo = yes ". Así que algo como
aws --region us-east-1 ec2 describe-instances --query 'Reservations[].Instances[].[?contains(Tags[?Key==`Data`].Value, `foo=yes` == `true`)].InstanceId'
Pero eso no funciona.
¡Eso ciertamente es complicado! Lo logré con la siguiente expresión:
"Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId"
Esa es una larga, así que la voy a dividir, pieza por pieza. Para empezar, usemos estos datos de muestra:
{
"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"}
]
}
]}]
}
Primero, queremos obtener la lista de instancias, por lo que comenzamos con 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"
}
]
Ahora queremos las etiquetas que tienen una clave con el valor "Datos": .Tags[?Key == 'Data']
para la expresión completa Reservations[].Instances[].Tags[?Key == 'Data']
y el resultado:
[
[
{
"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"
}
]
]
Ahora también queremos que el valor de esa etiqueta contenga "foo = yes", por lo que agregamos la condición && contains(Value, 'foo=yes')
para la expresión completa Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')]
y el resultado:
[
[
{
"Value": "foo=yes,bar=no",
"Key": "Data"
}
],
[
{
"Value": "foo=yes,bar=yes",
"Key": "Data"
}
],
[],
[]
]
Muy bien, ahora aplanamos esa lista con []
para la expresión completa Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]
y el resultado:
[
{
"Value": "foo=yes,bar=no",
"Key": "Data"
},
{
"Value": "foo=yes,bar=yes",
"Key": "Data"
}
]
Muy bien, ahora tenemos las etiquetas que queremos, pero lo que queremos son los datos completos de la instancia. Así que volvamos a mover ese filtro de etiquetas como un filtro en las instancias. Entonces, la expresión completa ahora es Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]]
con el resultado:
[
[
{
"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"
}
]
]
Para explicar un poco más, ?
busca un valor verdadero. Para aquellas instancias que no tienen la etiqueta adecuada, ?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]
devolverá null
, un valor falso.
Ahora todo lo que queda por hacer es aplanar esa lista y seleccionar los ID de instancia con [].InstanceId
para la expresión completa "Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId"
y el resultado:
[
"id-target1",
"id-target2"
]
¡Y hemos terminado!
¡Wow increible! El paso Tags[?Key == 'Data' && contains(Value, 'foo=yes')]
es donde descarrilé. ¡Gracias!
* actualizar *
Para mis propósitos, el siguiente fue un enfoque mucho más fácil (esto es lo que obtengo al acceder a un hilo con fecha de más de 2 años):
--filter "Name=tag:aws:cloudformation:stack-name,Values=*$1*"
* Mensaje original *
Parece que esto ya no funciona. Funcionó todo el camino hasta el último paso donde [? Tags se sustituyó por .Tags ... cuando lo ejecuto para mi caso de uso, obtengo un conjunto vacío (después de obtener con éxito lo que esperaba de
Reservations[].Instances[].Tags[?Key == 'aws:cloudformation:stack-name' && contains(Value, 'target')][]
Comentario más útil
¡Eso ciertamente es complicado! Lo logré con la siguiente expresión:
Esa es una larga, así que la voy a dividir, pieza por pieza. Para empezar, usemos estos datos de muestra:
Primero, queremos obtener la lista de instancias, por lo que comenzamos con
Reservations[].Instances[]
:Ahora queremos las etiquetas que tienen una clave con el valor "Datos":
.Tags[?Key == 'Data']
para la expresión completaReservations[].Instances[].Tags[?Key == 'Data']
y el resultado:Ahora también queremos que el valor de esa etiqueta contenga "foo = yes", por lo que agregamos la condición
&& contains(Value, 'foo=yes')
para la expresión completaReservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')]
y el resultado:Muy bien, ahora aplanamos esa lista con
[]
para la expresión completaReservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]
y el resultado:Muy bien, ahora tenemos las etiquetas que queremos, pero lo que queremos son los datos completos de la instancia. Así que volvamos a mover ese filtro de etiquetas como un filtro en las instancias. Entonces, la expresión completa ahora es
Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]]
con el resultado:Para explicar un poco más,
?
busca un valor verdadero. Para aquellas instancias que no tienen la etiqueta adecuada,?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]
devolveránull
, un valor falso.Ahora todo lo que queda por hacer es aplanar esa lista y seleccionar los ID de instancia con
[].InstanceId
para la expresión completa"Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId"
y el resultado:¡Y hemos terminado!