Как остановить/запустить экземпляр EC2 по расписанию в группе автомасштабирования без прерывания экземпляра?

Если у вас есть группа автомасштабирования, как вы собираетесь запускать/останавливать экземпляры ( не запуск/завершение)? Поведение по умолчанию - это только для запуска и завершения экземпляров, но поскольку мы также получаем экономию затрат только для остановки экземпляра, мы скорее предпочли бы, чтобы экземпляр сохранялся.

Для наших целей у нас есть среда QA, и мы хотим ежедневно запускать/останавливать несколько групп автомасштабирования, чтобы сэкономить деньги, когда команда разработчиков покидает офис для вечеров и выходных дней.

Итак, как это сделать?

Примечание:

В ближайшее время я продолжу свой собственный подробный ответ.

Ответ 1

Прежде всего, группа автомасштабирования AWS является контейнером для нескольких экземпляров, которые основаны на конфигурации запуска. Если мы можем отключить процессы, которые вызывают масштабирование вверх/вниз, мы вернемся к контейнеру, который просто содержит экземпляры.

Чтобы отключить эти процессы, нам нужно использовать команду suspend-processes от AWS-CLI. В этом примере я буду использовать powershell, но его так же легко записать в bash:

# suspend HealthCheck and ReplaceUnhealthy processes, you may find another combination works better for you.
$asGroup = "nameOfYourAutoScalingGroup" ;
aws autoscaling suspend-processes `
    --auto-scaling-group-name $asGroup `
    --scaling-processes HealthCheck ReplaceUnhealthy ;

# verify the change
awsp autoscaling describe-auto-scaling-groups `
    --auto-scaling-group-name $asGroup ;

В моих целях я хотел, чтобы экземпляры были в режиме онлайн между 7 утра и 7 вечера, чтобы сократить расходы. Эти экземпляры используются между нашими командами разработки и QA, и они предпочитают сохранять состояние сервера изо дня в день.

ПРИМЕЧАНИЕ: в случае, когда экземпляр EC2 становится коррумпированным или случайно завершен, наша команда в порядке с откатом до последнего AMI (они действительно хотят, чтобы журналы сохранялись, но если они потерянный, это не конец света)

Далее нам понадобится script для запуска/остановки серверов, здесь у меня это как 2 скрипта, но вы можете легко оптимизировать его в один script и передать аргумент в:

# in our case, we want to perform this to all autoscaling groups
# you'll need Powershell 3.0+ in order to use ConvertFrom-Json
$asGroups = aws autoscaling describe-auto-scaling-groups --query 'AutoScalingGroups[*].{Name:AutoScalingGroupName,Instances:Instances[*].InstanceId}' ;
$asGroups = "{ asGroups: $asGroups }" | ConvertFrom-Json ;

# foreach autoscaling group, go through each instance and start
foreach ($asGroup in $($asGroups.asGroups)) {

    echo "AS: $($asGroup.Name)" ;
    foreach ($instance in $asGroup.instances) {
        echo "starting instance: $instance";
        aws ec2 start-instances `
            --instance-ids $instance ;
    }
}
# in our case, we want to perform this to all autoscaling groups
# you'll need Powershell 3.0+ in order to use ConvertFrom-Json
$asGroups = awsp autoscaling describe-auto-scaling-groups --query 'AutoScalingGroups[*].{Name:AutoScalingGroupName,Instances:Instances[*].InstanceId}' ;
$asGroups = "{ asGroups: $asGroups }" | ConvertFrom-Json ;

# foreach autoscaling group, go through each instance and stop
foreach ($asGroup in $($asGroups.asGroups)) {

    echo "AS: $($asGroup.Name)" ;
    foreach ($instance in $asGroup.instances) {
        echo "stopping instance: $instance";
        awsp ec2 stop-instances `
            --instance-ids $instance ;
    }
}

Последним шагом было бы добавить его в запланированные задачи на сервере управления (сейчас я просто использую свой рабочий стол, который никогда не отключается). Приложен пример экспортированной задачи расписания, выполняется еженедельно Пн, Вт, Ср, Чт, Пятница в 7 утра.

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2014-08-22T13:13:02.2103946</Date>
    <Author>localhost\Administrator</Author>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2014-08-22T07:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByWeek>
        <DaysOfWeek>
          <Monday />
          <Tuesday />
          <Wednesday />
          <Thursday />
          <Friday />
        </DaysOfWeek>
        <WeeksInterval>1</WeeksInterval>
      </ScheduleByWeek>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>localhost\Administrator</UserId>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command>
      <Arguments>-ExecutionPolicy ByPass c:\tasks\AWS-Autoscaling-EC2-Start-Morning.ps1</Arguments>
      <WorkingDirectory>c:\tasks</WorkingDirectory>
    </Exec>
  </Actions>
</Task>

Вам нужно будет сделать "Stop" версию этой задачи, чтобы остановить серверы в 7 вечера. Просто измените начальную границу на <StartBoundary>2014-08-22T19:00:00</StartBoundary> и обновите <Arguments>-ExecutionPolicy ByPass c:\tasks\AWS-Autoscaling-EC2-Start-Morning.ps1</Arguments> до правильного ps1.

Ответ 2

Вы можете использовать ваш script, используя AWS Data Pipeline.
Используйте этот script для извлечения идентификатора экземпляра, а также зоны и области доступности и т.д.

Выберите Создать новый трубопровод и введите следующую информацию:

Name: for example, "Start EC2 instances" and "Stop EC2 instances".
Description: Provide relevant details about the pipeline as needed.
Source: Choose Build using template and choose the template Run AWS CLI command.
AWS CLI command: This is where you put your script to specify what the pipeline does.

Настройте каждый конвейер с соответствующей информацией scheduling.

Run: Choose on activation to run the pipeline as an on-demand pipeline.  
Run every: Enter a period for every pipeline run.
Starting: Enter a time and date for the pipeline to start.
Ending: Enter a time and date for the pipeline to end.

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

IAM Roles: Choose Custom
Pipeline Role: DataPipelineDefaultRole
EC2 Instance Role: DataPipelineDefaultResourceRole

Обратите внимание, что Data Pipeline создает для вас необходимую роли IAM.
Для получения дополнительной информации см. Цены на передачу данных AWS.

См. также другую опцию, используя AWS Lambda.