Статьи

Развертывание Scorched Earth в Amazon EC2, TeamCity & Web Deploy — Часть 3. Конфигурация сборки

Теперь, когда мы все настроены в Amazon и у нас есть решение в состоянии, в котором мы можем легко упаковать и развернуть, пришло время автоматизировать все это с TeamCity, чтобы вам не пришлось вмешиваться, когда вы хотите запустить создать новый экземпляр вашего сайта для тестирования.

Этот пост является частью 3 в серии из 3 частей.

  • Часть 1. Конфигурация Amazon AWS
  • Часть 2. Конфигурация сайта и скрипты
  • Часть 3: Автоматизация всего с TeamCity

Первый тест на дым

Прежде чем мы начнем использовать TeamCity, мы, вероятно, должны сначала проверить, что все работает локально, поэтому мы собираемся развернуть, упаковать и отправить, а затем запустить новый экземпляр с наших локальных машин.

Нам нужно пройти через процесс, как если бы мы были TeamCity. Для начала запустите развертывание из Visual Studio, чтобы создать пакет webdeploy.

image_thumb18_thumb [6]

Теперь откройте консоль PowerShell и компакт-диск в папку. \ Automation. Теперь запустите ваш   файл PackageAndPublish.ps1 .

образ

Это должно показать, что ваши пакеты успешно загружены в Amazon S3.

Теперь запустите следующий скрипт для автоматизации создания экземпляров Amazon —  LaunchNewInstance.ps1

образ

теперь подождите несколько минут (обычно около 10) и нажмите URL, указанный в удаленном PowerShell — ваш сайт должен быть там.

Настройка сборки

Теперь давайте переключимся на TeamCity и создадим новый проект сборки — я назвал мой «Deploy to Amazon».

image_thumb32

Затем создайте первую конфигурацию сборки — она ​​называется «Пакет и публикация на S3».

image_thumb36

Сохраните это и перейдите на следующую страницу.

image_thumb59

Присоедините новый репозиторий системы контроля версий и сохраните.

image_thumb63

Сохраните и затем добавьте новый шаг сборки

image_thumb72

Настройте шаг сборки с помощью:

  • Бегун: MSBUILD
  • Путь к файлу сборки: «Website \ AmazonSampleApp.sln»
  • Версия MSBUILD: Microsoft .NET Framework 4.5
  • MSBuild Tools Версия: 4.0
  • Цели: «Чистая перестройка»
  • Параметры командной строки: / p: Конфигурация = Выпуск; DeployOnBuild = True; PublishingProfile = «Amazon»

image_thumb83

Теперь добавьте второй шаг сборки — мы заставим TeamCity выполнить наш сценарий PowerShell «PackageAndPublish.ps1» для загрузки пакета в S3.

Введите следующее:

  • Тип бегуна: Powershell
  • Название шага: Загрузить в Amazon
  • Версия в режиме запуска: 3.0
  • Битность: x86
  • Скрипт: Файл
  • Файл сценария: «автоматизация \ packageandpublish.ps1»
  • Режим выполнения скрипта: «Выполнить скрипт .ps1 с аргументом« -File »»

image_thumb [7]

Сохраните это и добавьте наш последний шаг — запуск нового экземпляра Amazon.

image_thumb [9]

Сохраните этот последний шаг сборки и сохраните его из конфигурации сборки.

То, что мы сделали здесь, это автоматизация:

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

Теперь, если вы запустите конфигурацию сборки TeamCity и посмотрите файл журнала, вы увидите сообщение с именем хоста вашего нового сервера:


Создан экземпляр веб-сервера : i-0c268260
Ожидание IP-адреса
Новый экземпляр Amazon доступен по адресу: http://ec2-23-20-118-227.compute-1.amazonaws.com

Через 10-15 минут вы увидите свой веб-сайт по URL-адресу, указанному в приведенном выше файле журнала.

А теперь иди принеси себе вкусный напиток на праздник!

Клонировать копию кода для повторного использования

Обеззараженную версию всего кода и сценариев, использованных в этой серии постов в блоге, можно найти в следующем репозитории Github.

Просто клонируйте и вставьте свои кредиты и настройки Amazon.

https://github.com/dougrathbone/amazon-scorched-earth

Если сначала у вас не получилось, попробуйте, попробуйте еще раз

Если вы запускаете сборку и у вас возникают проблемы, есть несколько вещей, которые вы можете сделать, чтобы исследовать.

Ec2ConfigService Logs

Обычно это первое место, куда я смотрю, потому что именно там сами Amazon пишут свои логи. Когда сервер запускается и запускает ваш файл UserData, скрипт запускается службой Windows, написанной Amazon, которая называется Ec2ConfigService. Файлы журналов этой службы — место, где можно искать что-либо непредвиденное, что произошло во время инициализации сервера.

Это хранится в C: \ Program Files \ Amazon \ Ec2ConfigService \ logs \ Ec2ConfigLog.txt

Логи, созданные с помощью моего скрипта

Еще одно место, которое нужно посмотреть, это файл журнала, в котором я записываю результаты моего сценария пользовательских данных, хранящегося в  C: \ Data \ AutomationLog.txt.  Обычно он показывает, где вы ошибаетесь при загрузке пакета, установке веб-развертывания и окнах. особенности и т. д.

Делая это на один шаг вперед (или многие)

Ускорение предоставления времени

