【问题标题】:AWS Api-Gateway incorrect regionAWS Api-Gateway 区域不正确
【发布时间】:2017-03-30 13:33:45
【问题描述】:

我不完全确定我的aws api-gateway 设置有什么问题。我使用了两个区域,一个用于我的暂存 (eu-west-1) 环境,另一个用于我的实时 (us-east-1) 环境。

当我在 staging 中构建和运行我的 api 时,一切正常。但是,当我尝试实时运行我的 api 时,出现以下错误:

{"message": "Internal server error"}

为了尝试调试它,我使用 aws 控制台中的“测试”功能运行 API 并执行 GET 请求。令我惊讶的是,我注意到请求标头中的区域是错误的(eu-west-1 而不是 us-east-1)。测试还返回了以下带有 502 响应的消息:

{"Message":"Functions from 'us-east-1' are not reachable in this region ('eu-west-1')","Type":"User"}

这是否意味着我的 api 正在eu-west-1 区域中运行?

如果我在控制台中检查我的区域,我在运行测试时显然在us-east-1。我的 api-gateway uri 中的区域也是us-east-1

https://.execute-api.us-east-1.amazonaws.com/prod

我可以看到我的请求标头有:Host=lambda.eu-west-1.amazonaws.com 在输出中我有以下属性:

端点请求 URI:https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-东1::function:/invocations

我不知道为什么我的地区会混淆!我认为这可能与我的构建过程有关,但是在仔细检查了所有内容之后,我无法看到可能导致它的原因。我希望有一双新的眼睛能发现一些东西!

为了构建我的 api,我结合使用 swagger.yaml 文件和 cloudformation.json 文件。

招摇: 我在这个文件中有占位符,我在将文件发送到 aws 之前替换了运行节点脚本。

---
swagger: 2.0
info:
  title: ServerlessExpress
basePath: /YOUR_API_GATEWAY_STAGE
schemes:
- https
paths:
  /:
    x-amazon-apigateway-any-method:
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: 200
        uri: arn:aws:apigateway:YOUR_AWS_REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:YOUR_AWS_REGION:YOUR_ACCOUNT_ID:function:api-gateway-service/invocations
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
    options:
      consumes:
      - application/json
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
          headers:
            Access-Control-Allow-Origin:
              type: string
            Access-Control-Allow-Methods:
              type: string
            Access-Control-Allow-Headers:
              type: string
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: 200
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS,POST'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
        passthroughBehavior: when_no_match
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        type: mock
  /{proxy+}:
    x-amazon-apigateway-any-method:
      produces:
      - application/json
      parameters:
      - name: proxy
        in: path
        required: true
        type: string
      responses: {}
      x-amazon-apigateway-integration:
        uri: arn:aws:apigateway:YOUR_AWS_REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:YOUR_AWS_REGION:YOUR_ACCOUNT_ID:function:api-gateway-service/invocations
        httpMethod: POST
        type: aws_proxy
    options:
      consumes:
      - application/json
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
          headers:
            Access-Control-Allow-Origin:
              type: string
            Access-Control-Allow-Methods:
              type: string
            Access-Control-Allow-Headers:
              type: string
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: 200
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS,POST'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
        passthroughBehavior: when_no_match
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        type: mock
definitions:
  Empty:
    type: object
    title: Empty Schema

