Aws-cli: Я хочу отфильтровать экземпляры, сопоставив подстроку значения тега

Созданный на 29 сент. 2016  ·  3Комментарии  ·  Источник: aws/aws-cli

Я собираюсь вырвать себе волосы из-за этого. Все мои экземпляры имеют тег с именем «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'

Но это не работает.

guidance

Самый полезный комментарий

Это, конечно, непросто! Мне удалось это с помощью следующего выражения:

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

И мы закончили!

Все 3 Комментарий

Это, конечно, непросто! Мне удалось это с помощью следующего выражения:

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

Была ли эта страница полезной?
0 / 5 - 0 рейтинги