Microsoft Azure — это большой набор облачных сервисов: серверы, базы данных, хранилища, сеть и ещё пара сотен вещей. На первый взгляд это стена из названий, и легко растеряться. Но почти всё стоит на четырёх опорах. Разберитесь с ними — и остальное встроится в понятную картину.

Эти четыре опоры: иерархия ресурсов (где всё лежит и кто за это платит), Entra ID и RBAC (кто и что имеет право делать), регионы и зоны доступности (где физически живут ресурсы и как пережить сбой) и виртуальная сеть (как устроена ваша приватная сеть). Дальше — по порядку. Если вы знакомы с AWS, по ходу будут пометки, что чему соответствует.

клиент Entra ID пользователи и вход группы управления и политики подписка граница изоляции и счёта права и блокировки наследуются вниз группа ресурсов единица управления и прав теги для счёта ресурсы машины, базы, сети

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

Обязательно

Через что проходят все операции: Resource Manager

Прежде чем говорить про подписки и группы, надо назвать слой, через который идёт всё: создание ресурса из портала, команда в терминале, шаблон, вызов из программы. Этот слой называется Azure Resource Manager.

Практически это единый интерфейс управления: у него один адрес, одна модель прав, один журнал операций. Отсюда три следствия, которые пригодятся дальше.

Что бы вы ни делали, операция выглядит одинаково. Портал, командная строка, шаблон — все они в итоге отправляют один и тот же запрос. Поэтому любое действие, сделанное мышью, можно повторить командой, а права проверяются одни и те же.

«Шаблон ARM» — это описание для этого слоя. Файл в формате JSON, который говорит: хочу такие ресурсы с такими свойствами. Он не «ещё один инструмент», а родной язык самого Azure; всё остальное (Bicep, Terraform) в конечном счёте обращается к нему же. Разбор — в статье про инфраструктуру как код.

Каждая операция попадает в журнал. Журнал действий (Activity Log) хранит, кто, что и когда изменил на уровне управления ресурсами, — и это то место, куда идут с вопросом «кто удалил группу ресурсов».

И одно практическое правило, которое из этого вытекает: операции над данными — чтение файла в хранилище, запрос в базу — через этот слой не проходят. У них свои адреса, свои права и свой журнал. Это различие в Azure важнее, чем кажется, и его разбирает статья про доступ.

Иерархия: подписка и группа ресурсов

Тестовый стенд и продакшен в одной куче — и удаление «лишней» базы однажды сносит боевую. Чтобы среды не смешивались, а счета и права раздавались по границам, в Azure ресурсы разложены по нескольким уровням.

  • Клиент (tenant) — верхний уровень, ваш каталог удостоверений в Microsoft Entra ID (бывший Azure AD). Здесь живут пользователи и настройки входа.
  • Подписка (subscription) — граница изоляции и та единица, в разрезе которой считают расходы: у подписки свои лимиты, и в счёте видно, сколько потратила каждая. Сам счёт выставляют не на подписку, а на биллинг-аккаунт, к которому подписки присоединены, — пока подписка одна, разницы не видно, а как только их становится несколько, она становится важной. Обычно заводят отдельные подписки под production и под dev/test.
  • Группа ресурсов (resource group) — контейнер, внутри которого создаются сами ресурсы: виртуальные машины, базы, сети. Это граница управления: всю группу можно удалить целиком, права удобно выдавать на неё.

Крупные организации добавляют сверху группы управления (management groups), чтобы применять политики сразу к нескольким подпискам. Практика та же, что в других облаках: под разные среды — разные подписки или хотя бы разные группы ресурсов, чтобы ошибка в одной не задела боевую систему, а в счёте было видно, кто сколько потратил. (В терминах AWS подписка примерно соответствует аккаунту, а группа ресурсов — удобной границе внутри него.)

Главный практический вывод: «у нас есть Azure» всегда тянет вопрос «в какой подписке и группе ресурсов?».

Блокировки: чтобы группу нельзя было удалить

Раз группу ресурсов можно удалить целиком одним движением, у Azure есть штатная защита от этого движения — блокировки (locks). Ставятся они на ресурс, группу или подписку и бывают двух видов:

  • CanNotDelete — менять можно, удалить нельзя;
  • ReadOnly — нельзя ни менять, ни удалять (строже, чем кажется: сюда попадают и операции, которые технически являются изменением, например масштабирование).
az lock create --name prod-no-delete --lock-type CanNotDelete \
  --resource-group rg-orders-prod

