amazon-s3 - AWS CDK CloudFront 到 S3 重定向
问题描述
我正在使用 AWS CDK 设置 S3 和 CloudFront 静态网站托管。一切正常,直到我想将“http[s]//:www.mydomain.com”重定向到“https://mydomain.com”。我不想公开S3 存储库,而是为 CloudFront“原始访问身份”提供存储桶权限。我的 CDK 代码的相关片段如下:
const wwwbucket = new s3.Bucket(this, "www." + domainName, {
websiteRedirect: {
hostName: domainName,
protocol: s3.RedirectProtocol.HTTPS },
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL
})
const oaiWWW = new cloudfront.OriginAccessIdentity(this, 'CloudFront-OriginAccessIdentity-WWW', {
comment: 'Allows CloudFront to access the bucket'
})
wwwbucket.grantRead(oaiWWW)
const cloudFrontRedirect = new cloudfront.CloudFrontWebDistribution(this, 'https://www.' + domainname + '.com redirect', {
aliasConfiguration: {
acmCertRef: certificateArn,
names: [ "www." + domainName ],
sslMethod: cloudfront.SSLMethod.SNI,
securityPolicy: cloudfront.SecurityPolicyProtocol.TLS_V1_1_2016,
},
defaultRootObject: "",
originConfigs: [
// {
// customOriginSource: {
// domainName: wwwbucket.bucketWebsiteDomainName
// },
// behaviors : [ {isDefaultBehavior: true}],
// },
{
s3OriginSource: {
s3BucketSource: wwwbucket,
originAccessIdentity: oaiWWW
},
behaviors : [ {isDefaultBehavior: true}],
}
]
});
不幸的是,结果不是重定向,而是浏览到www.mydomain.com
浏览器中显示 S3 XML 存储桶列表结果的结果。我可以通过使用 AWS 控制台在“源设置”中从以下位置编辑 CloudFront 的“源域名”来手动解决问题:
bucketname.s3.eu-west-2.amazonaws.com
至:
bucketname.s3-website.eu-west-2.amazonaws.com
然后一切都按预期工作。我尝试将我的 CDK 脚本更改为使用customOriginSource
而不是s3OriginSource
(上面注释掉的代码),这会导致 CloudFront 的“源域名”中的地址正确,但是 CloudFront 分配没有“源访问身份”,所以可以t 访问 S3 存储桶。
有谁知道无需公开重定向存储桶或通过 AWS 控制台手动编辑“源域名”即可实现重定向的方法?
解决方案
我以为我已经使用CDK 逃生舱口找到了答案。在为我的重定向创建 CloudFront 分配后,我将 CDK 类后面的 CloudFormation JSON 修改为(在 typescript 中):
type ChangeDomainName = {
origins: {
domainName: string
}[]
}
const cfnCloudFrontRedirect = cloudFrontRedirect.node.defaultChild as cloudfront.CfnDistribution
var distributionConfig = cfnCloudFrontRedirect.distributionConfig as cloudfront.CfnDistribution.DistributionConfigProperty & ChangeDomainName
distributionConfig.origins[0].domainName = wwwbucket.bucketWebsiteDomainName
cfnCloudFrontRedirect.distributionConfig = distributionConfig
不幸的是,虽然这似乎生成了我cdk synthesize
在部署 ( cdk deploy
) 时瞄准的 CloudFormation 模板(使用 检查),但 CloudFormation 生成了以下错误:
UPDATE_FAILED | AWS::CloudFront::分发 | 参数 Origin DomainName 未引用有效的 S3 存储桶。
似乎即使可以在 CloudFront 控制台${bucketname}.s3-website.${region}.amazonaws.com
中的字段中手动设置表单的网站端点,Origin Domain Name
使用 CloudFormation 也是不可能的。这使我得出结论:
- 这是 CloudFormation 的一个错误。
- 这是控制台中的错误,因为控制台不应允许此设置。
但是,尽管目前Origin Domain Name
在控制台中进行修改是可行的,但我不知道这是否是一个“合法”的配置,将来可能会改变,在这种情况下,我的代码可能会停止工作。目前的解决方案是:
- 将重定向存储桶公开,在这种情况下
customOriginSource
将起作用。 - 与其使用重定向存储桶,不如使用 Lambda 执行重定向并使用 "Lambda@Edge" 在 CloudFront 中部署。
我不希望公开我的重定向存储桶,因为它会在使用安全检查工具时导致警告。使用 us-east-1 之外的 cdk 部署“Lambda@Edge”的选项目前看起来很痛苦,所以目前我将继续Origin Domain Name
在控制台中手动编辑。
作为参考,AWS 文档似乎暗示 API 禁止这种使用,尽管控制台允许,请参阅:使用 Amazon S3 Buckets Configured as Website Endpoints for Your Origin。也可以看看:
推荐阅读
- python - Python:在逗号前写入具有恒定字符数的数字
- python - 在csv文件中如何找到最大值(5个)及其对应的列uisng python
- wpf - 如何在动态创建的面板上动态添加按钮?
- php - 使用 cURL 在外部网站上提交表单不起作用
- amazon-web-services - 在“identityPoolId”检测到的验证错误未能满足约束
- android - 关于 Activity 和 Fragment 生命周期的问题
- r - 尝试通过数据拟合 nls 模型时出现“奇异梯度”或“低于 minFactor 的步长因子”错误
- java - 如何通过esb连接两个web服务?
- python - 无法从 for 循环中的列表中提取字典
- c - 链表不包含下一个元素(C 语言)