Портал, Azure CLI и подписки

Учимся входить в Azure тремя разными способами, разбираемся, что такое подписка и кто по ней платит, ставим az CLI и выполняем первые команды.

Подписка (Subscription) — контейнер биллинга и границ: все ресурсы живут внутри подписки, по ней считаются квоты и по ней же вам выставляют счёт.

Пока вы не понимаете, в какой подписке работаете, вы не понимаете, кто платит за созданные вами ресурсы. Поэтому начнём с иерархии.

Иерархия Azure: от арендатора до ресурса

Tenant (Microsoft Entra ID)   ← кто вы: организация, каталог пользователей
 └── Management Group          ← необязательный слой: политики на группу подписок
      └── Subscription         ← кто платит: биллинг, квоты, лимиты
           └── Resource Group  ← папка жизненного цикла
                └── Resource   ← виртуалка, база, хранилище…

Tenant (арендатор) — это ваш каталог удостоверений в Microsoft Entra ID (так теперь называется бывший Azure AD). Там живут пользователи, группы и приложения. Подписок внутри одного арендатора может быть много: типичная схема — отдельная подписка на dev, отдельная на prod. Это самая надёжная граница: ошибиться и удалить прод, работая в dev-подписке, физически невозможно.

Management Group — слой для крупных компаний: на него вешают Azure Policy («запретить создавать ресурсы вне Европы», «требовать тег owner»), и правила наследуются всеми подписками внутри.

Три способа управлять Azure

СпособЧто этоКогда применятьСлабое место
Портал
portal.azure.com
Веб-интерфейс с кнопками и мастерамиПосмотреть, разобраться, отладить, глянуть метрики и счетаНевоспроизводимо: через месяц никто не вспомнит, какие галочки вы ставили
CLI
Azure CLI / PowerShell
Команды в терминалеСделать что-то один раз, написать скрипт, автоматизировать в CIИмперативно: скрипт описывает шаги, а не желаемое состояние
IaC
Bicep, ARM, Terraform
Инфраструктура как код: декларативный файл в gitПрод и всё, что должно воспроизводиться одинаково много разПорог входа выше, нужен CI и дисциплина

Рабочее правило звучит так: портал — чтобы посмотреть, CLI — чтобы сделать один раз, IaC — чтобы сделать сто раз одинаково. Так выглядит фрагмент шаблона Bicep — вы описываете что должно быть, а не какие кнопки нажать:

param location string = 'westeurope'

resource stg 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: 'stshopdevweu001'
  location: location
  sku: { name: 'Standard_LRS' }
  kind: 'StorageV2'
}

К IaC мы вернёмся в отдельном разделе курса. В этом уроке освоим CLI — он даёт и понимание модели, и мгновенный результат.

Устанавливаем Azure CLI

# macOS
brew update && brew install azure-cli

# Debian / Ubuntu
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

# Windows (PowerShell)
winget install -e --id Microsoft.AzureCLI

# проверяем
az version

Результат:

{
  "azure-cli": "2.62.0",
  "azure-cli-core": "2.62.0",
  "extensions": {}
}

Не хотите ничего ставить? В портале есть Azure Cloud Shell — терминал прямо в браузере, где az уже установлен и вы уже авторизованы. Отличный вариант для первых шагов (учтите: Cloud Shell просит подключить небольшое файловое хранилище, и оно тарифицируется копейками).

Вход: az login и выбор подписки

az login

Команда откроет браузер, вы войдёте своей учётной записью — и CLI сохранит токен локально. На сервере без графики браузера нет, там используют вход по коду устройства:

az login --use-device-code

Дальше — самый важный шаг, который пропускают почти все новички. Если у вас несколько подписок, az выберет ту, что помечена как подписка по умолчанию. Проверьте, где вы находитесь, прежде чем что-то создавать:

# какие подписки мне доступны
az account list --output table

# где я сейчас
az account show --output table

# переключиться на нужную
az account set --subscription "Visual Studio Enterprise"

Результат:

Name                        CloudName    SubscriptionId                        State    IsDefault
--------------------------  -----------  ------------------------------------  -------  -----------
CodeChick Dev               AzureCloud   00000000-1111-2222-3333-444444444444  Enabled  True
CodeChick Prod              AzureCloud   99999999-8888-7777-6666-555555555555  Enabled  False

Форматы вывода и --query

Любая команда az умеет отдавать результат в JSON (по умолчанию), в таблицу (-o table) или голым значением (-o tsv — удобно подставлять в переменные bash). Фильтровать JSON помогает --query на языке JMESPath:

# только имя текущей подписки, без кавычек и скобок
az account list --query "[?isDefault].name" -o tsv

# id подписки в переменную
SUB_ID=$(az account show --query id -o tsv)
echo "$SUB_ID"

# один раз задать регион по умолчанию, чтобы не писать -l в каждой команде
az configure --defaults location=westeurope

JSON-вывод az — обычный JSON, и его можно разбирать чем угодно. Вот как выглядит разбор списка подписок на чистом Python (никаких SDK, только стандартная библиотека) — этот пример можно запустить прямо здесь:

