Выбор формата вывода в Azure CLI: JSON, TSV и лучшие практики автоматизации

Бесплатная консультация юриста

+7 (800) 301-07-30

Реклама jurik.ru

Эффективная автоматизация управления ресурсами в Microsoft Azure с помощью Azure CLI немыслима без понимания того, как обрабатывать результаты выполнения команд. Выбор правильного формата вывода (--output или -o) — это фундаментальное архитектурное решение, влияющее на надежность, скорость разработки и поддержку скриптов.

На актуальными остаются два основных подхода: структурированный JSON (и его вариации jsonc, yaml) и плоские текстовые форматы (TSV, table, text). В этой статье мы подробно разберем, когда и почему стоит выбирать тот или иной формат, опираясь на лучшие практики и специфику сред выполнения (Bash, PowerShell, GitHub Actions, ARM Deployment Scripts).


Обзор доступных форматов вывода

Azure CLI поддерживает несколько форматов, задаваемых глобально (az configure --defaults output=json) или локально для каждой команды (az vm list -o tsv).

  • json (по умолчанию): Стандартный JSON. Идеален для программной обработки;
  • jsonc: JSON с цветами (для интерактивного чтения в терминале).
  • yaml: YAML-сериализация (часто удобнее для чтения конфигов).
  • tsv (Tab-Separated Values): Плоский текст, разделенный табуляцией. Отлично подходит для awk, cut, циклов while read в Bash.
  • table: ASCII-таблица с заголовками. Только для человеческого чтения.
  • text: Псевдоним для tsv (в старых версиях) или простое текстовое представление.
  • none: Подавление вывода (для команд, где важен только код возврата или побочные эффекты).

JSON: Стандарт де-факто для автоматизации

Почему JSON выигрывает в сложных сценариях

JSON возвращает полную объектную модель ресурса Azure. Это означает, что у вас есть доступ ко всем свойствам: id, name, type, location, tags, properties (включая вложенные объекты, массивы SKU, сетевые интерфейсы, диски и т.д.).

Мощь запросов JMESPath (--query)

Главное преимущество JSON — язык запросов JMESPath. Он позволяет фильтровать, проецировать и трансформировать данные прямо внутри CLI, не вызывая внешние утилиты.

# Получить список ID запущенных ВМ в конкретной группе ресурсов
az vm list -g MyResourceGroup --query "[?powerState=='VM running'].id" -o tsv

az vm list-ip-addresses -g MyRG --query "[].{name: virtualMachine.name, ip: virtualMachine.network.publicIpAddresses[0].ipAddress}" -o json

Интеграция с Bash: jq — лучший друг DevOps

Хотя JMESPath мощен, для сложной логики (математика, рекурсия, сложные строковые манипуляции) стандарт де-факто — утилита jq.

# Пример: Найти ВМ с диском больше 100GB и вывести имя + размер
az vm show -g MyRG -n MyVM -o json | 
jq -r '.storageProfile.dataDisks[] | select(.diskSizeGb > 100) | "(.name) (.diskSizeGb)GB"'

Специфика ARM Deployment Scripts (Bash/CLI)

Согласно документации Microsoft Learn (Use deployment scripts in Azure Resource Manager templates), при использовании Azure CLI в Deployment Scripts внутри ARM-шаблонов или Bicep, существует важная особенность:

В отличие от PowerShell, CLI/bash не предоставляет общую переменную для выходных данных. Вместо этого используется переменная окружения AZ_SCRIPTS_OUTPUT_PATH. Ее предопределенное значение: /mnt/azscripts/azscriptoutput/scriptoutputs.json.

Практический вывод: Ваш Bash-скрипт внутри Deployment Script обязан записать результат в этот файл в формате JSON.

#!/bin/bash

RESULT=$(az storage account show -g $RG -n $STORAGE_ACCOUNT --query "{name: name, primaryEndpoints: primaryEndpoints.blob}" -o json)

echo $RESULT > $AZ_SCRIPTS_OUTPUT_PATH

Работа с JSON в PowerShell

Если вы вызываете Azure CLI из PowerShell (например, при миграции скриптов, как упоминалось на Stack Overflow Az Powershell function ─ how to get output in JSON format), JSON — единственный безопасный выбор.

