SAM CLI 在 VPC 和无服务器 api 网关中部署 lambdas

问题描述 投票:0回答:1

我正在尝试在 VPC 的私有子网中创建 2 个 lambda 函数,lambda 将从 API 网关调用。

api 网关将有几条通往 lambda 的路径。

我创建了 2 个 VPC 端点,一个用于 lambda 调用 Secrets Manager,其中存储了对 RDS Aurora 的用户和密码访问权限,另一个用于 api 网关的 VPC 端点,因此它可以调用 lambda 函数。

我面临的问题是我收到错误消息:

{ "message": "Internal server error" }
尝试请求我的 API 网关时。

我的 lambda 函数似乎甚至没有被请求,当我在 AWS 控制台中使用测试按钮手动请求它时,它工作并生成日志,但是在我的机器上使用邮递员从 API 网关调用,只返回错误,lambda 函数不生成日志,网关日志也没有告诉我太多信息。来自网关的日志示例:

{
    "requestId": "id",
    "ip": "ipv4",
    "caller": "-",
    "user": "-",
    "requestTime": "31/Mar/2023:15:47:35 +0000",
    "httpMethod": "GET",
    "resourcePath": "/{database_name}/{table_name}",
    "status": "500",
    "protocol": "HTTP/1.1",
    "responseLength": "36"
}

这是我当前使用 SAM CLI 部署所有服务的 main.yaml 文件:

