簡體   English   中英

如何使用 AWS_PROXY 模式通過 API Gateway 和 CloudFront 通過 AWS Lambda 返回二進制內容?

[英]How can one return binary content via AWS Lambda through API Gateway and CloudFront using AWS_PROXY mode?

如何使用AWS_PROXY使用AWS_PROXY集成類型AWS_PROXY由 CloudFront 前置(以便我可以進行 HTTP 到 HTTPS 重定向)並由 AWS Lambda 函數支持的 AWS API 網關?

下面是一個 CloudFormation 模板,顯示了我嘗試過的內容。 這包括

  • 一個簡單的 Lambda 函數,它返回AWS_PROXY模式下 Lambda 的預期輸出格式
    • 這將isBase64Encoded設置為 True。
  • 一個AWS::ApiGateway::RestApi資源,其中包含一個BinaryMediaTypes屬性,該屬性的值為*~1*
    • 此 AWS 文檔頁面中建議將二進制媒體類型設置為*/* ,並且CloudFormation 文檔說明Slashes must be escaped with ~1. For example, image/png would be image~1png in the BinaryMediaTypes list Slashes must be escaped with ~1. For example, image/png would be image~1png in the BinaryMediaTypes list

我已經閱讀了這篇 AWS 論壇帖子、 AWS_PROXY 和二進制響應,但還沒有弄清楚我做錯了什么。 論壇帖子包括發布有關AWS_PROXY模式以及其他模式的人,因此有點令人困惑。

這AWS文檔頁面, Support Binary Payloads in API Gateway ,是的,我相信,談論比其他模式AWS_PROXY因為它談論設置IntegrationResponses需要使用屬性的StatusCode其匹配的MethodResponse的StatusCode。

這是一個展示問題的 CloudFormation 模板。 您可以通過這些步驟重現它

  1. 為您賬戶中現有 Route53 區域中的 DNS 域名提供 ACM 證書
  2. 將域名、區域名稱(以“.”字符結尾)和 ACM ARN 作為參數提供給 CloudFormation 堆棧
  3. 使用下面的模板啟動 CloudFormation 堆棧(因為它使用 CloudFront,這可能需要 30 分鍾)
  4. curl API 網關的 URL

如果這正常工作,您將返回二進制 png HTTP 響應,而不是返回 base64 響應。

AWSTemplateFormatVersion: 2010-09-09
Description: Test binary responses with AWS_PROXY mode
Parameters:
  CustomDomainName:
    Type: String
    Description: The custom domain name to use for the API
    Default: ''
    # AWS::ApiGateway::DomainName can not contain any uppercase characters
    AllowedPattern: '^[^A-Z]*$'
    ConstraintDescription: must not contain any uppercase characters
  DomainNameZone:
    Type: String
    Description: The Route53 DNS zone containing the custom domain name
    Default: ''
  CertificateArn:
    Type: String
    Description: The ARN of the AWS ACM Certificate for your custom domain name
    Default: ''
Resources:
  TestFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: AllowLambdaLogging
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: '*'
  TestFunction:
    Type: AWS::Lambda::Function
    Properties:
      Description: Test Function
      Code:
        ZipFile: |
          def lambda_handler(event, context):
            body = 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAKCAYAAABSfLWiAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA0gAAANIBBp0MHQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHgSURBVCiRlY47aFNxGEfP97/p05SWYhXfEHMjNZobuChYk1iwUCKKiqSjj0XpIM46uDgUQdxqk0lUHJwsiEPtoEmtgxhMIx2StFJBhA4tOCTVPO7n0C5uesbDj8NPAEJO4oXCLqDHU3PbktYJhM/lwty07SRmEHlQKWRn7Uh8VlRvqDFpoEdgo7yQO+0DqP80V1ZW3v0KOcMxI95dMFOqnD8YGfoAckCUZMCNlWhKvxoGxaNWLuZGAQUQwNhOfEJFjhqPugo7u7RzZEN+50HvgO4R5KKKPkVlb9VXfbit5X+Cp2FBn5WLc/dNyBkeAkksFXJnWurdA6xi8U0VqIBc89R6q0hVPLmgtF7+yOdrlUI2ZdXb4hhzKRQ95frENL6qZ+2zo/FHqHQAA6RSlpZWp0WYWC5mF4NO4j3C1aWF+UXbiZ0VZKxFo4pitTcbywAE3JHeQDRhAxIOh9vZxITDw34A13Xbdrtu95Yn4Mb2HzoSjwSDyQ4A0SlOyjjz/Af6mE7q3AQGgW4D1DTDc01zWTP0/lPlG02ULxgmUfoEQCfx4+MWMI5SQvi0NVpDWcejC6EfsBGOA4cR0vh4RZNz8tfNzVgSYRTlGLADGADWge/AR4QZ+ngtY9Q1w3aus/YHPCW0c1bW92YAAAAASUVORK5CYII='
            return {
              'headers': {'Content-Type': 'image/png'},
              'statusCode': 200,
              'isBase64Encoded': True,
              'body': body}
      Handler: index.lambda_handler
      Runtime: python3.7
      Role: !GetAtt TestFunctionRole.Arn
      Timeout: 900
  TestFunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      # Let's hope that the Lambda function doesn't execute before this LogGroup
      # resource is created, creating the LogGroup with no expiration and
      # preventing this resource from creating
      LogGroupName: !Join [ '/', ['/aws/lambda', !Ref 'TestFunction' ] ]
      RetentionInDays: 1
  TestRoute53RecordSet:
    Type: AWS::Route53::RecordSet
    Properties:
      AliasTarget:
        DNSName: !GetAtt TestCloudFrontDistribution.DomainName
        HostedZoneId: Z2FDTNDATAQYW2  # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget-1.html
      Comment: Bind the custom domain name to the Test CloudFront fronted API Gateway
      HostedZoneName: !Ref DomainNameZone
      Name: !Ref CustomDomainName
      Type: A
  TestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: Test
      BinaryMediaTypes:
        - '*~1*'
      Description: Test API
      FailOnWarnings: true
      EndpointConfiguration:
        Types:
          - REGIONAL
  TestApiGatewayDomainName:
    # The ApiGateway requires a custom domain name, despite sitting behind
    # CloudFront. This is because we want to pass all ( * ) HTTP headers
    # through CloudFront and onto API Gateway. If we didn't set a custom domain
    # name on the API Gateway, the "Host" header passed through from CloudFront
    # to API Gateway would be for the custom domain, but API Gateway, which uses
    # SNI, wouldn't know which TLS certificate to use in the handshake because
    # API Gateway would have no record of that Host header. This would result in
    # API Gateway being unable to setup a TLS connection with the inbound
    # CloudFront connection attempt, API Gateway writing no logs about this
    # fact, and CloudFront returning to the user an error of
    # {"message":"Forbidden"}
    # If we weren't passing the "Host" header from CloudFront to API Gateway
    # this resource wouldn't be needed
    Type: AWS::ApiGateway::DomainName
    Properties:
      # Uppercase letters are not supported in DomainName
      DomainName: !Ref CustomDomainName
      EndpointConfiguration:
        Types:
          - REGIONAL
      RegionalCertificateArn: !Ref CertificateArn
      SecurityPolicy: TLS_1_2
  TestBasePathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Properties:
      # BasePath:   # Not specifying this so that we have no base path
      DomainName: !Ref TestApiGatewayDomainName
      RestApiId: !Ref TestApi
      Stage: !Ref TestApiStage
  TestLambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:invokeFunction
      FunctionName: !GetAtt TestFunction.Arn
      Principal: apigateway.amazonaws.com
      SourceArn: !Join [ '', [ 'arn:aws:execute-api:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref 'TestApi', '/*/*' ] ]
  TestApiStage:
    Type: AWS::ApiGateway::Stage
    Properties:
      DeploymentId: !Ref TestApiDeployment
      MethodSettings:
        - DataTraceEnabled: true
          HttpMethod: '*'
          ResourcePath: /*
      RestApiId: !Ref TestApi
  TestApiDeployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn:
      - TestRequest
    Properties:
      RestApiId: !Ref TestApi
      StageName: DummyStage
      # Deployment with an Empty Embedded Stage
      # The following instructional text is no longer present in the AWS
      # documentation for AWS::ApiGateway::Deployment StageName and it's not
      # clear if it still applies.
      #
      # "Note This property is required by API Gateway. We recommend that you
      # specify a name using any value (see Examples) and that you don’t use
      # this stage. We recommend not using this stage because it is tied to
      # this deployment, which means you can’t delete one without deleting the
      # other. For example, if you delete this deployment, API Gateway also
      # deletes this stage, which you might want to keep. Instead, use the
      # AWS::ApiGateway::Stage resource to create and associate a stage with
      # this deployment."
  TestResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: !Ref TestApi
      ParentId: !GetAtt TestApi.RootResourceId
      PathPart: '{proxy+}'
  TestRequest:
    DependsOn: TestLambdaPermission
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      Integration:
        Type: AWS_PROXY
        # IntegrationHttpMethod is POST regardless of the HttpMethod for this resource
        # https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
        # "For Lambda integrations, you must use the HTTP method of POST for the
        # integration request, according to the specification of the Lambda service
        # action for function invocations."
        IntegrationHttpMethod: POST
        Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
      ResourceId: !Ref TestResource
      RestApiId: !Ref TestApi
  TestPOSTRequest:
    DependsOn: TestLambdaPermission
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: POST
      Integration:
        Type: AWS_PROXY
        # https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
        # "For Lambda integrations, you must use the HTTP method of POST for the
        # integration request, according to the specification of the Lambda service
        # action for function invocations."
        IntegrationHttpMethod: POST
        Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
      ResourceId: !Ref TestResource
      RestApiId: !Ref TestApi
  TestRootRequest:
    # This resource is necessary to get API Gateway to respond to requests for the '/' path
    # Without it API Gateway will respond to requests for '/' with the error
    # {"message":"Missing Authentication Token"}
    # https://stackoverflow.com/q/46578615/168874
    # https://stackoverflow.com/q/52909329/168874
    DependsOn: TestLambdaPermission
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      Integration:
        Type: AWS_PROXY
        # IntegrationHttpMethod is POST regardless of the HttpMethod for this resource
        # https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
        # "For Lambda integrations, you must use the HTTP method of POST for the
        # integration request, according to the specification of the Lambda service
        # action for function invocations."
        IntegrationHttpMethod: POST
        Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
      # ResourceId must use the RootResourceId attribute of the AWS::ApiGateway::RestApi
      # https://stackoverflow.com/a/56121914/168874
      ResourceId: !GetAtt TestApi.RootResourceId
      RestApiId: !Ref TestApi
  TestCloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Comment: !Join [ ':', [!Ref 'AWS::StackName', 'Test']]
        DefaultCacheBehavior:
          AllowedMethods:
            - GET
            - HEAD
            - POST
            - DELETE
            - OPTIONS
            - PUT
            - PATCH
          Compress: true
          DefaultTTL: 0
          MinTTL: 0
          MaxTTL: 0
          ForwardedValues:
            Cookies:
              Forward: all
            QueryString: true
            Headers:
              - '*'
          TargetOriginId: TestCloudFrontOriginId
          ViewerProtocolPolicy: redirect-to-https
        # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-defaultrootobject
        DefaultRootObject: ''  # "If you don't want to specify a default root object when you create a distribution, include an empty DefaultRootObject element."
        Enabled: true
        Aliases:
          - !Ref CustomDomainName
        HttpVersion: http2
        IPV6Enabled: true
        #Logging:
        #  Logging
        Origins:
          - CustomOriginConfig:
              OriginProtocolPolicy: https-only
              OriginSSLProtocols:
                - TLSv1.2
            DomainName: !GetAtt TestApiGatewayDomainName.RegionalDomainName
            Id: TestCloudFrontOriginId
            # OriginPath: !Join [ '', [ '/', !Ref 'TestApiStage' ] ]
        PriceClass: PriceClass_100  # US, Canada, Europe, Israel
        ViewerCertificate:
          AcmCertificateArn: !Ref CertificateArn
          MinimumProtocolVersion: TLSv1.2_2018
          SslSupportMethod: sni-only

我聯系了 AWS Support,經過多次來回發現問題出在 AWS 文檔中。

AWS::ApiGateway::RestApi資源類型上的文檔頁面錯誤地說明

斜線必須用 ~1 轉義。 例如,在 BinaryMediaTypes 列表中,image/png 將是 image~1png。

事實證明這不是真的,您應該在BinaryMediaTypes字段中輸入的BinaryMediaTypes*/*而不是*~1* 這使字段看起來像這樣