Три вещи про блокировки, которые стоит знать заранее.

Они наследуются вниз. Блокировка на группе действует на все ресурсы внутри — это и есть основной способ применения: одна блокировка на боевую группу вместо блокировки на каждый ресурс.

Они не зависят от прав. Владелец подписки тоже не удалит заблокированный ресурс, пока не снимет блокировку. Это её смысл: защита не от злого умысла, а от случайного движения и от ошибки в автоматизации.

Они мешают инфраструктуре как коду. Инструмент, который пытается удалить или изменить заблокированный ресурс, получит отказ. Это правильное поведение, но о нём надо знать: в конвейере появляется шаг снятия и возврата блокировки для тех редких изменений, которым она действительно мешает.

Практический минимум: CanNotDelete на боевые группы ресурсов и отдельно на всё, чья потеря необратима — базы, хранилища с данными, хранилища секретов.

Entra ID и RBAC: кто и что может делать

В Azure доступ делится на две связанные системы.

Microsoft Entra ID отвечает на вопрос «кто ты» — это каталог удостоверений: пользователи, группы, приложения. Через него входят люди (в том числе по корпоративному SSO) и регистрируются приложения.

Azure RBAC (role-based access control) отвечает на вопрос «что тебе можно» с ресурсами. Здесь два ключевых понятия:

  • Роль — набор разрешений. Есть широкие встроенные роли — Owner (всё, включая раздачу прав), Contributor (создавать и менять, но не раздавать права), Reader (только смотреть) — и множество узких сервисных ролей вроде «Storage Blob Data Contributor».
  • Назначение роли (role assignment) — «кому — какую роль — на каком уровне». Роль выдают на группу управления, подписку, группу ресурсов или отдельный ресурс, и права наследуются вниз.

Одна ловушка тут стоит отдельного абзаца, потому что на ней спотыкаются почти все. Широкие роли вроде Contributor управляют самим ресурсом, а не тем, что внутри него лежит. Дали человеку Contributor на учётную запись хранилища — он может её переименовать, поменять настройки, удалить целиком, но при попытке прочитать файл получит отказ. Чтобы работать с содержимым, нужна роль из отдельного семейства — Storage Blob Data Reader или Storage Blob Data Contributor. Управление ресурсом и доступ к данным в Azure разведены намеренно, и «я же Contributor, почему отказ» — самый частый первый вопрос новичка.

Два правила, которые экономят нервы и деньги.

Первое: ваш код не должен носить с собой ключи. Когда приложение работает в Azure, ему дают управляемое удостоверение (managed identity) — платформа сама выдаёт временные токены, а библиотека Azure (SDK) находит их автоматически. Это тот же принцип, что instance profile в AWS. Ключи в конфиге или в git — классический путь к утечке. Подробнее — в статье про Entra ID и RBAC.

Второе: минимум прав (least privilege). Давайте роли ровно то, что нужно: сервису — доступ к своему хранилищу и своей базе, а не Contributor на всю группу ресурсов. Узкие права — лишние десять минут; широкие — потенциальный инцидент.

Регионы и зоны доступности

Регион — географическая площадка Azure: например, West Europe, North Europe. Ресурсы привязаны к региону, и данные сами между регионами не путешествуют — копию в другом регионе настраивают отдельно.

Зона доступности (availability zone) — изолированный дата-центр внутри региона: своё питание, охлаждение и сеть, чтобы авария в одной зоне не задела соседнюю. Зоны одного региона связаны быстрыми каналами.

Зачем это знать новичку:

  • Отказоустойчивость строят на нескольких зонах одного региона. Копии приложения и реплики базы разносят по зонам, сверху — балансировщик; упадёт зона — сервис продолжит работать.
  • Крупная авария региона — большая редкость; защита от неё строится на втором регионе и настраивается отдельно. Исторически для этого брали парный регион (region pair) — заранее назначенную Microsoft пару, но пара есть не у всех регионов, а у новых её обычно и нет: ставку там делают на зоны доступности. Так что «у моего региона есть пара» — предположение, которое надо проверить. Это тема отказоустойчивости и восстановления.
  • Трафик между регионами стоит денег — это видно в счёте. А вот за трафик между зонами одного региона Azure с 2024 года платы не берёт, так что раскладывать сервис по зонам ради надёжности не значит переплачивать за передачу данных.

Как строить высокую доступность — в статье про масштабирование и доступность.

Виртуальная сеть

