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

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

<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, а затем разверну его с точно таким же сценарием пользовательских данных, он не будет работать. Но если я перейду к экземпляру URL (http://169.254.169.254/latest/user-data) он покажет, что скрипт успешно импортирован, но не был выполнен.

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

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

5 ответов

Решение

Обновление 15.04.2017: для EC2Launch и Windows Server 2016 AMI

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

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

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

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

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

Пользователи Windows Server 2016 должны дополнительно включить настройку и включить EC2Launch вместо EC2Config. EC2Config был объявлен устаревшим для AMI 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и укажите назначенную задачу для сценария пользовательских данных (или другого сценария) в 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>

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

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

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

Вот быстрый шаг за шагом:

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

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

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

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

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

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

<persist>true</persist>

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

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

Я добавил ниже сценарий powershell для запуска во время процесса выпечки AMI, который помог мне решить эту проблему. Это был сервер Windows 2019.

      $EC2LaunchInitInstance = "C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1"
$EC2LaunchSysprep = "C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\SysprepInstance.ps1"
Invoke-Expression -Command "$EC2LaunchInitInstance -Schedule"
Invoke-Expression -Command "$EC2LaunchSysprep -NoShutdown"
Другие вопросы по тегам