使用 Cloudformation 的 AWS Api Gateway 代理资源?

Posted

技术标签:

【中文标题】使用 Cloudformation 的 AWS Api Gateway 代理资源?【英文标题】:AWS Api Gateway proxy resource using Cloudformation? 【发布时间】:2018-05-25 05:52:46 【问题描述】:

我正在尝试从 API Gateway 端点代理配置为网站的 S3 存储桶。我使用控制台成功配置了端点,但无法使用 Cloudformation 重新创建配置。

经过大量的反复试验和猜测,我想出了以下 CF 堆栈模板,让我非常接近:

Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: ApiDocs

  Resource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      ParentId: !GetAtt Api.RootResourceId
      RestApiId: !Ref Api
      PathPart: 'proxy+'

  RootMethod:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      HttpMethod: ANY
      ResourceId: !GetAtt Api.RootResourceId
      RestApiId: !Ref Api
      AuthorizationType: NONE
      Integration:
        IntegrationHttpMethod: ANY
        Type: HTTP_PROXY
        Uri: 'http://my-bucket.s3-website-$AWS::Region.amazonaws.com/'
        PassthroughBehavior: WHEN_NO_MATCH
        IntegrationResponses:
          - StatusCode: 200

  ProxyMethod:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      HttpMethod: ANY
      ResourceId: !Ref Resource
      RestApiId: !Ref Api
      AuthorizationType: NONE
      RequestParameters:
        method.request.path.proxy: true
      Integration:
        CacheKeyParameters:
          - 'method.request.path.proxy'
        RequestParameters:
          integration.request.path.proxy: 'method.request.path.proxy'
        IntegrationHttpMethod: ANY
        Type: HTTP_PROXY
        Uri: 'http://my-bucket.s3-website-$AWS::Region.amazonaws.com/proxy'
        PassthroughBehavior: WHEN_NO_MATCH
        IntegrationResponses:
          - StatusCode: 200

  Deployment:
    DependsOn:
      - RootMethod
      - ProxyMethod
    Type: 'AWS::ApiGateway::Deployment'
    Properties:
      RestApiId: !Ref Api
      StageName: dev

使用这个模板我可以成功获取bucket网站的root,但是代理资源给了我一个500:

curl -i https://abcdef.execute-api.eu-west-1.amazonaws.com/dev/index.html
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Content-Length: 36
Connection: keep-alive
Date: Mon, 11 Dec 2017 16:36:02 GMT
x-amzn-RequestId: 6014a809-de91-11e7-95e4-dda6e24d156a
X-Cache: Error from cloudfront
Via: 1.1 8f6f9aba914cc74bcbbf3c57e10df26a.cloudfront.net (CloudFront)
X-Amz-Cf-Id: TlOCX3eemHfY0aiVk9MLCp4qFzUEn5I0QUTIPkh14o6-nh7YAfUn5Q==

"message": "Internal server error"

我不知道如何调试那个 500。

为了找出可能有问题的地方,我比较了我在控制台中手动创建的资源上的aws apigateway get-resource 的输出(正在运行)与 Cloudformation 制作的(不是)。资源看起来完全一样。但是,get-method 的输出略有不同,我不确定是否可以使用 Cloudformation 使它们完全相同。

工作方式配置:


  "apiKeyRequired": false,
  "httpMethod": "ANY",
  "methodIntegration": 
    "integrationResponses": 
      "200": 
        "responseTemplates": 
          "application/json": null
        ,
        "statusCode": "200"
      
    ,
    "passthroughBehavior": "WHEN_NO_MATCH",
    "cacheKeyParameters": [
      "method.request.path.proxy"
    ],
    "requestParameters": 
      "integration.request.path.proxy": "method.request.path.proxy"
    ,
    "uri": "http://muybucket.s3-website-eu-west-1.amazonaws.com/proxy",
    "httpMethod": "ANY",
    "cacheNamespace": "abcdefg",
    "type": "HTTP_PROXY"
  ,
  "requestParameters": 
    "method.request.path.proxy": true
  ,
  "authorizationType": "NONE"

不起作用的配置:


    "apiKeyRequired": false,
    "httpMethod": "ANY",
    "methodIntegration": 
        "integrationResponses": 
            "200": 
                "responseParameters": ,
                "responseTemplates": ,
                "statusCode": "200"
            
        ,
        "passthroughBehavior": "WHEN_NO_MATCH",
        "cacheKeyParameters": [
            "method.request.path.proxy"
        ],
        "requestParameters": 
            "integration.request.path.proxy": "method.request.path.proxy"
        ,
        "uri": "http://mybucket.s3-website-eu-west-1.amazonaws.com/proxy",
        "httpMethod": "ANY",
        "requestTemplates": ,
        "cacheNamespace": "abcdef",
        "type": "HTTP_PROXY"
    ,
    "requestParameters": 
        "method.request.path.proxy": true
    ,
    "requestModels": ,
    "authorizationType": "NONE"

区别:

工作配置将responseTemplates 设置为"application/json": null。据我所知,没有办法使用 Cloudformation 将映射显式设置为null。我的 CF 方法在这里只有一个空对象。 我的CF方法有"responseParameters": ,,而工作配置根本没有responseParameters 我的CF方法有"requestModels": ,,而工作配置根本没有requestModels

在控制台中比较两者,它们看起来完全一样。

我在这里束手无策:我做错了什么?这可以使用 Cloudformation 实现吗?

【问题讨论】:

您是否尝试过在 API Gateway 控制台中为您的 API 开启详细日志记录?也许它可以给你更多的细节。 嗯,所以我删除了我的堆栈并再次从头开始,现在它可以工作了。所以我想通过一堆小的调整从我的起点到这个并没有真正奏效。实在不能称得上。无论如何,这篇文章现在记录了设置它的正确方法:) 【参考方案1】:

答案:以上是正确的。我通过一系列步骤得出了这个解决方案,并一遍又一遍地重新应用模板。删除堆栈并使用此配置重新部署它具有预期的效果。

【讨论】:

这是因为对现有 API 网关的任何更新都需要您重新部署 API 网关 - 即使在使用 CloudFormation 时也是如此。 CloudFormation 只会部署全新的 API。

以上是关于使用 Cloudformation 的 AWS Api Gateway 代理资源?的主要内容,如果未能解决你的问题,请参考以下文章

AWS CloudFormation 可以调用 AWS API 吗?

有没有办法使用 cloudformation 修改 AWS 现有资源?

通过 cloudformation 使用 aws `cdk synth` 输出

如何修复与 AWS::CloudFormation::Init 一起创建 EC2 的 cloudformation 模板

使用 AWS CLI 将现有资源导入 CloudFormation

AWS 中的 cloudformation 最佳实践