API Gateway (APIG) は、CloudFront (CF) を使用していますが、CDN エッジ キャッシングをサポートしていません。カスタム オリジンとして APIG を使用するように CF ディストリビューションを構成すると、アクセス許可拒否エラーが発生します。
これを修正するために CF を構成するにはどうすればよいですか?
API Gateway (APIG) は、CloudFront (CF) を使用していますが、CDN エッジ キャッシングをサポートしていません。カスタム オリジンとして APIG を使用するように CF ディストリビューションを構成すると、アクセス許可拒否エラーが発生します。
これを修正するために CF を構成するにはどうすればよいですか?
API Gateway (APIG) が CloudFront (CF) の内部使用によるエッジ キャッシングをサポートするまで、私は回避策を考え出しました。
確かに APIG の前に CF dist を置くことができます。秘訣は、APIG には SNI が必要なため、HTTPS のみを「Viewer Protocol Policy」に強制し、HOST ヘッダーを転送しないようにすることです。
ヘッダーを転送しないようにCFの「デフォルトキャッシュ動作設定」をセットアップし、「ビューアプロトコルポリシー」を「HTTPSのみ」に強制すると機能します。これが他の人に役立つことを願っています。
必要なすべての設定を含む CloudFormation リソース オブジェクトを次に示します (注: <stage>--<app name>
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
2018 年後半の更新
MinimumProtocolVersion: TLSv1.1_2016