Итак, вы видели выше, что каждому новому серверу (или развертыванию инфраструктуры) требуется около 10–15 минут, чтобы подключиться к сети, установить функции Windows и затем подготовить свой веб-сайт. Помните, что мы используем стандартный образ Windows Server 2012, предоставленный Amazon, на котором ничего не установлено (в нем также отсутствуют IIS и web-развертывание, поэтому нам также нужно время для их установки).

Вы можете ускорить это, создав образ Windows-сервера в начальном состоянии — обычно со всеми установленными службами и т. Д .; вы не хотите, чтобы ваше приложение было там или какие-либо зависимости, которые вы хотите развернуть во время выполнения сценария UserData, но вы хотите сохранить это время «позволяет установить IIS и WebDeploy».

Читайте об этом  здесь .

Пакеты мультисреды с Package-Web

Говорят, что Hashimi  из нашей команды Visual Studio имеет отличный проект с открытым исходным кодом, называемый  Package-Web,  который позволяет вам упаковать несколько преобразований web.config с вашим пакетом WebDeploy — и вы можете выбрать, какое преобразование запускать  во время развертывания,  что невероятно эффективно, если вы Если вы хотите создать вышеупомянутый пакет, но иметь возможность его самостоятельного развертывания в промежуточных или производственных средах — тогда вы можете сохранить один пакет и продвигать его между средами.

Nuget> Package-Web

Несколько серверов

Крутая вещь при запуске этого сценария сборки заключается в том, что с ним легко играть — возможно, вы используете кластер серверов и вам нужно развернуть 5 новых машин, чтобы заменить 5 старых. Просто измените наш  сценарий  powershell LaunchInstance.ps1, чтобы поднять количество серверов для запуска, и вы отключены.

Пример модификации нашего  LaunchInstance.ps1 :

echo 'Launching Web Server' 
$runRequest = new-object Amazon.EC2.Model.RunInstancesRequest
$runRequest.ImageId = $amiId
$runRequest.KeyName = $serverKey
$runRequest.MaxCount = "5"
$runRequest.MinCount = "5"
$runRequest.InstanceType = $instanceSize
$runRequest.SecurityGroupId = $securityGroup 
$runRequest.UserData = $userDataContent

Пометка экземпляров версией сборки

Одна интересная особенность EC2 — возможность  помечать серверы  ярлыками для последующей идентификации. Вы можете использовать эту метку для обозначения ваших серверов версией их сборки, чтобы позже вы могли легко отключить старые версии вашего приложения, просто убив предыдущие сборки (вы можете легко сделать это как часть вашего сценария powershell).

Пример нашего модифицированного   скрипта LaunchInstance.ps1 :

if($ip.Length -gt 0)
     {
        $newInstanceName = "$servername-$runResult"
        # We have an IP address


        $tag = New-Object Amazon.EC2.Model.Tag
        $tag.Key = "BuildVersion"
        $tag.Value = "1.00.1.3" 
        echo "Attempting to tag instance with build version $newInstanceName"
        $createTagsRequest = New-Object Amazon.EC2.Model.CreateTagsRequest
        $createTagsRequest.WithResourceId($runResult)
        $createTagsRequest.WithTag($tag);
        $null = $client.CreateTags($createTagsRequest);
}

Электронная почта по завершении

Еще одна идея, которую мы использовали на своем рабочем месте, заключается в том, чтобы каждый новый экземпляр отправлял вам электронное письмо после завершения настройки — либо чтобы вы знали, что он жив и здоров, либо для отправки вам журнала того, что пошло не так. Это избавит вас от необходимости копаться в журналах TeamCity в поисках URL-адреса экземпляра.

Это влечет за собой:

  • По завершении UserData сервер должен посетить локальный сайт с помощью WebClient или аналогичного.
  • Наличие на вашем сайте страницы, на которой выполняется проверка «предполетной проверки», например, общение с БД, любое совместное хранение данных и т. Д. (Приемочные тесты) и выдача исключения, если не 100%.
  • Сделайте так, чтобы ваша UserData PowerShell отвечала на коды статуса Http, которые возвращает страница, и отправляйте их по электронной почте соответственно.

Добавление балансировщика нагрузки по завершении

Выше я упоминал, что вы можете начать думать о том, чтобы серверы выполняли некоторые приемочные «предполетные» тесты (например, общение с вашей БД, проверка доступа на чтение / запись к любым общим ресурсам, таким как S3), а затем переходите к «добавлению себя» в ваш Эластичный балансировщик нагрузки — это позволяет настроить автоматическое масштабирование, чтобы кластер мог автоматически масштабироваться при возникновении нагрузки.

Пример:

Write-Host "Registering instance with the load balancer"
 
$elbConfig=New-Object Amazon.ElasticLoadBalancing.AmazonElasticLoadBalancingConfig
$elbConfig.ServiceURL = "HTTPS://elasticloadbalancing.us-east-1.amazonaws.com"
 
$elbClient=[Amazon.AWSClientFactory]::CreateAmazonElasticLoadBalancingClient($accessKeyID,$secretKeyID,$elbConfig)
 
$elbRequest = New-Object Amazon.ElasticLoadBalancing.Model.RegisterInstancesWithLoadBalancerRequest
$elbRequest.LoadBalancerName = "[name of load balancer]"
 
$instances = New-Object System.Collections.Generic.List[Amazon.ElasticLoadBalancing.Model.Instance]
$instance = New-Object Amazon.ElasticLoadBalancing.Model.Instance
$instance.InstanceId = $instanceId
$instances.add($instance)
 
$elbRequest.Instances = $instances
$elbResponse = $elbClient.RegisterInstancesWithLoadBalancer($elbRequest)