Estou prestes a arrancar meu cabelo por causa disso. Todas as minhas instâncias têm uma tag chamada "Data" e o valor "Data" é um dos seguintes: "foo = yes, bar = yes", "foo = yes, bar = no", "foo = no, bar = yes "," foo = no, bar = no ", quero executar um --query
que retorna o InstanceId para qualquer instância que tenha um valor de tag" Data "que contenha" foo = yes ". Então algo como
aws --region us-east-1 ec2 describe-instances --query 'Reservations[].Instances[].[?contains(Tags[?Key==`Data`].Value, `foo=yes` == `true`)].InstanceId'
Mas isso não funciona.
Isso certamente é complicado! Consegui com a seguinte expressão:
"Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId"
Essa é longa, então vou dividi-la, peça por peça. Para começar, vamos usar estes dados de amostra:
{
"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"}
]
}
]}]
}
Primeiro, queremos obter a lista de instâncias, então começamos com 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"
}
]
Agora queremos as tags que possuem uma chave com o valor "Dados": .Tags[?Key == 'Data']
para a expressão completa Reservations[].Instances[].Tags[?Key == 'Data']
e o 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"
}
]
]
Agora também queremos que o valor dessa tag contenha "foo = yes", então adicionamos a condição && contains(Value, 'foo=yes')
para a expressão completa Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')]
e o resultado:
[
[
{
"Value": "foo=yes,bar=no",
"Key": "Data"
}
],
[
{
"Value": "foo=yes,bar=yes",
"Key": "Data"
}
],
[],
[]
]
Tudo bem, agora vamos nivelar essa lista com []
para a expressão completa Reservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]
e o resultado:
[
{
"Value": "foo=yes,bar=no",
"Key": "Data"
},
{
"Value": "foo=yes,bar=yes",
"Key": "Data"
}
]
Tudo bem, agora temos as tags que queremos, mas queremos os dados completos da instância. Então, vamos mover esse filtro de tag de volta como um filtro nas instâncias. Portanto, a expressão completa agora é Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]]
com o 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 um pouco mais, ?
está verificando um valor verdadeiro. Para aquelas instâncias que não possuem a tag apropriada, ?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]
retornará null
, um valor falso.
Agora tudo o que resta a fazer é nivelar essa lista e selecionar os ids de instância com [].InstanceId
para a expressão completa "Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId"
e o resultado:
[
"id-target1",
"id-target2"
]
E terminamos!
Wow fantástico! A etapa Tags[?Key == 'Data' && contains(Value, 'foo=yes')]
foi onde eu descarrilei. Obrigado!
* atualizar *
Para meus propósitos, a abordagem a seguir foi muito mais fácil (isso é o que eu obtenho ao acessar um tópico datado de mais de 2 anos atrás):
--filter "Name=tag:aws:cloudformation:stack-name,Values=*$1*"
* mensagem original *
Isso parece não estar mais funcionando. Funcionou até a última etapa em que [? Tags foi substituído por .Tags. Quando eu o executo para meu caso de uso, obtenho um conjunto vazio (após obter com sucesso o que espero de
Reservations[].Instances[].Tags[?Key == 'aws:cloudformation:stack-name' && contains(Value, 'target')][]
Comentários muito úteis
Isso certamente é complicado! Consegui com a seguinte expressão:
Essa é longa, então vou dividi-la, peça por peça. Para começar, vamos usar estes dados de amostra:
Primeiro, queremos obter a lista de instâncias, então começamos com
Reservations[].Instances[]
:Agora queremos as tags que possuem uma chave com o valor "Dados":
.Tags[?Key == 'Data']
para a expressão completaReservations[].Instances[].Tags[?Key == 'Data']
e o resultado:Agora também queremos que o valor dessa tag contenha "foo = yes", então adicionamos a condição
&& contains(Value, 'foo=yes')
para a expressão completaReservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')]
e o resultado:Tudo bem, agora vamos nivelar essa lista com
[]
para a expressão completaReservations[].Instances[].Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]
e o resultado:Tudo bem, agora temos as tags que queremos, mas queremos os dados completos da instância. Então, vamos mover esse filtro de tag de volta como um filtro nas instâncias. Portanto, a expressão completa agora é
Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]]
com o resultado:Para explicar um pouco mais,
?
está verificando um valor verdadeiro. Para aquelas instâncias que não possuem a tag apropriada,?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]
retornaránull
, um valor falso.Agora tudo o que resta a fazer é nivelar essa lista e selecionar os ids de instância com
[].InstanceId
para a expressão completa"Reservations[].Instances[?Tags[?Key == 'Data' && contains(Value, 'foo=yes')][]][].InstanceId"
e o resultado:E terminamos!