Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Lambda function using Boto3 timeout

Tags:

I have solved my own question, but am posting it anyway in the hope of saving someone else a few hours!

I have a serverless project on AWS using Python to insert a record into a kinesis queue. However when I use boto3.client('kinesis') or the put_record function it seems to hang until it times out, with no error messages or other information. Below is the function:

import boto3

def put_record_kinesis(data, stream_name, partition_key):
    print "create kinesis begin"
    kinesis = boto3.client("kinesis")

    print "put record begin"
    response = kinesis.put_record(StreamName=stream_name, Data=data, PartitionKey=partition_key)
    print "put record complete"
    print response

The serverless.yml definition is a follows:

provider:
  name: aws
  runtime: python2.7
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DeleteNetworkInterface"
        - "kinesis:*"
      Resource: "*"

  vpc:
    securityGroupIds:
      - sg-...
    subnetIds:
      - subnet-...
      - subnet-...
      - subnet-...

  stage: dev
  region: eu-west-1
  memorySize: 128

functions:
  LambdaQueueFunction:
    handler: python_file.queue
    memorySize: 1024
    timeout: 100

  LambdaDequeueFunction:
    handler: python_file.dequeue

resources:
  Resources:
    KinesisQueue:
      Type: AWS::Kinesis::Stream
      Properties:
        Name: kinesis-queue
        ShardCount: 1
    ChronosQueueMap:
      Type: AWS::Lambda::EventSourceMapping
      DependsOn:
        - "LambdaDequeueFunctionLambdaFunction"
        - "IamPolicyLambdaExecution"
      Properties:
        BatchSize: 1
        EventSourceArn:
          Fn::GetAtt:
            - "KinesisQueue"
            - "Arn"
        FunctionName:
          Fn::GetAtt:
            - "LambdaDequeueFunctionLambdaFunction"
            - "Arn"
        StartingPosition: "TRIM_HORIZON"

When I run the function I see the following in cloud watch logs:

10:53:02 | START RequestId: 027bb0cb-acb4-11e6-b20c-1b587b734943 Version: $LATEST
10:53:02 | put records begin
10:54:42 | END RequestId: 027bb0cb-acb4-11e6-b20c-1b587b734943
10:54:42 | REPORT RequestId: 027bb0cb-acb4-11e6-b20c-1b587b734943   Duration: 100002.99 ms  Billed Duration: 100000 ms Memory Size: 1024 MB Max Memory Used: 22 MB
10:54:42 | 2016-11-17T10:54:42.155Z 027bb0cb-acb4-11e6-b20c-1b587b734943 Task timed out after 100.00 seconds

It turns out that the solution was that the lambda function did not have access to the internet. By default a lambda function not in a VPC has internet access, but a lambda function inside a VPC does not.

To fix this I created a new subnet, route table, elastic IP and nat gateway. They were configured as follows:

  • The nat gateway uses the elastic IP and points to any subnet with an internet gateway
  • The Route table has a route for local traffic (..0.0/16 | Local | Active) and a route for all other IP's to the nat gateway (0.0.0.0/0 | NAT ID | Active)
  • The is set to use the new route table.

Hope this helps someone!

like image 440
William Moore Avatar asked Nov 17 '16 11:11

William Moore


People also ask

Can you use Boto3 in Lambda?

You can run Python code in AWS Lambda. Lambda provides runtimes for Python that run your code to process events. Your code runs in an environment that includes the SDK for Python (Boto3), with credentials from an AWS Identity and Access Management (IAM) role that you manage.

Can we run Lambda more than 15 minutes?

Historically, the maximum execution timeout limit was 5 minutes. At the time of writing this article, AWS Lambda functions cannot run continuously for more than 15 minutes. This is a hard limit in the AWS Lambda service. In practice, there are use cases for which those 15 minutes are not enough.


1 Answers

It turns out that the solution was that the lambda function did not have access to the internet. By default a lambda function not in a VPC has internet access, but a lambda function inside a VPC does not.

To fix this I created a new subnet, route table, elastic IP and nat gateway. They were configured as follows:

  • The NAT gateway uses the elastic IP and points to any subnet with an internet gateway
  • The Route table has a route for local traffic (..0.0/16 | Local | Active) and a route for all other IP's to the NAT gateway (0.0.0.0/0 | NAT ID | Active)
  • The is set to use the new route table.

Hope this helps someone!

like image 115
William Moore Avatar answered Sep 26 '22 14:09

William Moore