Amazon EC2 custom AMI не запускает загрузку (пользовательские данные)

Я столкнулся с проблемой при создании пользовательских AMI (изображений) в экземплярах EC2. Если я запустил экземпляр сервера Windows по умолчанию 2012 с пользовательскими загрузочными/пользовательскими данными script, например:

<powershell>
PowerShell "(New-Object System.Net.WebClient).DownloadFile('http://download.microsoft.com/download/3/2/2/3224B87F-CFA0-4E70-BDA3-3DE650EFEBA5/vcredist_x64.exe','C:\vcredist_x64.exe')"
</powershell>

Он будет работать по назначению и перейти к URL-адресу и загрузить файл и сохранить его на диске C:.

Но если я настрою экземпляр Windows Server, затем создаю образ из него и сохраню его как пользовательский AMI, а затем разворачиваю его с помощью тех же пользовательских пользовательских данных script, это не сработает. Но если я перейду к экземпляру url (http://169.254.169.254/latest/user-data), он покажет, что script успешно импортирован, но не был выполнен.

После проверки журналов ошибок я заметил это регулярно:

Failed to fetch instance metadata http://169.254.169.254/latest/user-data with exception The remote server returned an error: (404) Not Found.

Ответ 1

Обновление 4/15/2017: для AMILaunch и Windows Server 2016 AMI

В документации AWS для пользователей EC2Launch пользователи Windows Server 2016 могут продолжать использовать теги persist, представленные в EC2Config 2.1.10:

Для EC2Config версии 2.1.10 и более поздних версий или для EC2Launch вы можете использовать true в пользовательских данных, чтобы включить плагин после выполнение пользовательских данных.

Пример данных пользователя:

<powershell>
    insert script here 
</powershell> 
<persist>true</persist>

Для последующих ботов:

Пользователи Windows Server 2016 должны дополнительно включить настроить и включить EC2Launch вместо EC2Config. EC2Config устарел на ОЗУ Windows Server 2016 в пользу EC2Launch.

Запустите следующую команду powershell, чтобы запланировать задачу Windows, которая будет запускать пользовательские данные при следующей загрузке:

C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 –Schedule

По своей конструкции эта задача отключается после ее запуска в первый раз. Однако использование тега persist заставляет Invoke-UserData планировать отдельную задачу через Register-FunctionScheduler, чтобы сохранить ваши пользовательские данные при последующих загрузках. Вы можете увидеть это сами в C:\ProgramData\Amazon\EC2-Windows\Launch\Module\Scripts\Invoke-Userdata.ps1.

Дальнейшее устранение неполадок:

Если у вас возникли дополнительные проблемы с вашими сценариями пользовательских данных, вы можете найти журналы выполнения пользовательских данных в C:\ProgramData\Amazon\EC2-Windows\Launch\Log\UserdataExecution.log для экземпляров, полученных из базового AMI WS 2016.


Исходный ответ: для EC2Config и более старых версий Windows Server

Выполнение пользовательских данных автоматически отключается после начальной загрузки. Когда вы создали свое изображение, вероятно, что исполнение уже отключено. Это настраивается вручную в C:\Program Files\Amazon\Ec2ConfigService\Settings\Config.xml.

Документация для "Настройка экземпляра Windows с помощью службы EC2Config" предлагает несколько вариантов:

  • Программно создать запланированную задачу для запуска при запуске системы с помощью schtasks.exe /Create и указать запланированную задачу на пользовательские данные script (или другой script) на C:\Program Files\Amazon\Ec2ConfigServer\Scripts\UserScript.ps1.

  • Программно включить плагин пользовательских данных в файле Config.xml.

Пример из документации:

<powershell>
$EC2SettingsFile="C:\Program Files\Amazon\Ec2ConfigService\Settings\Config.xml"
$xml = [xml](get-content $EC2SettingsFile)
$xmlElement = $xml.get_DocumentElement()
$xmlElementToModify = $xmlElement.Plugins

foreach ($element in $xmlElementToModify.Plugin)
{
    if ($element.name -eq "Ec2SetPassword")
    {
        $element.State="Enabled"
    }
    elseif ($element.name -eq "Ec2HandleUserData")
    {
        $element.State="Enabled"
    }
}
$xml.Save($EC2SettingsFile)
</powershell>
  • Начиная с версии EC2Config версии 2.1.10, вы можете использовать <persist>true</persist> для включения плагина после выполнения пользовательских данных.

Пример из документации:

<powershell>
    insert script here
</powershell>
<persist>true</persist>

Ответ 2

В конце начальной загрузки (UserData) script просто добавьте тег persist, как показано ниже. Прекрасно работает.

<powershell>
    insert script here
</powershell>
<persist>true</persist>

Ответ 3

Другим решением, которое сработало для меня, является запустить Sysprep с EC2Launch.

Проблема заключается в том, что AWS не восстанавливает маршрут к службе профиля (169.254.169.254) в вашем пользовательском AMI. См. Ответ SanjitPatel в этом post. Поэтому, когда я пытался использовать свой пользовательский AMI для создания точечных запросов, мои новые экземпляры не смогли найти пользовательские данные.

Завершение работы с помощью Sysprep, по сути, заставляет AWS выполнять все работы по настройке экземпляра, как если бы он запускался в первый раз. Поэтому, когда вы создаете свой экземпляр, закройте его с помощью Sysprep и затем создайте свой собственный AMI, AWS правильно настроит маршрут сервиса профиля для новых экземпляров и выполнит ваши пользовательские данные. Это также позволяет избежать ручного изменения задач Windows и выполнения пользовательских данных при последующих загрузках, как это делает тег persist.

Вот шаг за шагом:

  • Создайте экземпляр, используя один из AMI для Windows AWS (Windows Server 2016 Nano Server не поддерживает Sysprep) и передачи ваших желаемых пользовательских данных (это может быть необязательно, но полезно убедиться, что AWS правильно устанавливает скрипты для работы с пользователем данные).
  • Настройте свой экземпляр по мере необходимости.
  • Завершите свой экземпляр с помощью Sysprep. Просто откройте приложение EC2LaunchSettings и нажмите "Shutdown with Sysprep". Полные инструкции здесь.
  • Создайте свой собственный AMI из экземпляра, который вы только что отключили.
  • Используйте свой собственный AMI для создания других экземпляров, передавая данные пользователя при создании экземпляра. Пользовательские данные будут выполняться при запуске экземпляра. В моем случае я использовал экран Spot Request, в котором было текстовое поле User Data.

Надеюсь, это поможет!

Ответ 4

Для тех людей, которые пришли от Google и работают с экземпляром Server 2016, кажется, что это уже невозможно.

Server2016 не имеет службы ec2config, поэтому вы не можете использовать флаг persist.

<persist>true</persist>

Описано в сообщении Энтони Ниса.

Сервер 2016 использует EC2Launch, и я еще не видел, как можно запускать script при каждой загрузке. Вы можете запустить script при первой загрузке, но последующие загрузки не будут запускаться.