【问题标题】:Lambda invoke Lambda via API GatewayLambda 通过 API Gateway 调用 Lambda
【发布时间】:2018-09-13 08:59:34
【问题描述】:

我似乎无法让它工作。我通过 C9 创建了 2 个 lambda。我正在使用 boto3 从另一个调用一个 lambda。通过 C9 似乎一切正常,但是当我发布并尝试通过 API Gateway 访问时,我不断收到“端点请求超时”错误。

我知道这不可能是超时问题,因为我已经设置了我的 yaml 文件以便有足够的时间来执行,并且现在的 lambda 非常简单(只返回一个字符串)

这是我当前的 yaml 文件。我想知道是否可能需要在第二个 yaml 中为 API Gateway 添加某种权限

Lambda1

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Resources:
    api:
        Type: 'AWS::Serverless::Function'
        Properties:
        Description: ''
        Handler: api/lambda_function.lambda_handler
        MemorySize: 256
        Role: 'arn:aws:iam::820788395625:role/service-role/api_int-role'
        Runtime: python3.6
        Timeout: 30
        VpcConfig:
            SecurityGroupIds:
                - ...
            SubnetIds:
                - ...
        Policies: AWSLambdaFullAccess

Lambda2

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Resources:
    api:
        Type: 'AWS::Serverless::Function'
        Properties:
            Description: ''
            Handler: api/lambda_function.lambda_handler
            MemorySize: 512
            Role: 'arn:aws:iam::820788395625:role/service-role/api_int-role'
            Runtime: python3.6
            Timeout: 15
            VpcConfig:
                SecurityGroupIds:
                    - ...
                SubnetIds:
                    - ...

我刚刚将一个 API Gateway 端点直接设置为 Lambda2,它没有返回任何问题。所以...

API 网关 -> Lambda 2(有效) API 网关 -> Lambda 1 -> Lambda 2(不起作用)

因此,由于某种原因,当我想通过 API 网关通过 Lambda 1 调用 Lambda 2 时,它不起作用。

这是调用第二个 Lambda 的代码

import json
import boto3

def lambda_handler(event, context):
    print('call boto3 client')
    lambda_client = boto3.client('lambda', region_name='us-east-1')
    print('boto3 client called')

    print('invoke lambda')
    env_response = lambda_client.invoke(
        FunctionName='cloud9-apiAlpha-api-TBSOYXLVBCLX',
        InvocationType='RequestResponse',
        Payload=json.dumps(event)
    )
    print('lambda invoked')

    print('env_response')
    print(env_response)
    print(env_response['Payload'])
    print(env_response['Payload'].read())

    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json', 
            'Access-Control-Allow-Methods': 'POST,GET,OPTIONS,PUT,DELETE',
            'Access-Control-Allow-Origin': '*'
        },
        'body': 'HELLO WORLD!',
        'isBase64Encoded': False
    }

现在,当我查看日志时,它会打印('invoke lambda'),但随后会停止并超时

【问题讨论】:

  • 您的角色是否具有执行另一个 lambda 的适当权限? api_int-role
  • 你能告诉我们你如何调用 lambda 的实际代码吗?
  • @AminAhmedKhan 我被告知该角色有权执行另一个 lambda
  • @yorodm 我已经分享了调用第二个 Lambda 的代码
  • 如果您遇到超时问题,那么您可以异步调用 lambda 或增加调用 lambda 的超时阈值

标签: amazon-web-services aws-lambda boto3


【解决方案1】:

1.如果没有一些配置,就无法从另一个 Lambda 调用 Lambda。在您的 .yml 文件中,必须指定权限才能调用另一个 Lambda。这可以通过在 provider 属性下添加 iamRoleStatements 部分来完成 or 通过将简单策略 AWSLambdaRole 添加到附加到 lambda function_1 的现有角色中。

provider:  
    name: aws
    runtime: <runtime goes here> # e.g. python3.6 or nodejs6.10
    iamRoleStatements:
      - Effect: Allow
        Action:
          - lambda:InvokeFunction
        Resource: "*" 

or do this add/attach this policy to your existing role attached to your lambda function_1

2.调用lambda function_1附加代码。

global LAMBDA_CLIENT
if not LAMBDA_CLIENT:
    LAMBDA_CLIENT = boto3.client('lambda')
try:
    encoded_payload = json.dumps({'message': 'this is an invokcation call form lambda_1'}).encode(UTF_8)

    invoke_resp = lambda_client.invoke(
        FunctionName='function_2',
        InvocationType='RequestResponse',
        Payload=encoded_payload)

    status_code = invoke_resp['StatusCode']
    if status_code != 200:
        LOGGER.error('error ')
    paylaod = invoke_resp['Payload'].read()
    resp = json.loads(payload)
    print(resp)
except Exception:

如果您使用 InvocationType=RequestResponse,那么您可以返回一些响应表单 function_2。

【讨论】:

  • 我在 C9 中创建了这个,并且有一个 template.yml,那我还需要一个 serverless.yml 吗?
  • 我认为您的 lambda 附加了一个现有角色,那么值得将此策略 AWSLambdaRole 附加到它。因此,在您的情况下,您不需要对 .yml 文件进行任何更改,如果我无法正确解释内容,我们深表歉意
  • 某处必须有权限,因为在日志中它会到达 invoke_resp = lambda_client.invoke 然后挂起并最终超时
  • 好的,看起来这样做让它工作了 Payload=bytes(encoded_pa​​yload)
  • 不错的json.loads()应该这样做
【解决方案2】:

终于找到了解决办法。我的特定问题的答案是 Lambda 1 和 Lambda 2 在 VPC 上运行,因此没有互联网连接。一旦我从 Lambda 1 中删除了 VPC,Lambda 2 的调用就没有任何问题。

只是想分享一下,以防我可以为其他人节省一周的调试时间 LOL

【讨论】:

    猜你喜欢
    • 2019-01-07
    • 1970-01-01
    • 2017-04-13
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    • 2017-12-07
    • 2019-04-17
    • 2018-11-09
    相关资源
    最近更新 更多