Установка дополнительных компонентов на Web/Worker роли с использованием Web Platform Installer Command Line Tool

Привет!

Сперва хочу немного объяснить контекст задачи, а уже потом перейду к сути поста. Недавно столкнулся с одной простой, на первый взгляд, задачей. Но, как оно обычно бывает, на ее решение потратил намного больше времени, чем ожидалось. Основная идея была токова - нужно разработать веб портал, при помощи котрого пользователь сможет запросить N виртуальных машин в Microsoft Azure настроенных согласно определенному шаблону. Стандартным сценарием для нас было использование следующего шаблона:

  • вируальная сеть из 3 виртуальных машин
  • одна из машин является контроллером домена, а остальные входят в этот домен
  • на одной из машин развернут MS SQL Server

Если разворачивать все это руками с портала, то это потребует довольно много времени, а такое окружение мы можем запрашивать по несколько раз на дню. И вот мы принялись автоматизировать создание таких окружений и за инструмент автоматизации мы взяли Powershell. Такой выбор был обусловлен фактом, что используя Powershell можно решить все поставленные задачи, а именно: развернуть N виртуальных машин в Vindows Azure, установить контроллер домена и т.д. Таким образом мы сможем легко поддерживать нашу систему автоматизации в дальнейшем.

Основной проблемой в реализации такого решения стала необходимость установить на нашей Web роли набор Microsoft Azure Powershell cmdlet-ов, собственно для отправки команд на Microsoft Azure Management API. Данный набор Powershell cmdlet-ов можно свободно скачать с сайта azure.com(раздел Command-line tools), но он будет установлен на локальной машине через Web Platform Installer. Это решение не очень хорошо нам подходит по нескольким причинам:

  1. Web Platform Installer запускает свой UI, в котором пользователь должен делать выбор при помощи мыши или клавиатуры. Т.е. автоматизацией тут и не пахнет.
  2. Немного исследовав предыдущую тему выяснилось, что в комплекте Web Platform Installer-а с недавнего времени появились Web Platform Installer Command Line Tool-ы. Именно с их помощью можно органиовать автоматизацию установки интересующих нас дополнений. Но есть одно замечание - Web Platform Installer всегда будет устанавливать самую последнюю версию Microsoft Azure Powershell cmdlet-ов. С одной стороны это хорошо, но, на самом деле это очень плохо. Как все мы помним Startup Tasks запускаются в момент выделения ресурсов для конкретного экземпляра (instance) нашей Web роли. Т.е. в случае сбоя провизор Microsoft Azure может перевезти один из экземпляров нашей Web роли на новое оборудование, там будет запущена инсталяция Microsoft Azure Powershell cmdlet-ов через Web Platform Installer. В результате мы можем получить ситуацию когда на разных экземплярах Web роли мы будем иметь разные версии Microsoft Azure Powershell cmdlet-ов.

Поработав мозгами еще немного было обнаружено, что с недавнего времени у Web Platform Installer-а есть очень хитрый режим работы, который называется Offline режим. Идея данного режима проста и прозрачна - он позволяет нам сделать текущую offline копию необходимых нам модулей и проводить их дальнейшую установку непосредственно с локальной копии, а не с глобального репозитория. Итого у меня получилась следующая последовательность действий:

  1. Устанавливаем локально Web Platform Installer.
  2. Делаем offline копию Microsoft Azure Powershell cmdlet-ов.
  3. Добавляем Microsoft Azure Powershell cmdlet-ы и скрипт для их установки в проект.

Устанавливаем локально Web Platform Installer

Этот шаг самый простой. Для его выполнения нам необходимо:

  1. пройти по ссылке https://www.iis.net/learn/install/web-platform-installer/web-platform-installer-v4-command-line-webpicmdexe-rtw-release
  2. пролистать вниз до секции Downloading WebPI и скачать себе локально Web Platform Installer x86 https://download.microsoft.com/download/7/0/4/704CEB4C-9F42-4962-A2B0-5C84B0682C7A/WebPlatformInstaller_x86_en-US.msi или Web Platform Installer x64 https://download.microsoft.com/download/7/0/4/704CEB4C-9F42-4962-A2B0-5C84B0682C7A/WebPlatformInstaller_amd64_en-US.msi
  3. пройти по всем шагам мастера установки Web Platform Installer

Делам offline копию Microsoft Azure Powershell cmdlet-ов

С этого момента мы начинаем использовать Web Platform Installer Command Line Tool. Чтобы получить первое представление о том как работают данные утилиты командной строки мы возвращаемся к уже извествной нам странице https://www.iis.net/learn/install/web-platform-installer/web-platform-installer-v4-command-line-webpicmdexe-rtw-release. В секции Setting up WebPICMD.exe мы видим, что интересующие нас утилиты расположены в директории