import json

# так выглядит вывод команды: az account list -o json
raw = '''[
  {"name": "Dev",  "id": "00000000-1111-2222-3333-444444444444", "isDefault": true},
  {"name": "Prod", "id": "99999999-8888-7777-6666-555555555555", "isDefault": false}
]'''

accounts = json.loads(raw)
for a in accounts:
    mark = "*" if a["isDefault"] else " "
    print(mark, a["name"].ljust(6), a["id"])

Результат:

* Dev    00000000-1111-2222-3333-444444444444
  Prod   99999999-8888-7777-6666-555555555555

Звёздочкой отмечена активная подписка — именно в ней окажутся все ресурсы, которые вы создадите следующей командой.

Подписка и биллинг

Подписка — это не только счёт, но и границы: в ней действуют квоты (например, лимит на число ядер определённой серии виртуальных машин в конкретном регионе). Упереться в квоту на бесплатном аккаунте — обычное дело; лечится запросом на увеличение лимита.

Типы подписок разные: Free (стартовый кредит на короткий срок плюс год бесплатных популярных сервисов и небольшой набор always free), Pay-As-You-Go (платите за фактическое потребление), студенческие и корпоративные соглашения. Важно понимать: кредит бесплатного аккаунта заканчивается, а ресурсы — нет. Как только кредит сгорит, всё, что вы забыли удалить, начнёт тарифицироваться по обычной цене.

Поэтому первое, что стоит сделать в новой подписке, — зайти в Cost Management + Billing в портале и завести бюджет с оповещением: например, 5 долларов в месяц с письмом на 80%. Это ваша страховка от «ой, я оставил на выходные виртуалку с GPU».

Как это работает

Azure CLI написан на Python и является тонкой обёрткой над REST API Azure Resource Manager. После az login в каталоге ~/.azure сохраняется профиль и OAuth-токен, полученный от Microsoft Entra ID; дальше каждая команда просто подставляет этот токен в заголовок Authorization HTTP-запроса.

Убедиться в этом легко — добавьте --debug к любой команде, и вы увидите реальные HTTP-вызовы, URL с версией API и коды ответов. Это, кстати, лучший способ отладки: если команда падает, ответ ARM с текстом ошибки виден именно там.

az group list --debug 2>&1 | grep "Request URL"

В CI-конвейере интерактивный вход невозможен: там заводят service principal — техническую учётную запись приложения — и логинятся ею. Секрет при этом берут из переменных окружения или из Key Vault, а не пишут в скрипт:

az login --service-principal \
  --username "$AZURE_CLIENT_ID" \
  --password "$AZURE_CLIENT_SECRET" \
  --tenant "$AZURE_TENANT_ID"

Частые ошибки

  • Создавать ресурсы, не проверив активную подписку. Самая дорогая ошибка урока: вы думали, что в dev, а создали нагруженный кластер в проде компании. Возьмите за правило начинать сессию с az account show -o table.
  • Путать учётную запись организации и личный Microsoft-аккаунт. Один и тот же адрес почты может существовать в двух мирах; если az login пускает вас «не туда», явно укажите арендатора: az login --tenant <tenant-id>.
  • Запускать az login на сервере без браузера и ждать чуда. Нужен --use-device-code.
  • Класть секрет service principal в скрипт и коммитить его в git. Утёкший секрет — это чужой майнинг за ваш счёт. Секреты живут в переменных окружения CI или в Key Vault.
  • Настроить всё кликами в портале и забыть. Через полгода никто не воспроизведёт конфигурацию, а IaC-шаблон при следующем применении молча снесёт ваши ручные правки (это называется дрифт). Что настроено кодом — правится кодом.
  • Не завести бюджет. Оповещение о превышении стоит ноль рублей и спасает нервы.

Итоги

  • Иерархия Azure: арендатор → (группа управления) → подписка → группа ресурсов → ресурс.
  • Подписка — граница биллинга и квот; dev и prod разводят по разным подпискам.
  • Портал — смотреть, CLI — делать один раз, IaC — воспроизводить.
  • az login, затем обязательно az account show и при необходимости az account set --subscription.
  • -o table для глаз, -o tsv с --query — для скриптов.
  • Azure CLI — обёртка над REST API ARM; --debug показывает реальные запросы. В CI вход выполняется через service principal.
  • Первым делом в новой подписке заведите бюджет с оповещением.
Проверьте себя
1. Вы вошли через az login, у вас две подписки: Dev и Prod. Какую команду стоит выполнить ПЕРЕД созданием ресурсов?
Aaz group list
Baz account show --output table
Caz version
Daz configure --defaults location=westeurope
2. Для чего в Azure CLI используется параметр --query?
AЧтобы выполнить SQL-запрос к базе данных Azure
BЧтобы отфильтровать JSON-ответ команды по выражению JMESPath
CЧтобы переключить активную подписку
DЧтобы посмотреть цену ресурса