Как я уже говорил в прошлом посте, основная причина, по которой я подключал посторонние виртуальные машины к Azure Arc, это сбор метрик. Сегодня этим и займёмся.
И продолжим прямо с того места, где остановились — с созданной в Digital Ocean и подключённой к Azure Arc виртуальной машины. Так что если в сегодняшнем терраформе будут непонятно откуда взявшиеся куски и ссылки — они наверняка пришли из терраформа вчерашнего. В общем, погнали.
Сбор метрик виртуальных машин в Azure
Подход Azure к сбору метрик виртуальных машин (загрузки процессора, памяти, диска, и т.п.) называется VM Insights. На самом деле Insights это намного больше, чем просто сбор «железных» цифр. Но мы люди простые, и сегодня будем таращиться исключительно на примитивные картинки с циферками.
Включить VM Insights через UI — очень просто. Заходим на «Insights» панель в настройках VM, жмём «ВКЛ» кнопку, и минут через десять свежесозданные графики утешат глаз одержимого контролем девопса. Но жать кнопки — не есть путь джедая. Так что будем Terraform’ить.
Строительные блоки VM Insights
Ладно, хотя бы один раз нажать кнопку «ВКЛ» всё же придётся, но я уже это сделал за вас. Ведь при отсутствии внятной документации, должен же кто-то посмотреть, что там у Insights внутри. Я успешно провёл вскрытие, и вот что там откопалось:
- Как оказалось, Azure втихаря создал Log Analytics workspace (LA) ресурс, который будет подрабатывать базой данных для наших метрик.
- Он также добавил Data Collection Rule (DCR) — правило сбора данных, которое перечисляет, что именно мы будем собирать (Microsoft Insights, Performance Counters), и где это хранить (в LA).
- На виртуальной машине, для которой мы жали кнопку «Enable», появилось расширение — Azure Monitor Agent (AMA). Его главной обязанностью будет собирать заказанные DCR метрики и отправлять туда, куда скажут (опять же, в LA).
- Собственно, Azure явно создала привязку (association) DCR к виртуальной машине, тем самым замыкая круговорот метрик в природе.
Настройка VM Insights через Terraform
Зная эти компоненты, не требуется большого IQ, чтобы записать их в терраформ. Правда, есть проблема. Вот создали мы лог-аналитикс и правило сбора данных (LA + DCR), но на что вешать расширение и ассоциацию? Ведь Arc машина создаётся shell скриптом, который, пусть и забрасывается в Digital Ocean машину терраформом, но оттуда выполняется и общается с Azure уже совсем автономно. Как синхронизировать эту автономность с терраформом — непонятно.
Но есть обходной манёвр — Azure Policy. Полиси описывает, как должны выглядеть ресурсы в идеале, и что делать, если идеал не случился. То есть мы можем создать полиси, которая скажет, что в данной ресурсной группе все виртуальные машины должны иметь расширение для мониторинга и привязку к DCR правилу, и если это не так — автоматически патчить врагов на месте. Во имя порядка!
И между прочим, такие полиси даже создавать не надо — они идут с Azure в комплекте:
- «Configure Linux Arc-enabled machines to run Azure Monitor Agent» для установки расширений.
- «Configure Linux Machines to be associated with a Data Collection Rule or a Data Collection Endpoint» — для привязки DCR.
Нам всего-то нужно включить эти полиси в ресурсной группе и передать им айдишку DCR правила. А дальше магия будет происходить автоматически.
Шаги 1-2: Создаём Log Analytics Workspace и Data Collection Rule
Создать LA можно с закрытыми глазами и руками, привязанными к затылку:
1 2 3 4 5 6 7 |
resource "azurerm_log_analytics_workspace" "this" { name = "Arc-Telemetry" resource_group_name = azurerm_resource_group.this.name location = azurerm_resource_group.this.location sku = "PerGB2018" retention_in_days = 30 } |
Так как метрики-данные имеет смысл хранить в том же регионе, что и машины, с которых они собираются, мы положим LA в ту же ресурсную группу, что и Arc машины.
Создание Data Collection Rule проходит чуть более геморройно. В основном потому, что документация по его настройке по качеству близка к статистической погрешности. Я не придумал ничего лучше, чем создать DCR руками, посмотреть на его JSON внутренности, и повторить находки в Terraform.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
resource "azurerm_monitor_data_collection_rule" "this" { name = "Arc-Telemetry-Collection-Rule" resource_group_name = azurerm_resource_group.this.name location = azurerm_resource_group.this.location destinations { log_analytics { workspace_resource_id = azurerm_log_analytics_workspace.this.id name = "VMInsightsPerf-Logs-Dest" } } data_flow { streams = ["Microsoft-InsightsMetrics"] destinations = ["VMInsightsPerf-Logs-Dest"] } data_sources { performance_counter { streams = ["Microsoft-InsightsMetrics"] sampling_frequency_in_seconds = 60 counter_specifiers = ["\\VmInsights\\DetailedMetrics"] name = "VMInsightsPerfCounters" } } } |
В принципе, конфигурация в чём-то даже логична. destinations-log_analytics
, очевидно, указывает, что хранить данные мы будем в LA. data_flow
в чём-то тоже имеет смысл — он привязывает источник данных к их получателю, и может применять трансформации данных на лету. Нам это не нужно, и мы передаём данные как есть.
data_sources
тоже было бы прекрасным в своей понятности свойством, да только все его параметры выглядят слабо предсказуемыми, и нагуглить, какие ещё значения туда можно передать — нереально. Будем копипастить, что есть.
В любом случае, такая конфигурация оказалась валидной, Azure всё проглотил, так что теперь переходим к более сложным вещам — полиси.
Шаги 3-4: Создаём полиси для мониторинг-расширения и привязки к DCR
Ну что, пришло время чёрной магии. Во-первых, на уже существующие полиси надо сослаться из терраформа.
1 2 3 4 5 6 7 |
data "azurerm_policy_definition" "monitoring-agent" { display_name = "Configure Linux Arc-enabled machines to run Azure Monitor Agent" } data "azurerm_policy_definition" "data-collection-rule" { display_name = "Configure Linux Machines to be associated with a Data Collection Rule or a Data Collection Endpoint" } |
Во-вторых, их нужно привязать к нашей ресурсной группе. Для полиси, создающей Azure Monitor Agent расширение, даже дополнительных параметров не надо:
1 2 3 4 5 6 7 8 9 10 11 12 |
resource "azurerm_resource_group_policy_assignment" "monitoring-agent" { name = "Enable Azure Monitor on Arc Machines" resource_group_id = azurerm_resource_group.this.id policy_definition_id = data.azurerm_policy_definition.monitoring-agent.id identity { type = "SystemAssigned" } location = local.azure_arc_region enforce = true } |
А для DCR-привязки нужно всего-то передать айдишку DCR:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
resource "azurerm_resource_group_policy_assignment" "data-collection-rule" { name = "Associate Data Collection Rule with Arc Machines" resource_group_id = azurerm_resource_group.this.id policy_definition_id = data.azurerm_policy_definition.data-collection-rule.id parameters = <<PARAMS { "dcrResourceId":{ "value": "${azurerm_monitor_data_collection_rule.this.id}" } } PARAMS identity { type = "SystemAssigned" } location = local.azure_arc_region enforce = true } |
Кроме стандартной для полиси ерунды мы ещё включили им «SystemAssigned» айдентити. Ведь полиси будут изменять состояние ресурсов, и для этого нужны права доступа. А права доступа на ресурсы не вешаются, только на кого-то — пользователей, группы, сервисные аккаунты (service principal), да системные и пользовательские айдентити. Вот мы их и включили через identity {}
блок.
Для редактирования виртуальных машин айдентити потребуется «Azure Connected Machine Resource Administrator» роль. Для DCR-привязки же нужен «Monitoring Contributor». Всё это элементарно делается терраформом.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
resource "azurerm_role_assignment" "monitoring-agent" { scope = azurerm_resource_group.this.id role_definition_name = "Azure Connected Machine Resource Administrator" principal_id = azurerm_resource_group_policy_assignment.monitoring-agent.identity[0].principal_id } resource "azurerm_role_assignment" "data-collection-rule" { for_each = toset([ "Azure Connected Machine Resource Administrator", "Monitoring Contributor" ]) scope = azurerm_resource_group.this.id role_definition_name = each.key principal_id = azurerm_resource_group_policy_assignment.data-collection-rule.identity[0].principal_id } |
Тест-драйв
Я положил новые ресурсы в arc-policies.tf
файл, по соседству к прошлым main.tf
и arc.tf
, и затем натравил terraform apply
команду:
Полиси появились практически сразу. Им потребовалось немного времени, чтобы обнаружить, что существует целая Ar машина, у которой всё ещё нет ни расширения, ни DCR-привязки, но лучше поздно, чем завтра. В течение получаса в настройках виртуальной машины появилось полностью работоспособное Azure Monitoring Agent расширение, а ещё через пару минут на Insights дашборде появились первые данные.
Мораль
Надеюсь, теперь даже самые ярые атеисты осознали, что гибридное облако — это не просто новомодный культ, а самое что ни на есть полезное колдунство. Да, в Digital Ocean, чью машину мы подключали к Azure через Azure Arc, есть свой мониторинг, так что как бы зачем это всё. Но ведь в реальной жизни я подключал не DO, а какого-то мутного французского облачного провайдера, где даже пользователей фиг создашь, не то, что мониторинг. В том случае Arc был чудовищно полезен.
Более того, Arc — это ведь не только про мониторинг. Мы ещё могли бы собрать логи, включить контроль доступа, автоматические апдэйты, контроль настроек, антивирус и прочие достижения западной цивилизации. Всё это запросто делается через полиси и расширения. Приди к нам завтра госдеп и закажи FedRAMP сертификацию для Digital Ocean машин, и я бы, наверное, застрелился. А подключи их к Arc, и всё уже не так уж и страшно.
В общем, гибридные облака, Azure Arc и направляющая рука Terraform — вот где наше счастливое будущее, а не во всяких там смыслах жизни и хорошем поведении.