4

I'd like to start an EC2 instance on-demand, and to take it down when it is idle for some period of time (e.g. no network activity for >= 1 hour), but I can't tell what a standard way of doing this in AWS looks like, given that AWS doesn't support wake-on-LAN.

The service I intend to run will require a persistent network connection, e.g. ssh.

The user experience I am aiming for goes something like this:

  • If the service is up when the user attempts to connect, the user has immediate access to the service.
  • If the service is down when the user attempts to connect, the user receives a "service is starting" reply (and the connection is closed). The user retries after a few minutes and connects successfully (or receives the "starting" message again if he retries too early). The service remains up for up to an hour after the last user disconnects.

My motivation here is primarily cost savings. The demand will be highly unpredictable (so scheduled instances are not a good fit), probably less than 12 active hours/day, and the users are willing to wait a few minutes for the service to start. And I don't want to get locked in to a 1+ year term with reserved instance pricing.

I also have some wild stabs at how I might accomplish this, and would appreciate feedback on how plausible/sensible they are:

  1. Use an auto-scaling group that "scales" the service from 0 to a maximum of 1 instances. But I don't know how I'd be able to issue the "service is starting" reply if there are no instances running.
  2. Run a t2.micro instance when the service is down whose sole purpose is to catch a connection attempt, issue the "starting" reply, trigger the start the actual service instance, and then die. When the service instance goes down due to inactivity, it would need to start the t2.micro instance again.

Thanks!

koschei
  • 143
  • 1
  • 5
  • 3
    You're going to have to have *something* running 24x7. As you mentioned, this can be a very small instance, but you're not going to be able to shut it down as you proposed. – EEAA Mar 22 '16 at 14:57

2 Answers2

3

Lambda works somewhat like this, though instead it makes the user wait while it spins up an app. In Lambda though you don't have an instance to manage -- its all done under the hood.

I'd also check if you could do something involving Lambda and a Route53 failover check, such that users hit Lambda if the instance is down and the instance if it is up. This might not work of Lambda requires a specific Host header though.

Or use R53 failover again to run a reserved-instance t2.nano to do the 'waiting room', then proxy or redirect to another instance once it is up.

Jason Martin
  • 4,865
  • 15
  • 24
1

You can do something like this without using other services:

import boto3
import json

def lambda_handler(event, context):

    ec2 = boto3.resource('ec2')
    instance = ec2.Instance(event['instance_id'])

    if instance.state['Code'] == 16:
        # Instance is running, do what you want
    elif instance.state['Code'] == 80:
        # Instance is stopped, start it
        instance.start()
        return { 'status': 'instance-unavailable' }
    else
        # Instance is in another state

In this case, the instance_id is received by parameter but of course, you can hardcode it.

fsinisi90
  • 155
  • 2
  • 8