
누군가가 나를 깨달을 수 있다면 크게 감사하겠습니다.
예를 들어 단일 CloudFront 인스턴스에서 다음 매핑이 가능합니까?
feature-a.domain.com => dev-bucket/feature-a
feature-b.domain.com => dev-bucket/feature-b
staging.domain.com => dev-bucket/staging
기타 등등..
사용 사례는 존재하는 S3의 버킷에 매핑되는 각 git 브랜치에 대해 최대한 많은 환경을 배포할 수 있기를 원한다는 것입니다. 이 모든 것이 가능할까요?
답변1
예, 가능합니다. 하지만 버킷에 요청을 보내기 전에 요청 매개변수를 조작하려면 CloudFront에 대한 Lambda@Edge 향상된 기능을 사용해야 합니다.
나는 가능한 해결책 중 하나를 설명했습니다.이 공식 포럼 게시물. 동일한 솔루션이 아래에 포함되어 있습니다.
Lambda@Edge는 CloudFront가 HTTP 요청 또는 응답을 처리하는 동안 프로그래밍 방식으로 액세스할 수 있도록 하여 기본적으로 트리거 후크를 제공합니다. HTTP 트랜잭션은 관찰하고 수정한 다음 CloudFront에 제어권을 반환할 수 있는 javascript 객체로 제공됩니다.
이 애플리케이션의 경우 CloudFront 구성에서 버킷의 웹 사이트 호스팅 엔드포인트를 원본 도메인 이름으로 사용해야 합니다. 즉, 드롭다운에서 버킷을 선택하지 말고 적절한 "s3-website" 호스트 이름을 사용하여 입력합니다. ) 그리고 Host
우리가 실제로 헤더를 전달하지 않을지라도(우리는 그것을 읽은 다음 경로와 함께 조작할 것입니다) 원본으로 전달하기 위해 헤더를 화이트리스트에 추가해야 합니다. 일반적으로 이것을 다음으로 전달합니다. S3 오리진은 의도한 대로 작동하지 않습니다. 하지만 이를 읽고 조작할 수 있도록 CloudFront에 화이트리스트를 지정하도록 지시해야 합니다.
다음 Lambda 함수를 Origin Request 트리거로 구성합니다. 이 트리거는 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);
};
또한최소 TTL을 0으로 캐싱하는 중 오류가 발생했습니다.CloudFront 캐시 오류 응답을 방지하기 위해. 이는 캐시 동작 설정의 최소/기본/최대 TTL과 별개의 설정입니다. 기본값은 5분이므로 의미가 있지만 이 동작을 예상하지 않으면 문제 해결이 복잡해집니다.
이제 Lambda@Edge 함수는 v6.10 또는v8.10Node.js 런타임 환경. 위의 예는 원래 v6.10용으로 작성되었지만 v8.10에서는 핸들러에 더 많은 옵션이 있으므로 두 런타임 모두와 호환됩니다. async/await를 사용할 수 있거나 약속을 직접 반환할 수 있거나 위와 같이 작성할 수 있습니다. 콜백 인터페이스를 사용합니다.