7

I want to allow users to start an EC2 instance only when it is needed.

So I created a Lambda function to do just that:

import boto3

def lambda_handler(event, context):
    ec2 = boto3.resource('ec2', region_name='eu-central-1')
    return ec2.instances.filter(InstanceIds=['i-abc123']).start()

I've also added the following IAM permissions:

    {
        "Effect": "Allow",
        "Action": [
            "ec2:StartInstances"
        ],
        "Resource": "arn:aws:ec2:*"
    },
    {
        "Effect": "Allow",
        "Action": [
            "ec2:DescribeInstances"
        ],
        "Resource": "*"
    }

Problem is that when I execute the Lambda I get timed out.

BTW running the exact same code from an EC2 within the same VPC and same permissions, returns immediately.

Any idea?

4
  • Did you enable VPC access for the Lambda function? Commented Apr 26, 2016 at 15:10
  • Did you setup a proper IAM roles + user in Lambda docs.aws.amazon.com/lambda/latest/dg/setting-up.html You may need to do chnage your resource arn to " "arn:aws:ec2:accoun-id:user-name" The lamdba script also need specific user credential to determine the resources. Commented Apr 26, 2016 at 16:08
  • I configured the VPC of the lambda to be the same as the EC2 instance. Commented Apr 26, 2016 at 16:50
  • I setup the proper IAM role. Not sure how to set the user of the Lambda? Commented Apr 26, 2016 at 16:55

2 Answers 2

3

If credentials were the problem, you would not get timeouts. More likely, you're using a small memory model, and boto takes lots of memory, even to do simple things. Try running with a larger memory model or longer timeout.

If this does turn out to be the issue, consider creating the ec2 resource in class initialization code or using a singleton pattern, so that subsequent invocations can use the same resource. However, be sure to set the function timeout so that it has enough time to do initialization as well as its normal duties, even if that doesn't seem to be necessary. If your function gets an error, the next run may include class init time.

Sign up to request clarification or add additional context in comments.

Comments

1

I was facing this exact same issue. My scenario had 1 lambda in a private subnet and 1 ec2 instance in the public subnet. And both these subnets inside the same VPC.

My security groups for both these resources allowed inbound and outbound traffic between themselves.

My lambda function calls ec2 functions like describeInstances(),startInstances(), stopInstances().

This code worked locally, but when deployed as a lambda function, it always threw function timeout error. I increased function timeout and memory but the issue didn't resolve.

Turns out you can't directly access/invoke/start/stop an ec2 instance from lambda function that is inside a VPC without access to the internet.

To solve this you need to either have a NAT Gateway/Instance or a VPC Endpoint.

The cheapest solution for small scale projects is to have a NAT instance that will allow your Lambda functions in private subnet to connect with internet. So for me spawning a NAT instance solved the timeout issue, and the ec2 instance invocation worked just fine from my Lambda function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.