Van*_*yen 6 amazon-s3 subdomain amazon-cloudfront amazon-web-services
我一直在寻找一种方法来执行以下操作,如果有人能启发我,将不胜感激。
例如,在单个 CloudFront 实例中是否可以进行以下映射?
feature-a.domain.com => dev-bucket/feature-a
feature-b.domain.com => dev-bucket/feature-b
staging.domain.com => dev-bucket/staging
Run Code Online (Sandbox Code Playgroud)
等等..
用例是我希望能够为每个映射到 S3 上存在的存储桶的 git 分支部署尽可能多的环境。这一切有可能吗?
是的,这是可能的,但您需要使用 CloudFront 的 Lambda@Edge 增强功能,以便在将请求发送到存储桶之前操作请求参数。
我在这篇官方论坛帖子中描述了一种可能的解决方案。下面包含相同的解决方案。
Lambda@Edge 允许在 CloudFront 处理 HTTP 请求或响应时以编程方式访问它们,本质上是提供触发挂钩。HTTP 事务以 JavaScript 对象的形式呈现,您可以观察和修改该对象,然后将控制权返回给 CloudFront。
对于此应用程序,您需要在 CloudFront 配置中使用托管存储桶端点的网站作为您的原始域名(即不要从下拉列表中选择存储桶 - 使用适当的“s3-website”主机名输入它) )并且您需要将Host标头列入白名单以转发到原点,即使我们实际上不会转发它(我们将读取它,然后与路径一起操作它),并且即使通常将其转发到S3 源无法按预期工作...但我们需要告诉 CloudFront 将其列入白名单,以便可以读取和操作它。
将以下 Lambda 函数配置为源请求触发器。此触发器在检查 CloudFront 缓存并发生缓存未命中之后、请求发送到源服务器 (S3) 之前触发。
'use strict';
// https://serverfault.com/a/930191/153161
// if the end of incoming Host header matches this string,
// strip this part and prepend the remaining characters onto the request path,
// along with a new leading slash (otherwise, the request will be handled
// with an unmodified path, at the root of the bucket)
// set this to what we should remove from the incoming hostname, including the leading dot.
const remove_suffix = '.example.com';
// provide the correct origin hostname here so that we send the correct
// Host header to the S3 website endpoint
// this is the same value as "origin domain name" in the cloudfront distribution configuration
const origin_hostname = 'example-bucket.s3-website-us-east-1.amazonaws.com';
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
const host_header = headers.host[0].value;
if(host_header.endsWith(remove_suffix))
{
// prepend '/' + the subdomain onto the existing request path ("uri")
request.uri = '/' + host_header.substring(0,host_header.length - remove_suffix.length) + request.uri;
}
// fix the host header so that S3 understands the request
// we have to do this even if the above if() didn't match
headers.host[0].value = origin_hostname;
// return control to CloudFront with the modified request
return callback(null,request);
};
Run Code Online (Sandbox Code Playgroud)
另请记住将错误缓存最小 TTL设置为 0 ,以避免出现 CloudFront 缓存错误响应。这是与缓存行为设置中的最小/默认/最大 TTL 分开的设置。默认值为 5 分钟,这是有道理的,但如果您没有预料到这种行为,故障排除就会变得复杂。
请注意,Lambda@Edge 函数现在可以使用 v6.10 或v8.10 Node.js 运行时环境。上面的示例最初是为 v6.10 编写的,但与任一运行时兼容,因为在 v8.10 中处理程序有更多选项:它可以使用 async/await,它可以直接返回一个 Promise,或者可以如上所示编写使用回调接口。
| 归档时间: |
|
| 查看次数: |
1488 次 |
| 最近记录: |