Освоение фильтрации вывода AWS CLI с помощью JQ: Продвинутые методы

Используйте jq с JSON-выводом AWS CLI для фильтрации, преобразования и экспорта облачных данных для скриптов и отчетов.

Освоение фильтрации вывода AWS CLI с помощью JQ: продвинутые техники

Фильтрация вывода AWS CLI становится запутанной, когда команда возвращает глубоко вложенный JSON. Вам может понадобиться только один ID экземпляра, одно значение тега или короткий CSV-отчет, но такие команды, как aws ec2 describe-instances, возвращают гораздо больше данных.

У AWS CLI есть встроенная опция --query, использующая JMESPath, и она часто является правильным инструментом для простых запросов. jq полезен, когда вам нужно более богатое преобразование JSON, условная логика, вывод в CSV или фильтры, которые можно повторно использовать в shell-скриптах.

Начните с JSON-вывода

jq читает JSON, поэтому явно укажите AWS CLI возвращать JSON:

aws ec2 describe-instances --output json

Вы также можете установить JSON как формат по умолчанию с помощью aws configure, но использование --output json в примерах и скриптах делает зависимость очевидной.

Установите jq с помощью менеджера пакетов вашей системы, если он еще не доступен:

sudo apt update && sudo apt install jq
sudo dnf install jq
brew install jq

Чтение и проверка AWS JSON

Фильтр идентичности . возвращает входной JSON. Он удобен, когда вы хотите получить pretty-printed вывод, изучая структуру ответа:

aws ec2 describe-instances --output json | jq '.'

Чтобы выбрать ключ верхнего уровня, используйте точечную нотацию:

aws ec2 describe-instances --output json | jq '.Reservations'

Большинство команд AWS оборачивают полезные данные в массивы. Для EC2-экземпляров структура — Reservations[], за которой следует Instances[], поэтому обычно нужны оба уровня.

Итерация по массивам

Используйте .[], чтобы выдать каждый элемент из массива. Эта команда выводит все ID EC2-экземпляров во всех резервациях:

aws ec2 describe-instances --output json | jq '.Reservations[].Instances[].InstanceId'

По умолчанию строковый вывод включает кавычки JSON. Добавьте -r, когда вам нужен сырой текст для цикла в shell или другой команды:

aws ec2 describe-instances --output json | jq -r '.Reservations[].Instances[].InstanceId'

Вы также можете создать меньший объект только с нужными полями:

aws ec2 describe-instances --output json |
  jq '.Reservations[].Instances[] | {id: .InstanceId, state: .State.Name, type: .InstanceType}'

Это дает компактные JSON-записи вместо полного ответа EC2.

Фильтрация с помощью select()

Используйте select(), когда вам нужны только записи, соответствующие условию. Этот пример выводит ID запущенных экземпляров:

aws ec2 describe-instances --output json |
  jq -r '.Reservations[].Instances[] | select(.State.Name == "running") | .InstanceId'

Строковые литералы внутри фильтра jq используют двойные кавычки, например "running". Если вы обернете всю программу jq в одинарные кавычки, ваша оболочка безопасно передаст эти двойные кавычки.

Для более конкретной проверки отфильтруйте по типу экземпляра:

aws ec2 describe-instances --output json |
  jq -r '.Reservations[].Instances[] | select(.InstanceType == "t3.micro") | .InstanceId'

Безопасная обработка опциональных полей

Ресурсы AWS часто опускают поля. Теги — распространенный пример. Если у экземпляра нет массива Tags, .Tags[] может вызвать ошибку. Используйте опциональный итератор .Tags[]?:

aws ec2 describe-instances --output json |
  jq '.Reservations[].Instances[] | {id: .InstanceId, name: (.Tags[]? | select(.Key == "Name") | .Value)}'

Это работает, но может не дать значения name, когда тег отсутствует. Для скриптов обычно проще использовать значение по умолчанию:

aws ec2 describe-instances --output json |
  jq '.Reservations[].Instances[] | {
    id: .InstanceId,
    name: ((.Tags[]? | select(.Key == "Name") | .Value) // "unnamed")
  }'

Возврат массива вместо потока

Многие фильтры jq выдают поток значений. Если другой инструмент ожидает один валидный JSON-массив, оберните выражение в квадратные скобки:

aws ec2 describe-instances --output json |
  jq '[.Reservations[].Instances[].InstanceId]'

Это полезно, когда вы записываете JSON-файл для другого шага автоматизации.

Экспорт в CSV или TSV

Для отчетов, удобных для работы в электронных таблицах, создайте массив полей и передайте его в @csv или @tsv. Используйте -r, чтобы jq записывал сырые CSV-строки вместо JSON-строк:

aws ec2 describe-instances --output json |
  jq -r '.Reservations[].Instances[] | [.InstanceId, .InstanceType, .State.Name] | @csv'

Чтобы включить строку заголовка, выведите ее перед строками данных:

aws ec2 describe-instances --output json |
  jq -r '["instance_id","instance_type","state"], (.Reservations[].Instances[] | [.InstanceId, .InstanceType, .State.Name]) | @csv'

Практический пример: поиск непривязанных Elastic IP

Непривязанные Elastic IP-адреса могут создавать ненужные расходы. Эта команда выводит публичные IP, для которых AWS не вернул AssociationId:

aws ec2 describe-addresses --output json |
  jq -r '.Addresses[] | select(.AssociationId == null) | .PublicIp'

Если выводятся адреса, проверьте их перед освобождением:

aws ec2 release-address --allocation-id eipalloc-0123456789abcdef0

Не передавайте команды освобождения напрямую из запроса обнаружения, пока не проверите результаты. Короткий шаг проверки дешевле, чем восстановление после удаления не того ресурса.

Когда использовать --query вместо jq

Используйте --query AWS CLI для простых проекций, потому что он выполняется до форматирования вывода и делает команду самодостаточной:

aws ec2 describe-instances \
  --query 'Reservations[].Instances[].InstanceId' \
  --output text

Обращайтесь к jq, когда результат требует больше преобразований, таких как значения по умолчанию, форматирование CSV, объединение полей или более длинные фильтры, которые легче читать в синтаксисе jq.

Вывод

Используйте --output json как точку передачи между AWS CLI и jq. Затем комбинируйте .[], select(), конструирование объектов, значения по умолчанию // и сырой вывод -r, чтобы превратить большие ответы AWS в точные данные, которые нужны вашему скрипту или отчету.