AWS Api Gateway proxy resource using Cloudformation?

匿名 (未验证) 提交于 2019-12-03 01:38:01

问题:

I'm trying to proxy an S3 bucket configured as a website from an API Gateway endpoint. I configured an endpoint successfully using the console, but I am unable to recreate the configuration using Cloudformation.

After lots of trial and error and guessing, I've come up with the following CF stack template that gets me pretty close:

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 

Using this template I can successfully get the root of the bucket website, but the proxy resource gives me a 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"} 

I have no idea how to debug that 500.

To track down what may be wrong, I've compared the output of aws apigateway get-resource on the resource I created manually in the console (which is working) with the one Cloudformation made (which isn't). The resources look exactly alike. The output of get-method however, is subtly different, and I'm not sure it's possible to make them exactly the same using Cloudformation.

Working method configuration:

{   "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" } 

Configuration that doesn't work:

{     "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" } 

The differences:

  • The working configuration has responseTemplates set to "application/json": null. As far as I can tell, there's no way to set a mapping explicitly to null using Cloudformation. My CF method instead just has an empty object here.
  • My CF method has "responseParameters": {},, while the working configuration does not have responseParameters at all
  • My CF method has "requestModels": {},, while the working configuration does not have requestModels at all

Comparing the two in the console, they are seemingly exactly the same.

I'm at my wits end here: what am I doing wrong? Is this possible to achieve using Cloudformation?

回答1:

Answer: The above is correct. I had arrived at this solution through a series of steps, and re-applied the template over and over. Deleting the stack and deploying it anew with this configuration had the desired effect.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!