PowerShell DSC в продакшне: декларативный конфиг Windows без Puppet
Первый боевой опыт с PowerShell Desired State Configuration: описываем IIS и роли сервера как код. Аналог Puppet - но нативный, без агентов и мастер-сервера.
PowerShell Desired State Configuration (DSC) становится частью WMF 4.0 и Windows Server 2012 R2, предлагая декларативное управление конфигурацией нативными средствами Windows
Когда в прошлом месяце разбирали Ansible и идемпотентность, в комментариях закономерно прилетело: «а у вас же есть Windows-серверы, как там?» Там - иначе. Ansible на Windows работает через WinRM и пока что со скрипом, Puppet требует отдельного мастера и серьёзного вложения сил в настройку. И вот Microsoft выкатил в WMF 4.0 кое-что своё - Desired State Configuration.
Мы взяли DSC на одном из клиентских стендов под сопровождение и попробовали настроить через него IIS с несколькими сайтами и базовые роли сервера. Делимся тем, что получилось.
Что такое DSC в двух словах
Идея та же, что в Puppet или Chef: не пишешь скрипт «сделай то-то», а описываешь желаемое состояние системы. DSC сам разбирается, что нужно применить, а что уже в нужном виде и трогать не надо. Конфигурация компилируется в MOF-файл, который потом применяется на узле.
Выглядит это примерно так:
Configuration WebServer {
param ([string]$NodeName = 'localhost')
Node $NodeName {
WindowsFeature IIS {
Ensure = 'Present'
Name = 'Web-Server'
}
WindowsFeature IISManagement {
Ensure = 'Present'
Name = 'Web-Mgmt-Tools'
DependsOn = '[WindowsFeature]IIS'
}
File SiteRoot {
Ensure = 'Present'
Type = 'Directory'
DestinationPath = 'C:\inetpub\sites\myapp'
}
}
}
Запускаешь WebServer, получаешь MOF, потом Start-DscConfiguration - и Windows сам включает нужные роли, создаёт каталоги, не трогает то, что уже правильно.
Что мы реально настраивали
На стенде нужно было воспроизводимо поднимать веб-сервер с IIS: несколько application pools, несколько сайтов, конкретные версии .NET Framework, базовые настройки безопасности. Плюс стандартный набор - часовой пояс, региональные параметры, нужные Windows Features.
Проблема сразу вылезла с IIS-специфичными ресурсами. В базовой поставке DSC есть ресурсы для Windows Features, файлов, реестра, сервисов. Но для управления IIS-сайтами и пулами нужен модуль xWebAdministration из PowerShell Gallery - это экспериментальный (отсюда префикс x) набор ресурсов от Microsoft. Нестабильный, местами сырой, но работающий.
Установили xWebAdministration, и дело пошло:
xWebAppPool MainPool {
Name = 'MyApp'
Ensure = 'Present'
State = 'Started'
managedRuntimeVersion = 'v4.0'
}
xWebsite MainSite {
Name = 'MyApp'
Ensure = 'Present'
State = 'Started'
PhysicalPath = 'C:\inetpub\sites\myapp'
ApplicationPool = 'MyApp'
DependsOn = '[xWebAppPool]MainPool'
}
Работает. Пул создаётся, сайт поднимается, зависимости соблюдаются. Если запустить конфигурацию повторно на уже настроенном сервере - ничего лишнего не происходит.
Где споткнулись
Первое - отладка MOF. Ошибки компиляции конфигурации бывают невразумительными. «Resource xWebsite not found» вместо «установите модуль xWebAdministration» - это ещё мягкий вариант. Потратили время, пока разобрались с порядком импорта модулей.
Второе - push vs pull. DSC работает в двух режимах: push (ты сам толкаешь конфигурацию на узел) и pull (узел сам забирает конфигурацию с сервера по расписанию). Pull-режим логичнее для большого парка, но требует DSC Pull Server - отдельной роли. Для одного стенда мы обошлись push, но для нескольких серверов уже надо думать про pull и где его держать.
Третье - ресурсы с префиксом x это не шутка. Они реально могут повести себя неожиданно. У нас один раз xWebsite при повторном применении конфигурации удалил и пересоздал сайт вместо того чтобы проверить и пройти мимо. Разобрались: оказалось, что у сайта в IIS был добавлен вручную заголовок хоста, которого не было в конфиге, и ресурс счёл состояние неправильным. Урок: если сервер управляется через DSC - больше не трогай его вручную.
Четвёртое - нет встроенного аудита. Ansible по итогам прогона выводит что изменил, а что нет. DSC применяет конфигурацию - и молчит, если всё уже правильно. Get-DscConfigurationStatus есть, но читать его надо отдельно. Для привычного «что реально изменилось» нужно настраивать логирование отдельно.
Сравнение с Puppet и Ansible
С Ansible разница принципиальная: Ansible agentless и хорошо работает с Linux, с Windows - пока с ограничениями через WinRM. DSC - это родная Windows-технология, работает без сторонних агентов, через стандартный WinRM/WSMan. На чисто Windows-парке DSC смотрится органичнее.
С Puppet сравнение интереснее: оба декларативные, оба используют похожую концепцию ресурсов. Puppet на Windows работает, у него богатая экосистема модулей. Но Puppet требует мастер-сервера (или Puppet Enterprise за деньги), агента на каждой машине, настройки сертификатов. DSC из коробки - просто PowerShell, никаких дополнительных компонентов, кроме WMF 4.0.
Для небольшого парка Windows-серверов DSC выглядит разумным выбором. Порог входа ниже, зависимостей меньше, язык тот же PowerShell, который и так используется.
Где сейчас
На одном стенде всё работает, конфигурация в git, при изменениях - перегенерируем MOF и пушим. Не идеально: хотелось бы pull-режим, хотелось бы больше стабильных ресурсов для IIS. Но базовое управление ролями и структурой сервера через DSC - это уже реальная автоматизация, а не «скрипт настройки, который запустили один раз и забыли».
Следующий шаг - настроить Pull Server и попробовать управлять конфигурацией парка без ручного push на каждый узел. Но это уже отдельная история.