Aws-cli: Eu quero filtrar instâncias combinando uma substring de um valor de tag

Criado em 29 set. 2016  ·  3Comentários  ·  Fonte: aws/aws-cli

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.

guidance

Comentários muito úteis

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!

Todos 3 comentários

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')][]

Esta página foi útil?
0 / 5 - 0 avaliações