首页 > 解决方案 > 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 控制台手动编辑“源域名”即可实现重定向的方法?

标签: amazon-s3amazon-cloudfrontaws-cdk

解决方案


我以为我已经使用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 也是不可能的。这使我得出结论:

  1. 这是 CloudFormation 的一个错误。
  2. 这是控制台中的错误,因为控制台不应允许此设置。

但是,尽管目前Origin Domain Name在控制台中进行修改是可行的,但我不知道这是否是一个“合法”的配置,将来可能会改变,在这种情况下,我的代码可能会停止工作。目前的解决方案是:

  1. 将重定向存储桶公开,在这种情况下customOriginSource将起作用。
  2. 与其使用重定向存储桶,不如使用 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。也可以看看:


推荐阅读