# PowerShell 7+ (Core) / Windows PowerShell 5.1
$json = az resource list -g MyRG -o json | ConvertFrom-Json

$json | Where-Object { $_;type -eq 'Microsoft.Compute/virtualMachines' } | Select-Object name, location

Важно: Избегайте формата text или table в PowerShell — парсинг строк с пробелами в именах ресурсов приведет к ошибкам. Статья на Medium Use dynamic JSON strings with Azure CLI commands in PowerShell подчеркивает, что передача сложных объектов (JSON строк) в параметры CLI команд из PowerShell требует корректного экранирования, что возможно только при структурированных данных.


TEXT / TSV: Скорость и простота для простых задач

Когда TSV незаменим

  1. Циклы в Bash (while read loop): Самый быстрый способ итерироваться по списку ресурсов без накладных расходов на запуск jq или парсинг JSON в чистом Bash.
  2. Конвейеры Unix (pipes): Работа с awk, sed, cut, xargs.
  3. Генерация аргументов для других команд: Передача списка имен/ID в xargs -I {} az vm delete --ids {}.
  4. CI/CD Логирование: Компактный, читаемый лог в консоли GitHub Actions / Azure Pipelines.

Пример: Массовое удаление/операции через xargs

# Получить ID остановленных ВМ и удалить их (параллельно, по 4 процесса)
az vm list -g MyRG --query "[?powerState=='VM deallocated'].id" -o tsv | 
xargs -P 4 -I {} az vm delete --ids {} --yes --no-wait

Опасность формата table в скриптах

Формат table (и text в некоторых версиях) выводит заголовки и выравнивание пробелами.

Name ResourceGroup Location
------ --------------- --------
vm-prod rg-prod eastus

Парсить это в скрипте — плохая практика (заголовки, переменная ширина колонок, проблемы с пробелами в именах). Всегда используйте tsv для машинной обработки.


Сравнительная таблица: JSON vs TSV

Критерий JSON (с JMESPath / jq) TSV (Text)
Структура данных Иерархическая, вложенные объекты/массивы Плоская (строка = запись, колонка = поле)
Доступ к вложенным свойствам Нативно (properties.storageProfile.imageReference.offer) Требует предварительного --query для «выпрямления»
Парсинг в Bash Требует jq (рекомендуется) или сложный Bash-парсинг Нативный while IFS=$' ' read -r col1 col2; do ... done
Парсинг в PowerShell Идеален (ConvertFrom-Json) Сложен/хрупок (ConvertFrom-Csv -Delimiter "`t")
Безопасность имен (пробелы, спецсимволы) Высокая (строгие кавычки в JSON) Риск разбиения полей, если в значении есть таб/перенос строки (редко, но бывает)
Производительность (большие списки) Чуть выше накладные расходы на сериализацию Минимальные накладные расходы, быстрее стриминг
ARM Deployment Scripts Обязателен (запись в AZ_SCRIPTS_OUTPUT_PATH) Не подходит для возврата результата в ARM
GitHub Actions / Azure Pipelines Для set-output / task.setvariable (сложные объекты) Для простых списков, матриц стратегий (matrix)

Лучшие практики и паттерны (Best Practices)

Правило №1: Явно указывайте формат в скриптах

Никогда не полагайтесь на дефолт (json) или конфиг пользователя (az configure). Всегда пишите -o json или -o tsv в каждой команде скрипта. Это гарантирует детерминированное поведение на любом агенте (Hosted Agent, Self-hosted, Cloud Shell);

Правило №2: Используйте --query для проекции до вывода

Не скачивайте весь объект ВМ (мегабайты JSON), если вам нужен только id и name.

# Плохо: лишний трафик и память
az vm list -g MyRG -o json | jq '.[].id'

az vm list -g MyRG --query "[].id" -o tsv

Правило №3: Гибридный подход для сложных пайплайнов

Часто оптимально: получить список ID в TSV, а детали конкретного ресурса — в JSON.

# 1. Быстрый список ID (TSV)
ids=$(az vm list -g $RG --query "[?tags.env=='prod'].id" -o tsv)