Virtual Network (VNet) — ваша изолированная сеть внутри Azure, что-то вроде огороженного двора для серверов и баз. Минимальный набор понятий:

  • Подсети (subnets) разрезают адресное пространство VNet. Ресурсы получают внутренний IP; чтобы стать доступным из интернета, ресурсу нужен публичный IP (или он прячется за балансировщиком).
  • Network Security Group (NSG) — файрвол (сетевой фильтр) с разрешающими и запрещающими правилами; вешается на подсеть или сетевой интерфейс. Хороший приём — писать правила не через IP-адреса, а через теги и ссылки.
  • Для исходящего доступа из внутренних ресурсов используют NAT Gateway, а до сервисов Azure по приватной сети дотягиваются через Private Link / приватные эндпоинты, не выходя в интернет.

Правило простое: серверы и базы держат без публичного IP, а снаружи доступны только балансировщики и точки входа. Публичный IP базе «чтобы удобно подключаться» — прямая дыра. Глубже — в статье про сеть.

Теги и разнесение затрат

«В счёте видно, кто сколько потратил» — обещание, которое выполняется только при одном условии: на ресурсах есть теги. Иначе в отчёте видно, что подписка потратила столько-то на виртуальные машины, и всё.

Тег — это пара «ключ — значение» на ресурсе или группе ресурсов. Минимальный набор, с которым живут почти все:

az group create --name rg-orders-prod --location westeurope \
  --tags env=prod service=orders owner=platform-team cost-center=CC-1042
  • env — среда (prod, staging, dev): позволяет посмотреть, сколько стоит каждая, и обычно приносит первое открытие («стенды стоят как половина прода»).
  • service — какому сервису принадлежит ресурс.
  • owner — команда, к которой идти с вопросами.
  • cost-center или проект — то, по чему разносят затраты в финансах.

Три особенности, о которые спотыкаются.

Теги не наследуются автоматически. Тег на группе ресурсов не появляется у ресурсов внутри неё, и в счёте видно теги самого ресурса. Лечится это политикой, которая доназначает теги от группы (об этом ниже), или дисциплиной в коде инфраструктуры — там тег задаётся один раз для всего набора.

Часть затрат нельзя отнести к ресурсу. Трафик, поддержка, некоторые общие сервисы попадают в счёт без тегов. Поэтому разнесение получается не стопроцентным, и это нормально: цель — увидеть основные статьи, а не свести до копейки.

Теги — не место для секретов. Они видны всем, у кого есть доступ на чтение ресурса, и попадают в журналы и отчёты.

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

Где это применяется

Эти четыре опоры всплывают в любой работе с Azure. Создаёте ресурс — выбираете подписку, группу ресурсов, регион и зону. Запускаете приложение — даёте ему managed identity вместо ключей. Поднимаете базу — кладёте в подсеть без публичного IP и закрываете NSG. Любой следующий сервис (вычисления, функции, управляемые базы) стоит на этом фундаменте.

Где спотыкаются начинающие:

  • Хранят ключи в коде или git вместо managed identity — самая частая и дорогая ошибка.
  • Раздают Contributor/Owner широко «чтобы заработало» и забывают сузить.
  • Дают базе публичный IP ради удобства — и получают сканирование извне.
  • Путают регион и зону или не понимают, почему ресурс «не виден» — часто он в другой подписке или регионе.
Дополнительно: при первом чтении можно пропустить

Глубже: поставщики ресурсов: первая непонятная ошибкарасширенное

В свежей подписке создание ресурса иногда заканчивается сообщением вида MissingSubscriptionRegistration: The subscription is not registered to use namespace 'Microsoft.ContainerService'. Это не ошибка прав и не опечатка.

Дело в том, что каждое семейство сервисов в Azure — это поставщик ресурсов (Microsoft.Compute, Microsoft.Storage, Microsoft.ContainerService и десятки других), и он должен быть зарегистрирован в подписке. Регистрация — разовая операция, которая ничего не стоит и просто разрешает подписке пользоваться этим семейством. Часть поставщиков регистрируется автоматически при первом создании ресурса из портала, а вот через командную строку или шаблон вы упрётесь в ошибку.

az provider list --query "[?registrationState=='Registered'].namespace" -o tsv
az provider register --namespace Microsoft.ContainerService
az provider show --namespace Microsoft.ContainerService --query registrationState

Регистрация занимает от секунд до пары минут, и на это время создание ресурсов подождёт. Отсюда практическая привычка: в новой подписке регистрируют нужные поставщики заранее, до первого развёртывания, и держат этот список в коде инфраструктуры — иначе конвейер в новой подписке падает на первом же шаге.

