如何在自动缩放组中按计划停止/启动EC2实例而不终止实例?

时间:2014-08-22 20:18:53

标签: powershell amazon-web-services amazon-ec2 scheduled-tasks autoscaling

如果您有自动缩放组,那么如何开始/停止实例(启动/终止)?默认行为仅用于启动和终止实例,但由于我们还可以通过停止实例来节省成本,因此我们宁愿允许实例保持不变。

出于我们的目的,我们有一个QA环境,我们希望每天启动/停止几个自动缩放组,以便在开发团队在晚上和周末离开办公室时节省资金。

那么如何做到这一点?

注意:

我将很快跟进我自己的详细答案。

2 个答案:

答案 0 :(得分:1)

首先,AWS自动缩放组是基于启动配置的多个实例的容器。如果我们能够禁用触发向上/向下缩放的进程,我们将返回到仅容纳实例的容器。

为了禁用这些进程,我们需要使用AWS-CLI中的suspend-processes命令。对于此示例,我将使用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(他们真的只希望日志保持不变,但如果他们是迷失了,这不是世界末日)

接下来我们需要一个脚本来启动/停止服务器,这里我将它作为2个脚本,但您可以轻松地将其优化为一个脚本并传递参数:

# 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>

您需要制作此任务的“停止”版本,以便在晚上7点停止服务器。只需将您的起始边界更改为<StartBoundary>2014-08-22T19:00:00</StartBoundary>,然后将<Arguments>-ExecutionPolicy ByPass c:\tasks\AWS-Autoscaling-EC2-Start-Morning.ps1</Arguments>更新为正确的ps1

答案 1 :(得分:0)

您可以考虑使用 your script 运行AWS Data Pipeline 使用this script检索实例ID以及可用区和区域等

选择Create New Pipeline并输入以下信息:

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

请注意,数据管道会为您创建必要的 IAM Roles 有关详细信息,请参阅 AWS Data Pipeline Pricing

另请参阅使用 AWS Lambda 的其他选项。