for id in $ids; do
 sku=$(az vm show --ids $id -o json | jq -r '.hardwareProfile.vmSize')
 if [[ "$sku" == "Standard_D2s_v3" ]]; then
 echo "Resizing $id..."
 az vm resize --ids $id --size Standard_D4s_v5 --no-wait
 fi
done

Правило №4: Обработка ошибок и пустых выводов

  • JSON: Пустой массив [] — валидный JSON. Проверяйте длину: jq 'length == 0'.
  • TSV: Пустой вывод — пустая строка. В Bash цикл while read просто не выполнится ни разу (безопасно), но переменная будет пустой.
  • Всегда проверяйте $? (код возврата CLI) перед парсингом вывода.

Правило №5: Экранирование в PowerShell при передаче JSON

Если вы формируете JSON строку в PowerShell для передачи в параметр Azure CLI (например, --parameters или тело запроса), используйте ConvertTo-Json -Compress -Depth 5 и будьте осторожны с кавычками. Статья Philipp Bauknecht Use dynamic JSON strings with Azure CLI commands in PowerShell рекомендует использовать Here-Strings (@' ... '@) или временные файлы для сложных полезных нагрузок, чтобы избежать «ада кавычек».


Специфические сценарии автоматизации

GitHub Actions / Azure Pipelines: Matrix Strategy

Для динамической матрицы (strategy.matrix) нужен JSON.

- name: Get VM List for Matrix
 id: vm_matrix
 run: |
 # Формируем JSON объект для matrix: { "include": [ { "name": "vm1", "rg": "rg1" }, ... ] }
 MATRIX=$(az vm list -g $RG --query "map(&{name: name, rg: resourceGroup}, @)" -o json)
 echo "matrix=${MATRIX}" >> $GITHUB_OUTPUT

Azure Cloud Shell / Bash: Интерактивная работа vs Скрипты

  • Интерактивно: az configure --defaults output=table (или jsonc для цвета). Удобно для исследования.
  • В скриптах (.sh): Жестко задавайте -o tsv или -o json в каждой строке.

Работа с секретами и чувствительными данными

JSON часто содержит ключи доступа, connection strings, пароли (в properties).

  • Используйте --query для исключения секретных полей перед логированием/сохранением в артефакты.
  • В CI/CD маскируйте вывод: echo "::add-mask::$(az keyvault secret show ... -o tsv --query value)".

Чек-лист: Что выбрать для вашей задачи?

  1. Нужно вернуть сложный объект в ARM Template / Bicep / Deployment Script? → JSON (запись в AZ_SCRIPTS_OUTPUT_PATH).
  2. Пишете скрипт на PowerShell? → JSON (ConvertFrom-Json).
  3. Нужно просто перебрать список имен/ID в Bash цикле? → TSV (while IFS=$' ' read -r id name; do ... done).
  4. Нужно извлечь вложенное свойство (например, IP адрес конкретного NIC)? → JSON + jq или --query.
  5. Формируете матрицу для GitHub Actions / Azure Pipelines? → JSON.
  6. Передаете список ID в xargs / parallel для массовых операций? → TSV.
  7. Ловите ошибку «Property ‘x’ not found» в JMESPath? → Проверьте регистр свойств (JSON чувствителен к регистру) через az ... -o json | head -20.

Выбор между JSON и TEXT/TSV в Azure CLI — это не вопрос вкуса, а вопрос инструментария окружения и сложности данных.

  • JSON — это «тяжелая артиллерия»: стандарт для PowerShell, ARM Deployment Scripts, сложных трансформаций (jq/JMESPath), работы с вложенными структурами и CI/CD матрицами. Это формат, который гарантирует целостность данных.
  • TSV — это «легкая пехота»: идеален для Bash-циклов, Unix-конвейеров, xargs, быстрой выборки плоских списков идентификаторов. Минимальные накладные расходы, максимальная скорость парсинга в shell.

Профессиональный подход: Освойте оба. Используйте --query для формирования именно той «проекции» данных, которая удобна для следующего шага вашего конвейера: плоскую таблицу (TSV) для итераций или иерархию (JSON) для глубокого анализа. И помните про AZ_SCRIPTS_OUTPUT_PATH, это единственный контракт для возврата данных из CLI-скриптов в мир Infrastructure as Code (ARM/Bicep).