%programfiles%\microsoft\web platform installer 

В секции Using WebPICMD.exe мы видим руководство по использованию Web Platform Installer Command Line Tool. Теперь запустим приложение командной строки (cmd) от имни администратора и выполним следующие действия:

1. Перейдем в нужную директорию.

cd "%programfiles%\microsoft\web platform installer"

2. Получим список всех приложений, которые есть в репозиториях Web Platform Installer. Тут я столкнуся с проблемой связанной с ограничением на количество строк отображаемых приложением командной строки. Из-за этого ограничения я могу видеть только конец списка доступных прилижений. На текущий момент я нашел 2 способа как это побороть:

2.1. Перенаправляем поток вывода в файл:

WebpiCmd.exe /list /listoption:all > all.txt

На файловой системе в текущей папке будет создан файл all.txt в котором будет список всех приложений из репозиториев Web Platform Installer.

2.2. Воспользуемся поиском по результатам:

WebpiCmd.exe /list /listoption:all | find /i "powershell"

В данном примере мы увидим на экране только те строчки, в которых встречается подстрока "powershell". Если вам интересно что именно делает команда find, то можете пройти по этой ссылке https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/find.mspx?mfr=true и почитать более подробное ее описание.

В результате мы получаем список из двух колонок. Первая - это ID продукта (который собственно нам необходим), а вторая - описание.

PowerShell                Windows PowerShell
FakePre-d79268dfb6d9429fa0c2eb3f72b089cb-7648446898bf4bd1ac1b3d500858fb6eFakePre-84c31f54222542cda7f69acdf06c21f9-e7fd385a2b114065a0eb97fe57d83226FakePre-60bdcd491af641d4826de0faa14ca4bc-d5dd5fde71db40058c869f975010e13cFakePre-752d51292e9048a6b35f37c2304ba87a-ec62321bf955405f948aa05347d77cf6FakePre-b97f5e3a5cbe4586988f8ec6a207116c-2a40c1a1f2fe4c139a788ca6ba39d91e

3. Делаем локальную копию интересующего нас продукта:

WebpiCmd.exe /offline /products:WindowsAzurePowershell /path:c:\offline

В результате выполнения этой команды у нас будет создана папка offline в корне диска C. В эту папку будет помещено все необходимое для установки пакета WindowsAzurePowershell. Стоит отметить, что Web Platform Installer скачает нам не только сам пакет, но и все его возмоные заисимости для разных операционых систем. Таким образом у меня папка offline заняла около 600 МБ при размере файла windowsazure-powershell.0.7.4.msi около 9 МБ.

Добавляем Microsoft Azure Powershell cmdlet-ы и скрипт для их установки в проект

Ну и в завершение всей эпопеи мы должны добавить в нашу Web/Worker роль следующие вещи:

1. Добавляем в проект файл windowsazure-powershell.0.7.4.msi, который является установочным пакетом для Microsoft Azure Powershell cmdlet-ов. Стоит отметить, что для Windows Server 2012 больше ничего не нужно добавлять в проект. Возможно для других версий операционной системы нужно добавить что-то еще, но наше приложение размещалось на Windows Server 2012, а других тестов я не проводил.

2. Добвляем скрипт командной строки InstallWindowsAzurePowershell.cmd для установки Microsoft Azure Powershell cmdlet-ов. В моем примере он выглядит чертовски просто:

windowsazure-powershell.0.7.4.msi /quiet

3. Добавляем новую Startup задачу в файл ServiceDefinition.csdef:

executionContext="elevated"
taskType="simple"
commandLine="InstallWindowsAzurePowershell.cmd" />

Главное запустить данную задачу с правами администратора (executionContext="elevated"), а также дождаться ее завершение до запуска роли (taskType="simple"). Если вам интересно подробнее почитать про Startup задачи, то можете пройти по ссылке https://msdn.microsoft.com/en-us/library/windowsazure/hh180155.aspxи почитать об этом более подробно в официальной документации.

Теперь мы можем быть уверены, что каждый экземпляр роли будет содержать единую версию Microsoft Azure Powershell cmdlet-ов. В случае необходимости обновления до более новой версии нам нужно будет пройти весь путь от начала до конца и пересоздать/проапдейтить роль с новым дистрибутивом.

Надеюсь данный материал будет полезен моим читателям. Если у вас возникли вопросы, то оставляйте их в комментариях и/или пишите мне на почту. Также я рекомендую почитать другую мою статью на тему Startup задач http://boykoant.azurewebsites.net/azure/blog/startup-task-execution-in-web-worker-roles.

Автор статьи: Антон Бойко.