26

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!

1

1 Answer 1

37

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!

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

8 Comments

How were you able to debug this? The silent "timeout" message isn't sufficient for me to figure out anything :-(
I used logging to work out which line the problem was happening on, then read up on the AWS documentation where I was that it needed the internet access to be able to access the kinesis queue and that lambda functions are not by default assigned an IP address.
Ah, thanks for clarifying that. So essentially some sleuthing is definitely required :-)
This gist is also very helpful
This plagued me for 2 days. silent timeout, debugging boto3 just showed multiple https requests open, no errors. Thank you so much for this!
|

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.