ADG Оставить заявку
Блог Автоматизация 5 мин чтения

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 на каждый узел. Но это уже отдельная история.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.