본문 바로가기
자습

AWS Lambda@Edge

by litaro 2019. 8. 10.

https://medium.com/@gavinlewis/localizing-content-with-lambda-edge-fefb12aa6199

 

Localizing content with Lambda@Edge

Recently our marketing team came to me with the challenge of localizing content for viewers from different countries on the GreenOrbit…

medium.com

생소한 Lamda@Edge 에 대한 글이 있어 정리하려고한다.

요구사항?

사용자의 browser language 에 따라 localized content 로 redirect 하기

ex) en-au 면 https://litaro.com 을 접속할때 https://litaro.com/en-au/ 로 redirect

Lambda@Edge?

AWS에서 제공하는 Lambda@Edge 로 Viewer requet/response 나 origin request/response 부분에서 발생한 CloudFront Event를 받아 실행되는 lambda를 통해 중간에 우리가 원하는 응답을 하도록 바꾸는 것이다.

https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html

 

Customizing Content at the Edge with Lambda@Edge - Amazon CloudFront

Customizing Content at the Edge with Lambda@Edge Lambda@Edge is an extension of AWS Lambda, a compute service that lets you execute functions that customize the content that CloudFront delivers. You can author Node.js or Python functions in one Region, US-

docs.aws.amazon.com

Lambda@Edge 는 AWS Lambda 를 확장한 것으로 CloudFront에서 deliver 하는 content를 customize 하는 기능을 실행하도록 도와준다. 

사용 예제...

1. Lambda 에서 cookie를 확인하여 A/B testing을 위해 사용자가 다른 version의 site를 보도록 rewrite

2. CloudFront가 user-agent header(device  정보가 있는) 를 통해 사용자가 사용하는 device에 따라 다른 대상을 보도록 할수 있다. 한 예로, device에 따라 다른 size의 image를 return

3. 또다른 목적을 위해 cookie를 활용할수 있다. 예를 들어, 옷을 파는 사이트라고 하면, 사용자가 선택한 색상이 무엇인지 알려주는 cookie를 통해 어떤 색상의 자켓을 보여줄지 확인해서 해당 색상의 자켓의 이미지를 return

4. Lamgda에서 CloudFront의 Viewer request 나 Origin request Event 발생시 필요한 Response 를 생성

5. header 난 authorization token 을 사전에 검열해서 origin으로 보낼때 접근 제어를 위한 header를 주입

6. Lambda는 response를 customize하기 위해 필요한 추가 정보나 user credentials 확인을 위해 외부 resource 를 call 하는것도 가능

실제 적용 방법

1. CloudFront 설정

먼저 cache 할 data 인 Accept-Language header를 whitelisted 한다.

https://medium.com/@gavinlewis/localizing-content-with-lambda-edge-fefb12aa6199

언어별로 다른 S3 복사본 경로로 가도록 추가적인 behaviors 를 설정 : 예) en-au의 경우는 s3://bucketname/en-au*로 요청

https://medium.com/@gavinlewis/localizing-content-with-lambda-edge-fefb12aa6199

2. Lambda function 작성

Lambda@Edge를 실행하는데는 제한사항이 있어 이를 미리 확인해둬야한다.

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html

 

Requirements and Restrictions on Lambda Functions - Amazon CloudFront

Requirements and Restrictions on Lambda Functions See the following sections for requirements and restrictions on using Lambda functions with CloudFront. CloudFront Distributions and Associations You cannot associate a Lambda function with a CloudFront dis

docs.aws.amazon.com

Viewer Request Event 의 경우 아래의 제약사항을 가지고... 그래서 NodeJS 나 Python을 택할 가능성이 높다. 

  • 128mb memory limit
  • 5 second execution time
  • 40KB response size
  • 1MB library size (compressed)
  • Cannot use environment variables

Lambda Function을 생성하면 Behavior에서 Trigger를 받을 수 있도록 설정한다.

이때 Lambda의 version을 명확히 해야한다.

https://medium.com/@gavinlewis/localizing-content-with-lambda-edge-fefb12aa6199

실행 시키면 아래와 같이 Event가 들어와서..

[{
  "cf": {
   "config": {
    "distributionDomainName": "d********.cloudfront.net",
    "distributionId": "EM*******",
    "eventType": "viewer-request",
    "requestId": "1234567890"
   },
   "request": {
    "clientIp": "000.000.000.000",
    "headers": {
     "host": [{
      "key": "Host",
      "value": "greenorbit.com"
     }],
     "accept-language": [{
      "key": "accept-language",
      "value": "en-AU,en;q=0.9,en-GB;q=0.8"
     }],
    },
    "method": "GET",
    "querystring": "",
    "uri": "/product/features/"
   }
  }
 }]

결국 저 list 형태로 들어오는 Event에서 원하던 accept-language 값을 확인해서 url을 바꿔서 request를 redirect 하도록 한다.

'use strict';
  exports.redirector = (event, context, callback) => {
      console.log('Request: ' + JSON.stringify(event));
      const request = event.Records[0].cf.request;
      let response = request;
      
      if (headers['accept-language']) {
          const acceptLanguage = headers['accept-language'][0].value;
          const userLanguage = acceptLanguage.split(',')[0].toLowerCase();
  
          if (userLanguage === 'en-au') {
              url = url + userLanguage + uri + querystring;
              response = {
                  status: '302',
                  statusDescription: 'Found',
                  headers: {
                      location: [{
                          key: 'Location',
                          value: url,
                      }],
                  },
              };
          }
      }
          
      callback(null, response);
  }

 

그렇게 되면 원하던 redirect 구현 완료~!

 

'자습' 카테고리의 다른 글

click을 이용한 python CLI  (0) 2019.09.08
pre-commit 활용하기  (0) 2019.08.31
파이썬 클린 코드 CH3. 좋은 코드의 일반적인 특징  (0) 2019.08.17
Python Logging  (0) 2019.07.26
AWS S3-Select  (0) 2019.07.20