How do you add CloudFront in front of API Gateway

后端 未结 5 1556
情话喂你
情话喂你 2020-11-28 20:49

API Gateway (APIG), while it uses CloudFront (CF) it does not support CDN edge caching. When I configured a CF distribution to use APIG as the custom origin, I get a permiss

5条回答
  •  忘掉有多难
    2020-11-28 20:59

    Until API Gateway (APIG) supports edge caching via its internal use of CloudFront (CF), I have come up with a workaround.

    You can indeed put CF dist in front of APIG, the trick is to force HTTPS only "Viewer Protocol Policy" AND to NOT forward the HOST header because APIG needs SNI.

    I setup my CF "Default Cache Behavior Settings" to not forward any headers, and forced "Viewer Protocol Policy" to "HTTPS Only" and it works. Hope this helps others.

    Here is a CloudFormation resource object that has all the required configuration (Note: I use the convention -- for StackName):

    CloudFront:  
        Type: AWS::CloudFront::Distribution
        Properties:
          DistributionConfig:
            Enabled: true
            IPV6Enabled: true
            HttpVersion: http2
            Comment: !Join [ '--', [!Ref 'AWS::StackName', ' Cloud Front']]
            Aliases: [!Ref CloudFrontCname]
            ViewerCertificate:
              AcmCertificateArn: !Ref AcmCertificateArn
              SslSupportMethod: sni-only
              MinimumProtocolVersion: TLSv1.1_2016
            Origins:
            - Id: APIGOrigin
              DomainName: !Sub
                - ${apigId}.execute-api.${AWS::Region}.amazonaws.com
                - { apigId: !Ref ApiGatewayLambdaProxy }
              OriginPath: !Sub
                - /${Stage}
                - { Stage: !Select [ "0", !Split [ '--', !Ref 'AWS::StackName' ] ] }
              CustomOriginConfig:
                # HTTPPort: 80
                HTTPSPort: 443
                OriginProtocolPolicy: https-only
              OriginCustomHeaders:
                - HeaderName: 'Verify-From-Cf'
                  HeaderValue: !Ref VerifyFromCfHeaderVal
            DefaultCacheBehavior:
              AllowedMethods: ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
              CachedMethods: ["GET", "HEAD", "OPTIONS"]
              ForwardedValues:
                Headers:
                - Access-Control-Request-Headers
                - Access-Control-Request-Method
                - Origin
                - Authorization
                # - Host APIG needs to use SNI
                QueryString: true
              TargetOriginId: APIGOrigin
              ViewerProtocolPolicy: https-only
              Compress: true
              DefaultTTL: 0
            CustomErrorResponses:
            - ErrorCachingMinTTL: 0
              ErrorCode: 400
            - ErrorCachingMinTTL: 1
              ErrorCode: 403
            - ErrorCachingMinTTL: 5
              ErrorCode: 500
      DNSARecord:    
        Type: AWS::Route53::RecordSet
        Properties:
          Comment: !Ref 'AWS::StackName'
          Name: !Ref CloudFrontCname
          Type: A
          HostedZoneName: !Join ['.', [ !Select [1, !Split ['.', !Ref CloudFrontCname]], !Select [2, !Split ['.', !Ref CloudFrontCname]], '']]
          AliasTarget:
            HostedZoneId: !Ref Route53HostedZoneId
            DNSName: !GetAtt CloudFront.DomainName
      DNSAAAARecord:    
        Type: AWS::Route53::RecordSet
        Properties:
          Comment: !Ref 'AWS::StackName'
          Name: !Ref CloudFrontCname
          Type: AAAA
          HostedZoneName: !Join ['.', [ !Select [1, !Split ['.', !Ref CloudFrontCname]], !Select [2, !Split ['.', !Ref CloudFrontCname]], '']]
          AliasTarget:
            HostedZoneId: !Ref Route53HostedZoneId
            DNSName: !GetAtt CloudFront.DomainName
    

    Late 2018 updates

    • CloudFormation finally supports setting SSL proto ver: MinimumProtocolVersion: TLSv1.1_2016
    • I've baked this (and many other) best practices into an OSS project: aws-blueprint

提交回复
热议问题