云:

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "AWS Serverless Express.",
    "Parameters": {
        "AwsServerlessExpressS3Bucket": {
            "Type": "String",
            "Description": "The S3 bucket in which the lambda function code is stored. Bucket names are region-unique, so you must change this."
        },
        "LambdaFunctionS3Key": {
            "Type": "String",
            "AllowedPattern": ".*\\.zip",
            "Description": "The S3 object for the lambda function code package.",
            "Default": "lambda-function.zip"
        },
        "ApiGatewaySwaggerS3Key": {
            "Type": "String",
            "AllowedPattern": ".*\\.yaml",
            "Description": "The S3 object for the swagger definition of the API Gateway API.",
            "Default": "simple-proxy-api.yaml"
        }
    },

    "Resources": {
        "ApiGatewayApi": {
            "Type": "AWS::ApiGateway::RestApi",
            "Properties": {
                "Description": "AWS Serverless Express API",
                "BodyS3Location": {
                    "Bucket": {
                        "Ref": "ServerlessExpressBucket"
                    },
                    "Key": {
                        "Ref": "ApiGatewaySwaggerS3Key"
                    }
                }
            }
        },

        "ApiGatewayApiDeployment": {
            "Type": "AWS::ApiGateway::Deployment",
            "Properties": {
                "RestApiId": {
                    "Ref": "ApiGatewayApi"
                },
                "StageName": "YOUR_API_GATEWAY_STAGE"
            }
        },

        "LambdaApiGatewayExecutionPermission": {
            "Type": "AWS::Lambda::Permission",
            "Properties": {
                "Action": "lambda:InvokeFunction",
                "FunctionName": {
                    "Fn::GetAtt": ["LambdaFunction", "Arn"]
                },
                "Principal": "apigateway.amazonaws.com",
                "SourceArn": {
                    "Fn::Join": ["", ["arn:aws:execute-api:", {
                        "Ref": "AWS::Region"
                    }, ":", {
                        "Ref": "AWS::AccountId"
                    }, ":", {
                        "Ref": "ApiGatewayApi"
                    }, "/*/*"]]
                }
            }
        },

        "LambdaFunction": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Code": {
                    "S3Bucket": {
                        "Ref": "ServerlessExpressBucket"
                    },
                    "S3Key": {
                        "Ref": "LambdaFunctionS3Key"
                    }
                },
                "FunctionName": "api-gateway-service",
                "Handler": "lambda.serverlessExpress",
                "Description": "Service running on api-gateway",
                "MemorySize": 128,
                "Role": {
                    "Fn::Join": ["", ["arn:aws:iam::", {
                        "Ref": "AWS::AccountId"
                    }, ":role/service-lambda"]]
                },
                "Runtime": "nodejs4.3",
                "Timeout": 30
            }
        }
    },

    "Outputs": {
        "LambdaFunctionConsoleUrl": {
            "Description": "Console URL for the Lambda Function.",
            "Value": {
                "Fn::Join": ["", ["https://", {
                    "Ref": "AWS::Region"
                }, ".console.aws.amazon.com/lambda/home?region=", {
                    "Ref": "AWS::Region"
                }, "#/functions/", {
                    "Ref": "LambdaFunction"
                }]]
            }
        },
        "ApiGatewayApiConsoleUrl": {
            "Description": "Console URL for the API Gateway API's Stage.",
            "Value": {
                "Fn::Join": ["", ["https://", {
                    "Ref": "AWS::Region"
                }, ".console.aws.amazon.com/apigateway/home?region=", {
                    "Ref": "AWS::Region"
                }, "#/apis/", {
                    "Ref": "ApiGatewayApi"
                }, "/stages/YOUR_API_GATEWAY_STAGE"]]
            }
        },
        "ApiUrl": {
            "Description": "Invoke URL for your API. Clicking this link will perform a GET request on the root resource of your API.",
            "Value": {
                "Fn::Join": ["", ["https://", {
                    "Ref": "ApiGatewayApi"
                }, ".execute-api.", {
                    "Ref": "AWS::Region"
                }, ".amazonaws.com/YOUR_API_GATEWAY_STAGE/"]]
            }
        }
    }
}

【问题讨论】:

    标签: api amazon-web-services lambda


    【解决方案1】:

    原来我手动创建了 api-gateway 调用的 lambda 函数。尽管 cloudformation 更新了此代码,但似乎在幕后发生了区域混淆。

    所以简而言之,只需删除 cloudformation 中的堆栈和我手动创建的 lambda 函数,重新运行构建并让 cloudformation 构建 lambda 函数即可解决问题!

    【讨论】:

    • 很好的侦探。这真的让我摸不着头脑,因为您似乎在描述一种本应不可能的情况。
    猜你喜欢
    • 1970-01-01
    • 2020-01-16
    • 2021-01-10
    • 1970-01-01
    • 2018-12-26
    • 2020-10-04
    • 2021-08-12
    • 2017-11-04
    • 2019-10-25
    相关资源
    最近更新 更多