amazon-web-services - 如何为两种 CloudFront 行为使用不同的错误配置?
问题描述
我有一个 CloudFront 分配,其自定义源指向所有其他路径上的 ALB/api/*
和一个 S3 源,用于所有其他路径上的静态站点(分配的默认行为)。这为存储在 S3 中的 Vue 应用程序和在 Fargate 中运行的由 ALB 负载平衡的 API 提供服务。
在 CloudFront 分配的错误配置中,我有一个发送 404 响应的规则/index.html
(这是 SPA 所必需的,以便 JavaScript 路由器可以拾取嵌套路由)。目前,当 API 返回 404 响应时,它给出的是/index.html
响应,而不是来自 API 的 404 响应。这是有道理的,但这不是我想要的行为。有没有办法获得 API 404 响应/api/*
,但/index.html
仅用作默认 S3 Origin/默认行为的 404 响应?
我最初在子域上提供了 ALB,所以这不是问题。我试图通过在同一个域 ( app.mydomain.com
) 上提供 API 和前端站点来简化事情,而不是在 上提供前端mydomain.com
和 API api.mydomain.com
,但这会产生一个带有错误响应的新错误。
我正在使用 CDK 构建此应用程序,这是我的 CloudFront 分配的代码,它导致 404 响应问题:
path_patterns = ["/api/*", "/admin/*"]
self.distribution = cloudfront.CloudFrontWebDistribution(
self,
"CloudFrontDistribution",
origin_configs=[
cloudfront.SourceConfiguration(
custom_origin_source=cloudfront.CustomOriginConfig(
domain_name=alb,
origin_protocol_policy=cloudfront.OriginProtocolPolicy.MATCH_VIEWER,
),
behaviors=[
cloudfront.Behavior(
allowed_methods=cloudfront.CloudFrontAllowedMethods.ALL,
path_pattern=path_pattern,
forwarded_values={
"headers": ["*"],
"cookies": {"forward": "all"},
"query_string": True,
},
)
for path_pattern in path_patterns
],
),
cloudfront.SourceConfiguration(
s3_origin_source=cloudfront.S3OriginConfig(
s3_bucket_source=self.static_site_bucket
),
behaviors=[
cloudfront.Behavior(
is_default_behavior=True,
cached_methods=cloudfront.CloudFrontAllowedMethods.GET_HEAD,
)
],
),
],
alias_configuration=cloudfront.AliasConfiguration(
acm_cert_ref=certificate.certificate_arn,
names=[full_domain_name],
),
error_configurations=[
{
"errorCode": 403,
"errorCachingMinTtl": 0,
"responseCode": 200,
"responsePagePath": "/index.html",
},
{
"errorCode": 404,
"errorCachingMinTtl": 0,
"responseCode": 200,
"responsePagePath": "/index.html",
},
],
)
编辑:2020-05-13
我已经尝试从 S3 存储桶中删除error_configuration
并且还CloudFrontWebDistribution
设置了website_index_document
和:website_error_document
self.static_site_bucket = s3.Bucket(
self,
"StaticSiteBucket",
access_control=s3.BucketAccessControl.PUBLIC_READ,
bucket_name=f"{full_app_name}-frontend",
removal_policy=core.RemovalPolicy.DESTROY,
website_index_document="index.html",
website_error_document="index.html",
)
通过此更改,当我希望看到我的 Vue 应用程序提供的 404 页面时,我仍然收到 Key Error 404 响应。
在我的 CloudFront 配置中为静态站点使用 S3 源是否正确,还是应该是指向存储桶网站 URL 的自定义源?
我没有为 ALB 和 S3 网站使用自定义来源。以下是 CDK 中描述的所有资源:
from aws_cdk import (
aws_certificatemanager as acm,
aws_s3 as s3,
aws_cloudfront as cloudfront,
aws_route53 as route53,
aws_iam as iam,
aws_route53_targets as targets,
core,
)
class CloudFront(core.Construct):
def __init__(
self,
scope: core.Construct,
id: str,
hosted_zone: route53.IHostedZone,
certificate: acm.ICertificate,
alb: str,
full_domain_name: str,
full_app_name: str,
**kwargs,
) -> None:
super().__init__(scope, id, **kwargs)
self.static_site_bucket = s3.Bucket(
self,
"StaticSiteBucket",
access_control=s3.BucketAccessControl.PUBLIC_READ,
bucket_name=f"{full_app_name}-frontend",
removal_policy=core.RemovalPolicy.DESTROY,
website_index_document="index.html",
website_error_document="index.html",
)
self.policy_statement = iam.PolicyStatement(
actions=["s3:GetObject"],
resources=[f"{self.static_site_bucket.bucket_arn}/*"],
)
self.policy_statement.add_any_principal()
self.static_site_policy_document = iam.PolicyDocument(
statements=[self.policy_statement]
)
self.static_site_bucket.add_to_resource_policy(self.policy_statement)
path_patterns = ["/api/*", "/admin/*", "/flower/*"]
self.distribution = cloudfront.CloudFrontWebDistribution(
self,
"CloudFrontDistribution",
origin_configs=[
cloudfront.SourceConfiguration(
custom_origin_source=cloudfront.CustomOriginConfig(
domain_name=alb,
origin_protocol_policy=cloudfront.OriginProtocolPolicy.MATCH_VIEWER, # noqa
),
behaviors=[
cloudfront.Behavior(
allowed_methods=cloudfront.CloudFrontAllowedMethods.ALL, # noqa
path_pattern=path_pattern,
forwarded_values={
"headers": ["*"],
"cookies": {"forward": "all"},
"query_string": True,
},
)
for path_pattern in path_patterns
],
),
cloudfront.SourceConfiguration(
custom_origin_source=cloudfront.CustomOriginConfig(
domain_name=self.static_site_bucket.bucket_domain_name,
origin_protocol_policy=cloudfront.OriginProtocolPolicy.MATCH_VIEWER, # noqa
),
behaviors=[
cloudfront.Behavior(
is_default_behavior=True,
cached_methods=cloudfront.CloudFrontAllowedMethods.GET_HEAD, # noqa
)
],
),
],
alias_configuration=cloudfront.AliasConfiguration(
acm_cert_ref=certificate.certificate_arn,
names=[full_domain_name],
),
)
route53.ARecord(
self,
"AliasRecord",
target=route53.AddressRecordTarget.from_alias(
targets.CloudFrontTarget(self.distribution)
),
zone=hosted_zone.hosted_zone,
record_name=f"{full_domain_name}.",
)
编辑 2020-05-14
我为自定义来源使用了错误的域名。我试过了bucket_regional_domain_name
,bucket_website_domain_name
但这些都给了我my-s3-bucket-name.s3.us-east-1.amazonaws.com
。这是我用于自定义源配置的设置:
cloudfront.SourceConfiguration(
custom_origin_source=cloudfront.CustomOriginConfig(
domain_name=f"{self.static_site_bucket.bucket_name}.s3-website-us-east-1.amazonaws.com",
origin_protocol_policy=cloudfront.OriginProtocolPolicy.HTTP_ONLY,
),
behaviors=[
cloudfront.Behavior(
is_default_behavior=True,
cached_methods=cloudfront.CloudFrontAllowedMethods.GET_HEAD,
)
],
),
HTTP_ONLY
很重要,这不适用于MATCH_VIEWER
. 另外,请注意我如何使用 f 字符串来获取s3-website
存储桶的正确 URL。我仍然不确定这是否可以在 CDK 中自动找到。如果我发现更多,我会更新这个。
解决方案
@briancaffey,很高兴再次为您提供帮助。在 CloudFront 中无法做到这一点。或者,我认为以下方法应该有效。
- 在 CloudFront 中删除自定义错误响应
- 在您的 S3 源中配置自定义错误文档。[参考]
- 将CloudFront 更改
S3Origin
为CustomOrigin
将 S3 网站终端节点设置为源域名。
推荐阅读
- c# - 在 Razor 页面中的 OnGetAsync 将值分配给另一个模型
- javascript - reactjs中的搜索功能
- javascript - Firebase:从云函数调用云函数
- gcc-warning - gcc 命令行结构参数
- python-3.x - 如何在 Pyomo 中声明二维和三维向量
- c# - 如何强制我的 C# windows 窗体使用阿拉伯数字?
- powershell - 用递增编号重命名所有子元素
- c++ - 指向具有移动语义的成员函数的指针
- java - ViewModel 不为 RecyclerView 缓存数据并且保存 ListState 不起作用
- php - 覆盖 FPDF 输出