Глубже: квоты: почему ресурс не создаётсярасширенное

Вторая частая ошибка в новой подписке звучит как QuotaExceeded или «недостаточно ядер в регионе». Это не про деньги и не про то, что в Azure кончились машины.

У подписки есть квоты, и считаются они не в машинах, а в ядрах по семействам типов, на каждый регион отдельно. У новой подписки значения скромные (десятки ядер), и «поднять десять машин по восемь ядер» в них не влезает. Отдельные квоты есть у публичных адресов, у групп безопасности, у наборов масштабирования и у большинства сервисов.

az vm list-usage --location westeurope -o table   # что занято и каков предел

Повышение квоты — это заявка в поддержку (из портала, раздел «Usage + quotas»), и обрабатывается она от минут до суток. Отсюда правило: квоты поднимают до того, как они понадобятся — особенно в резервном регионе, где в момент аварии ждать сутки неприемлемо. И раз в полгода их сверяют с фактическим потреблением, чтобы не обнаружить потолок в момент роста нагрузки.

Глубже: Azure Policy: правила, которые действуют самирасширенное

Группы управления введены как уровень, где применяют политики, — стоит сказать, что это за политики.

Azure Policy — механизм, который проверяет ресурсы на соответствие правилам и умеет либо сообщать о нарушении, либо не давать его создать, либо исправлять его сам. Правило описывается как условие и действие.

Что задают этим чаще всего:

  • Разрешённые регионы. Создавать ресурсы можно только в европейских регионах — типичное требование по хранению данных, и политика закрывает его жёстко, а не документом.
  • Обязательные теги. Ресурс без тега env и owner просто не создаётся (действие deny), либо тег доназначается от группы ресурсов (действие modify) — это и есть решение проблемы наследования из раздела выше.
  • Запрет публичного доступа. Хранилище без запрета публичного доступа, база с публичной точкой входа, диск без шифрования — всё это ловится политиками из готового набора.
  • Разрешённые размеры машин. Защита и от случайных дорогих типов, и от того, что кто-то поднимет машину с графическим ускорителем «посмотреть».
az policy assignment create --name require-tags \
  --scope /providers/Microsoft.Management/managementGroups/acme \
  --policy <идентификатор-определения> --params '{"tagName":{"value":"owner"}}'

Три практические вещи. Политики наследуются вниз по иерархии: назначенная на группу управления действует на все подписки внутри — именно поэтому группы управления и нужны. Существующие ресурсы политика не ломает: она помечает их как несоответствующие, и разбор этого списка — отдельная работа. И у политик есть исключения (exemptions) с датой — тот же приём, что и со списками исключений в сканерах: без даты исключение живёт вечно.

Начинают обычно с двух назначений: разрешённые регионы и обязательные теги. Они дают больше всего порядка при нулевом риске сломать работающее.

Коротко

  • Все операции управления идут через Resource Manager: портал, команда и шаблон отправляют один запрос, шаблон ARM это его родной язык, а журнал действий отвечает, кто удалил группу; операции над данными идут мимо него.
  • Иерархия: клиент Entra ID, подписка как граница изоляции и расходов, группа ресурсов как единица управления; под среды заводят разные подписки или группы, а группы управления применяют политики ко многим подпискам.
  • Блокировка CanNotDelete на боевые группы и всё необратимое: она наследуется вниз, не зависит от прав и мешает инфраструктуре как коду, о чём конвейер должен знать.
  • Две первые ошибки новой подписки: незарегистрированный поставщик ресурсов и квота ядер на регион; и то и другое готовят заранее, особенно в резервном регионе.
  • Entra ID отвечает «кто ты», RBAC «что можно»: роль плюс назначение на уровень с наследованием вниз; Contributor управляет ресурсом, а не данными внутри него.
  • Коду не дают ключей: managed identity выдаёт временные токены, а SDK находит их сам; права выписывают узкими сервисными ролями.
  • Отказоустойчивость строят на зонах одного региона, за трафик между зонами Azure платы не берёт; второй регион настраивают отдельно.
  • Серверы и базы живут без публичного IP, снаружи доступны только балансировщики; исходящий трафик через NAT Gateway, к сервисам Azure через приватные точки.
  • Теги env, service, owner и cost-center делают счёт читаемым, но не наследуются сами; Azure Policy доназначает их, ограничивает регионы и размеры машин и не даёт создать публичное хранилище.

Что почитать дальше