title: AWS Lambda function using Boto3 timeout
body: <p>I have solved my own question, but am posting it anyway in the hope of saving someone else a few hours!</p>
  
  <p>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:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>The serverless.yml definition is a follows:</p>
  
  <pre><code>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"
  </code></pre>
  
  <p>When I run the function I see the following in cloud watch logs:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>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.</p>
  
  <p>To fix this I created a new subnet, route table, elastic IP and nat gateway.  They were configured as follows:</p>
  
  <ul>
  <li>The nat gateway uses the elastic IP and points to any subnet with an internet gateway</li>
  <li>The Route table has a route for local traffic (<em>.</em>.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)</li>
  <li>The is set to use the new route table.</li>
  </ul>
  
  <p>Hope this helps someone!</p>