Resources:
  TestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: Test
      BinaryMediaTypes:
        - '*/*'

因此,通過對問題中的模板進行更改,生成的堆棧可以正確提供二進制資源。

我已經確認這個 AWS 文檔頁面Support Binary Payloads in API Gateway確實在談論AWS_PROXY以外的AWS_PROXY ,不適用於我的問題。

我已經確認有效的修復模板是這個

AWSTemplateFormatVersion: 2010-09-09
Description: Test binary responses with AWS_PROXY mode
Parameters:
  CustomDomainName:
    Type: String
    Description: The custom domain name to use for the API
    Default: ''
    # AWS::ApiGateway::DomainName can not contain any uppercase characters
    AllowedPattern: '^[^A-Z]*$'
    ConstraintDescription: must not contain any uppercase characters
  DomainNameZone:
    Type: String
    Description: The Route53 DNS zone containing the custom domain name
    Default: ''
  CertificateArn:
    Type: String
    Description: The ARN of the AWS ACM Certificate for your custom domain name
    Default: ''
Resources:
  TestFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: AllowLambdaLogging
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: '*'
  TestFunction:
    Type: AWS::Lambda::Function
    Properties:
      Description: Test Function
      Code:
        ZipFile: |
          def lambda_handler(event, context):
            body = 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAKCAYAAABSfLWiAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA0gAAANIBBp0MHQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHgSURBVCiRlY47aFNxGEfP97/p05SWYhXfEHMjNZobuChYk1iwUCKKiqSjj0XpIM46uDgUQdxqk0lUHJwsiEPtoEmtgxhMIx2StFJBhA4tOCTVPO7n0C5uesbDj8NPAEJO4oXCLqDHU3PbktYJhM/lwty07SRmEHlQKWRn7Uh8VlRvqDFpoEdgo7yQO+0DqP80V1ZW3v0KOcMxI95dMFOqnD8YGfoAckCUZMCNlWhKvxoGxaNWLuZGAQUQwNhOfEJFjhqPugo7u7RzZEN+50HvgO4R5KKKPkVlb9VXfbit5X+Cp2FBn5WLc/dNyBkeAkksFXJnWurdA6xi8U0VqIBc89R6q0hVPLmgtF7+yOdrlUI2ZdXb4hhzKRQ95frENL6qZ+2zo/FHqHQAA6RSlpZWp0WYWC5mF4NO4j3C1aWF+UXbiZ0VZKxFo4pitTcbywAE3JHeQDRhAxIOh9vZxITDw34A13Xbdrtu95Yn4Mb2HzoSjwSDyQ4A0SlOyjjz/Af6mE7q3AQGgW4D1DTDc01zWTP0/lPlG02ULxgmUfoEQCfx4+MWMI5SQvi0NVpDWcejC6EfsBGOA4cR0vh4RZNz8tfNzVgSYRTlGLADGADWge/AR4QZ+ngtY9Q1w3aus/YHPCW0c1bW92YAAAAASUVORK5CYII='
            return {
              'headers': {'Content-Type': 'image/png'},
              'statusCode': 200,
              'isBase64Encoded': True,
              'body': body}
      Handler: index.lambda_handler
      Runtime: python3.7
      Role: !GetAtt TestFunctionRole.Arn
      Timeout: 900
  TestFunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      # Let's hope that the Lambda function doesn't execute before this LogGroup
      # resource is created, creating the LogGroup with no expiration and
      # preventing this resource from creating
      LogGroupName: !Join [ '/', ['/aws/lambda', !Ref 'TestFunction' ] ]
      RetentionInDays: 1
  TestRoute53RecordSet:
    Type: AWS::Route53::RecordSet
    Properties:
      AliasTarget:
        DNSName: !GetAtt TestCloudFrontDistribution.DomainName
        HostedZoneId: Z2FDTNDATAQYW2  # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget-1.html
      Comment: Bind the custom domain name to the Test CloudFront fronted API Gateway
      HostedZoneName: !Ref DomainNameZone
      Name: !Ref CustomDomainName
      Type: A
  TestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: Test
      BinaryMediaTypes:
        - '*/*'
      Description: Test API
      FailOnWarnings: true
      EndpointConfiguration:
        Types:
          - REGIONAL
  TestApiGatewayDomainName:
    # The ApiGateway requires a custom domain name, despite sitting behind
    # CloudFront. This is because we want to pass all ( * ) HTTP headers
    # through CloudFront and onto API Gateway. If we didn't set a custom domain
    # name on the API Gateway, the "Host" header passed through from CloudFront
    # to API Gateway would be for the custom domain, but API Gateway, which uses
    # SNI, wouldn't know which TLS certificate to use in the handshake because
    # API Gateway would have no record of that Host header. This would result in
    # API Gateway being unable to setup a TLS connection with the inbound
    # CloudFront connection attempt, API Gateway writing no logs about this
    # fact, and CloudFront returning to the user an error of
    # {"message":"Forbidden"}
    # If we weren't passing the "Host" header from CloudFront to API Gateway
    # this resource wouldn't be needed
    Type: AWS::ApiGateway::DomainName
    Properties:
      # Uppercase letters are not supported in DomainName
      DomainName: !Ref CustomDomainName
      EndpointConfiguration:
        Types:
          - REGIONAL
      RegionalCertificateArn: !Ref CertificateArn
      SecurityPolicy: TLS_1_2
  TestBasePathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Properties:
      # BasePath:   # Not specifying this so that we have no base path
      DomainName: !Ref TestApiGatewayDomainName
      RestApiId: !Ref TestApi
      Stage: !Ref TestApiStage
  TestLambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:invokeFunction
      FunctionName: !GetAtt TestFunction.Arn
      Principal: apigateway.amazonaws.com
      SourceArn: !Join [ '', [ 'arn:aws:execute-api:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref 'TestApi', '/*/*' ] ]
  TestApiStage:
    Type: AWS::ApiGateway::Stage
    Properties:
      DeploymentId: !Ref TestApiDeployment
      MethodSettings:
        - DataTraceEnabled: true
          HttpMethod: '*'
          ResourcePath: /*
      RestApiId: !Ref TestApi
  TestApiDeployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn:
      - TestRequest
    Properties:
      RestApiId: !Ref TestApi
      StageName: DummyStage
      # Deployment with an Empty Embedded Stage
      # The following instructional text is no longer present in the AWS
      # documentation for AWS::ApiGateway::Deployment StageName and it's not
      # clear if it still applies.
      #
      # "Note This property is required by API Gateway. We recommend that you
      # specify a name using any value (see Examples) and that you don’t use
      # this stage. We recommend not using this stage because it is tied to
      # this deployment, which means you can’t delete one without deleting the
      # other. For example, if you delete this deployment, API Gateway also
      # deletes this stage, which you might want to keep. Instead, use the
      # AWS::ApiGateway::Stage resource to create and associate a stage with
      # this deployment."
  TestResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: !Ref TestApi
      ParentId: !GetAtt TestApi.RootResourceId
      PathPart: '{proxy+}'
  TestRequest:
    DependsOn: TestLambdaPermission
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      Integration:
        Type: AWS_PROXY
        # IntegrationHttpMethod is POST regardless of the HttpMethod for this resource
        # https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
        # "For Lambda integrations, you must use the HTTP method of POST for the
        # integration request, according to the specification of the Lambda service
        # action for function invocations."
        IntegrationHttpMethod: POST
        Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
      ResourceId: !Ref TestResource
      RestApiId: !Ref TestApi
  TestPOSTRequest:
    DependsOn: TestLambdaPermission
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: POST
      Integration:
        Type: AWS_PROXY
        # https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
        # "For Lambda integrations, you must use the HTTP method of POST for the
        # integration request, according to the specification of the Lambda service
        # action for function invocations."
        IntegrationHttpMethod: POST
        Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
      ResourceId: !Ref TestResource
      RestApiId: !Ref TestApi
  TestRootRequest:
    # This resource is necessary to get API Gateway to respond to requests for the '/' path
    # Without it API Gateway will respond to requests for '/' with the error
    # {"message":"Missing Authentication Token"}
    # https://stackoverflow.com/q/46578615/168874
    # https://stackoverflow.com/q/52909329/168874
    DependsOn: TestLambdaPermission
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: GET
      Integration:
        Type: AWS_PROXY
        # IntegrationHttpMethod is POST regardless of the HttpMethod for this resource
        # https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
        # "For Lambda integrations, you must use the HTTP method of POST for the
        # integration request, according to the specification of the Lambda service
        # action for function invocations."
        IntegrationHttpMethod: POST
        Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
      # ResourceId must use the RootResourceId attribute of the AWS::ApiGateway::RestApi
      # https://stackoverflow.com/a/56121914/168874
      ResourceId: !GetAtt TestApi.RootResourceId
      RestApiId: !Ref TestApi
  TestCloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Comment: !Join [ ':', [!Ref 'AWS::StackName', 'Test']]
        DefaultCacheBehavior:
          AllowedMethods:
            - GET
            - HEAD
            - POST
            - DELETE
            - OPTIONS
            - PUT
            - PATCH
          Compress: true
          DefaultTTL: 0
          MinTTL: 0
          MaxTTL: 0
          ForwardedValues:
            Cookies:
              Forward: all
            QueryString: true
            Headers:
              - '*'
          TargetOriginId: TestCloudFrontOriginId
          ViewerProtocolPolicy: redirect-to-https
        # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-defaultrootobject
        DefaultRootObject: ''  # "If you don't want to specify a default root object when you create a distribution, include an empty DefaultRootObject element."
        Enabled: true
        Aliases:
          - !Ref CustomDomainName
        HttpVersion: http2
        IPV6Enabled: true
        #Logging:
        #  Logging
        Origins:
          - CustomOriginConfig:
              OriginProtocolPolicy: https-only
              OriginSSLProtocols:
                - TLSv1.2
            DomainName: !GetAtt TestApiGatewayDomainName.RegionalDomainName
            Id: TestCloudFrontOriginId
            # OriginPath: !Join [ '', [ '/', !Ref 'TestApiStage' ] ]
        PriceClass: PriceClass_100  # US, Canada, Europe, Israel
        ViewerCertificate:
          AcmCertificateArn: !Ref CertificateArn
          MinimumProtocolVersion: TLSv1.2_2018
          SslSupportMethod: sni-only

如果 AWS 更新此文檔頁面以解決此問題,您可以在此處查看原始頁面

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM