Reputation: 7631
I'd like to give my client a (password protected) link, such that opening it will start an AWS instance. Is it possible to do it using AWS-Lambda without constantly running another instance?
Upvotes: 4
Views: 372
Reputation: 7631
Unfortunately @E.J. Brennan's answer requires passing HTTP headers in the request for authentication, while my client isn't a technical person, and doesn't use curl
or Postman
, he just needs a simple url to click in order to start the instance.
So, as a workaround I'm passing a query parameter:
import boto3
# Enter the region your instances are in, e.g. 'us-east-1'
region = 'xx'
# Enter your instances here: ex. ['X-XXXXXXXX', 'X-XXXXXXXX']
SECRET = "top"
KEY_ALIAS = "mykey"
instances = ['i-XXX', ...]
def lambda_handler(event, context):
if not KEY_ALIAS in event:
return "Missing key"
if event[KEY_ALIAS] == SECRET:
ec2 = boto3.client('ec2', region_name=region)
ec2.start_instances(InstanceIds=instances)
return 'Started servers. They will be available in 2 minutes.'
else:
return "Non-autorized"
In order to make it work, we need to configure an endpoint in API gateway.
Important: This won't work when going to the Triggers
tab of the lambda function and selecting API gateway
from the menu, since that will create a resource with ANY
method. We'll need to do it manually, by creating a resource and then a GET
method, then linking it to our function.
Next, we need to tell the AWS API we're passing a parameter named mykey
. We need to select our GET
method and then Integration Request
, at the bottom there should be an option for Body Mapping Templates
. If you don't see it, make sure the method is indeed GET
rather than ANY
(I was stuck on this for a while). Then create a new template:
{
"mykey" : "$input.params('mykey')"
}
Next, we select Method Request
and add mykey
in URL Query String Parameters
.
We also need to create a stage and add the resource there, we'll be prompted to do so anyway before deploying. Finally we need to deploy the API, and voila, the client can now click:
https://XX.execute-api.REGION.amazonaws.com/prod/startServers?mykey=top
Admittedly, hard-coding the password isn't the best approach security-wise, but I think it's a fair compromise given the requirements.
Upvotes: 0
Reputation: 146
Yes you can. You should use a combination of AWS lambda and AWS api gateway. AWS api gateway (gw) takes care of exposing a http url and you can optionally let AWS api gateway handle the authentication using a custom authorizer.
Api gateway can trigger an AWS lambda function which will then run the actual code to start the instance.
Additional notes:
I hope this helps.
G.
Upvotes: 1
Reputation: 46859
Yes, for example here is a function that will start an instance:
import boto3
# Enter the region your instances are in, e.g. 'us-east-1'
region = 'XX-XXXXX-X'
# Enter your instances here: ex. ['X-XXXXXXXX', 'X-XXXXXXXX']
instances = ['X-XXXXXXXX']
def lambda_handler(event, context):
ec2 = boto3.client('ec2', region_name=region)
ec2.start_instances(InstanceIds=instances)
print 'started your instances: ' + str(instances)
once you create that Lambda function (similar to the above - from the link below), you can define an AWS API endpoint in AWS and have it call the lambda function.
This link may help with some of what you want to do (the lambda functions).
https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/
Upvotes: 3