Granular Control of CloudFront traffic distribution

2019年01月03日

There might be multiple origins for one CloudFront Distribution. How to specify the Origin based on a more customizable "Origin selection rules"? In that case, we can use Lambda@Edge to achieve the goal. 
*
What does the Edge Lambda function code look like
Below is a snippet of Edge Lambda function code, where "Host" and "CloudFront-Viewer-Country" needs caching.

Note
If you want CloudFront to add some headers, the CloudFront must be configured to cache those headers.

if (request.headers['cloudfront-viewer-country']) {
	const countryCode = request.headers['cloudfront-viewer-country'][0].value;
	if (countryCode === 'CN' || countryCode === 'US') {
		request.origin = {
			custom: {
				domainName: "alb.example.com",
				port: 443,
				protocol: 'https',
				path: '',
				sslProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2'],
				readTimeout: 5,
				keepaliveTimeout: 5,
				customHeaders: {}
			}
		};
		request.headers['host'] = [ { key: 'host', value: domainName } ];
*
How is the next hop determined

*
If the "Origin" in the request is not changed by the Edge Lambda function, then CloudFront will use the origin specified in "Path Pattern" of the "Behaviors" of the CloudFront Distribution configuration. This "Path Pattern" follows the behavior matching rules of the CloudFront.

*
If the "Origin" in the request is changed by the Edge Lambda function, then CloudFront will use the origin specified in the Edge Lambda function.
If a criteria meets, then it will respond with the page representing alb1.example.com, not the alb.example.com.
request.origin = {
	custom: {
		domainName: 'alb2.example.com',
		port: 443,
		protocol: 'https',
		path: '',
		sslProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2'],
		readTimeout: 5,
		keepaliveTimeout: 5,
		customHeaders: {}
	}
};
request.headers['host'] = [{
	key: 'host', 
	value: domainName
}];
*

*
Below scenario is considered as healthy by Route 53. A Lambda function is associated to the target group, and the target group is attached to the ALB.

*

*

*
  1. The browser sends request to https://example.com, which is CloudFront's DNS address. As data arrives Cloudfront, its next hop, namely the "origin", is alb.example.com
  2. Lamdba@Edge queries Route 53 where alb.example.com is.
  3. Route 53 replies with the address of the ALB in us-west-2 region, in response to Lambda's DNS query, because it is deemed healthy by Route 53. The reason it is considered as healthy is the same as we explained previously.
  4. Cloudfront directs the request to that ALB.
  5. The ALB will respond with a 503 page back to Cloudfront.
  6. Depend on whether Cloudfront has custom error page configure, it may respond the tester's browser with a native or customized 503 page.
*

*
  1. The browser sends request to https://example.com, which is CloudFront's DNS address.
  2. At the Cloudfront, the next hop, namely the "origin", is alb.example.com
  3. Lamdba@Edge queries Route 53, asking where alb.example.com is.
  4. Route 53 replies with the address of the ALB in us-west-2 region in response to Lambda's DNS query.
  5. Cloudfront directs the request to that ALB.
  6. The ALB responds with a normal page back to Cloudfront.
  7. Cloudfront responds the tester's browser with that web page.
*

Category: AWS Tags: public

Upvote


Downvote