Resources:
  DcpBackendReaderRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: DcpBackendReaderRole
      Tags:
        - Key: "env"
          Value: "3"
        - Key: "serviceGroup"
          Value: "2"
        - Key: "owner"
          Value: "1"
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
        - arn:aws:iam::aws:policy/service-role/AWSLambdaRole
      Policies:
        - PolicyName: SecretsManagerReadAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - secretsmanager:GetSecretValue
                Resource: !Sub 'arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:secrets/manager/key/for/user/and/pss-*'
        - PolicyName: KMSDecryptAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - kms:Decrypt
                Resource: !Sub 'arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/key-id'

  DcpBackendWriterRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: DcpBackendWriterRole
      Tags:
        - Key: "env"
          Value: "3"
        - Key: "serviceGroup"
          Value: "2"
        - Key: "owner"
          Value: "1"
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
        - arn:aws:iam::aws:policy/service-role/AWSLambdaRole
      Policies:
        - PolicyName: SecretsManagerReadAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - secretsmanager:GetSecretValue
                Resource: !Sub 'arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:secrets/manager/key/for/user/and/pss-*'
        - PolicyName: KMSDecryptAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - kms:Decrypt
                Resource: !Sub 'arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/key-id'

  DcpDbManagementLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: DCP-Database-Management
      Description: DCP Database Management Layer
      ContentUri: layers/dcp-db-management/
      CompatibleRuntimes:
        - python3.9
      RetentionPolicy: Retain

  DcpApiGatewayLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub '/aws/apigateway/${DcpServerlessApiGtw}'
      RetentionInDays: 14

  DcpBackendReaderFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: DcpBackendReader
      Handler: lambda-function.lambda_handler
      Runtime: python3.9
      CodeUri: src/dcpBackendReader/
      Description: Lambda function for reading from the database
      Tags:
        env: "3"
        serviceGroup: "2"
        owner: "1"
      MemorySize: 128
      Timeout: 15
      Layers:
        - !Ref DcpDbManagementLayer
        - arn:aws:lambda:us-east-1:acc-id:layer:pymysql:1
      Role: !GetAtt DcpBackendReaderRole.Arn
      VpcConfig:
        SecurityGroupIds:
          - sg-123456789xxxxxxxx
        SubnetIds:
          - subnet-0012345678910xxxx
          - subnet-00123456789xxxxxx
      Environment:
        Variables:
          DB_HOST: aurora-host.us-east-1.rds.amazonaws.com
          SM_DNS: https://vpce-12345678910111213x-12345678.secretsmanager.us-east-1.vpce.amazonaws.com
          DB_SM_KEY: secrets/manager/key/for/user/and/pss
          DB_SM_REGION: us-east-1

  DcpBackendWriterFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: DcpBackendWriter
      Handler: lambda-function.lambda_handler
      Runtime: python3.9
      CodeUri: src/dcpBackendWriter/
      Description: Lambda function for writing to the database
      Tags:
        env: "3"
        serviceGroup: "2"
        owner: "1"
      MemorySize: 128
      Timeout: 15
      Layers:
        - !Ref DcpDbManagementLayer
        - arn:aws:lambda:us-east-1:acc-id:layer:pymysql:1
      Role: !GetAtt DcpBackendWriterRole.Arn
      VpcConfig:
        SecurityGroupIds:
          - sg-123456789xxxxxxxx
        SubnetIds:
          - subnet-0012345678910xxxx
          - subnet-00123456789xxxxxx
      Environment:
        Variables:
          DB_HOST: aurora-host.us-east-1.rds.amazonaws.com
          SM_DNS: https://vpce-12345678910111213x-12345678.secretsmanager.us-east-1.vpce.amazonaws.com
          DB_SM_KEY: secrets/manager/key/for/user/and/pss
          DB_SM_REGION: us-east-1

  DcpServerlessApiGtw:
    Type: AWS::Serverless::Api
    Properties:
      Name: DcpServerlessApiGtw
      StageName: prod
      MethodSettings:
        - ResourcePath: '/*'
          HttpMethod: '*'
          LoggingLevel: INFO
          DataTraceEnabled: true
          MetricsEnabled: true
      AccessLogSetting:
        Format: '{ "requestId":"$context.requestId", "ip": "$context.identity.sourceIp", "caller":"$context.identity.caller", "user":"$context.identity.user", "requestTime":"$context.requestTime", "httpMethod":"$context.httpMethod", "resourcePath":"$context.resourcePath", "status":"$context.status", "protocol":"$context.protocol", "responseLength":"$context.responseLength" }'
        DestinationArn: !GetAtt DcpApiGatewayLogGroup.Arn
      DefinitionBody:
        openapi: 3.0.1
        info:
          title: DCP API Gateway
          version: '1.0'
        Policy:
          Statement:
            - Effect: Allow
              Principal:
                Service: apigateway.amazonaws.com
              Action: lambda:InvokeFunction
              Resource:
                - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:DcpBackendReader'
                - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:DcpBackendWriter'
              Condition:
                StringEquals:
                  aws:SourceDomain: https://vpce-12345678910111213x-12345678.execute-api.us-east-1.vpce.amazonaws.com
        paths:
          /{database_name}/{table_name}:
            get:
              x-amazon-apigateway-integration:
                httpMethod: GET
                type: aws_proxy
                uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DcpBackendReaderFunction.Arn}/invocations
              responses: {}
            post:
              x-amazon-apigateway-integration:
                httpMethod: POST
                type: aws_proxy
                uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DcpBackendWriterFunction.Arn}/invocations
              responses: {}
            put:
              x-amazon-apigateway-integration:
                httpMethod: PUT
                type: aws_proxy
                uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DcpBackendWriterFunction.Arn}/invocations
              responses: {}
          /{database_name}/{table_name}/{id}:
            get:
              x-amazon-apigateway-integration:
                httpMethod: GET
                type: aws_proxy
                uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DcpBackendReaderFunction.Arn}/invocations
              responses: {}
            delete:
              x-amazon-apigateway-integration:
                httpMethod: DELETE
                type: aws_proxy
                uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${DcpBackendWriterFunction.Arn}/invocations
              responses: {}

Outputs:
  DcpDbManagementLayerVersion:
    Description: DCP Database Management Layer version ARN
    Value: !Ref DcpDbManagementLayer

  DcpServerlessApiGtwUrl:
    Description: DCP API Gateway URL
    Value: !Sub https://${DcpServerlessApiGtw}.execute-api.${AWS::Region}.amazonaws.com/prod`

基本上尝试了上面提到的所有内容,但什么都没有,为什么这不起作用的任何想法?

我没有使用最佳实践,因为我仍将更新安全规则并实施身份验证,目前此应用程序没有任何敏感数据,我只是想部署它并测试基础是否有效,但事实并非如此:(

amazon-web-services aws-lambda aws-api-gateway amazon-vpc
1个回答
0
投票

你的

httpMethod
对象中的
x-amazon-apigateway-integration
必须始终是
POST
.

这是 API 网关与您的数据源而非您的客户端之间集成的动词。

集成请求中使用的 HTTP 方法。对于 Lambda 函数调用,该值必须是 POST。

GET
PUT
DELETE
替换为
POST

在此文档页面中查找

httpMethod

https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions-integration.html

© www.soinside.com 2019 - 2024. All rights reserved.