Amazon Web Services 한국 블로그

Lambda@Edge 정식 출시 – 엣지 기반 HTTP 호출에 대한 지능적 처리 기능

지난해 말 Lambda@Edge미리 보기를 발표하여, 고객에게 가까이 있는 (대기 시간 기반) 엣지 로케이션에서 HTTP 요청을 지능적으로 처리하는 방법에 대해 설명했습니다. 미리 보기를 사용해 본 개발자 고객들은 이를 잘 활용하면서 많은 도움이 되는 피드백을 제공했습니다. 미리보기 테스트 중에 HTTP 응답을 생성하고 CloudWatch 통계를 지원하는 기능을 추가했으며, 피드백을 기반으로 향후 로드맵을 수정했습니다.

오늘 부터 Lambda@Edge가 정식 출시 되어 누구나 사용 가능합니다. 아래는 주요 사용 사례 입니다.

  • A/B 테스트를 수행하여, 쿠키 검사 및 URL 리다이렉트
  • User-Agent 헤더를 기반으로 특정 객체를 사용자에게 전송
  • HTTP 요청을 원본으로 전달하기 전에 특정 헤더를 찾아 접근 제어
  • HTTP 헤더를 추가, 삭제 또는 수정하여 사용자에게 다른 캐시 정보 사용
  • 신규 HTTP 응답 생성
  • 레거시 URL 에 대한 지원
  • HTTP 헤더 또는 URL을 수정 또는 압축하여 캐시 활용도 향상

Lambda@Edge를 활용하면 풍부한 개인적 웹 기반 사용자 환경을 만들 수 있습니다.  서버리스 기반이 빠르게 표준화 되고 있으므로, 이제 가상 서버를 프로비저닝하거나 관리 할 필요가 없습니다. 프로그래밍 코드 (Node.js로 작성된 람다 함수)를 업로드하고, Amazon CloudFront 배포판과 연결하면 됩니다. 그런 다음 원하는 CloudFront 이벤트와 함께 배포용으로 만든 CloudFront 동작 중 하나를 선택합니다.

위의 경우, 람다 함수 (가상으로 이름 붙인 EdgeFunc1)는 지정 배포 지점에서 image/*에 대한 원래 요청에 응답하여 실행합니다. 보시다시피 네 가지 CloudFront 이벤트에 대한 응답으로 코드를 실행할 수 있습니다.

뷰어 요청 (Viewer Request) -이 이벤트는 뷰어 (HTTP 클라이언트, 일반적으로 웹 브라우저 또는 모바일 앱)에서 이벤트가 도착하고 들어오는 HTTP 요청에 접근할 때 동작합니다. 각 CloudFront Edge 로케이션은 반복되는 요청에 효율적으로 응답 할 수 있도록 객체 캐시를 유지합니다. 이 특정 이벤트는 요청 된 개체가 이미 캐시되어 있는지 여부에 관계없이 동작합니다.

오리진 요청(Origin Request) -이 이벤트는 요청된 객체가 엣지 로케이션에 캐시되지 않기 때문에 오리진으로 다시 요청하려고 할 때 동작합니다. 오리진 요청 (종종 S3 버킷 또는 EC2 인스턴스에서 실행되는 코드)에 접근할 수 있습니다.

오리진 응답 (Origin Response) -이 이벤트는 오리진이 요청에 대한 응답을 반환 한 후에 동작합니다. 오리진의 응답에 접근할 수 있습니다.

뷰어 응답 (Viewer Response) – 엣지 로케이션 뷰어에 응답을 반환하기 전에 이벤트가 동작합니다. 응답에 대한 액세스 권한이 있습니다.

람다 함수는 중국을 제외한 모든 AWS 엣지 로케이션과 공개 리전에 자동 복제됩니다. HTTP 요청은 자동 실행을 위해 최적의 위치로 라우팅됩니다. 프로그램 코드를 한번에 배포하여, 전 세계 사용자가 낮은 지연 시간으로 실행할 수 있습니다.

소스 코드에는 HTTP 헤더, 쿠키, 메소드 (GET, HEAD 등) 및 URI를 비롯한 요청 및 응답에 대한 모든 접근 권한이 있습니다. 몇 가지 제한 사항에 따라 기존 헤더를 수정하고 새 헤더를 삽입 할 수 있습니다.

Lambda@Edge 직접 사용해 보기
뷰어 요청 이벤트에 응답하여 실행되는 간단한 함수를 작성해 보겠습니다. 람다 콘솔을 열고 새로운 함수를 만듭니다. Node.js 6.10 런타임을 선택하고 cloudfront 예제를 검색합니다.

cloudfront-response-generation을 선택하고 함수를 호출하는 트리거를 구성합니다.

람다 콘솔은 본 함수를 위한 운영 환경에 대한 몇 가지 정보를 제공합니다:

평소대로 함수에 대한 이름과 설명을 입력합니다.

예제에는 완전한 기능이 작동되도록 되어 있습니다. “200” HTTP 응답에 대한 간단한 동작을 생성합니다.

소스 코드를 내 자신 코드의 시작점으로 사용하여 HTTP 요청에서 흥미로운 값을 가져 와서 테이블에 표시합니다.

'use strict';
exports.handler = (event, context, callback) => {

    /* Set table row style */
    const rs = '"border-bottom:1px solid black;vertical-align:top;"';
    /* Get request */
    const request = event.Records[0].cf.request;
   
    /* Get values from request */ 
    const httpVersion = request.httpVersion;
    const clientIp    = request.clientIp;
    const method      = request.method;
    const uri         = request.uri;
    const headers     = request.headers;
    const host        = headers['host'][0].value;
    const agent       = headers['user-agent'][0].value;
    
    var sreq = JSON.stringify(event.Records[0].cf.request, null, ' ');
    sreq = sreq.replace(/\n/g, '<br/>');

    /* Generate body for response */
    const body = 
     '<html>\n'
     + '<head><title>Hello From Lambda@Edge</title></head>\n'
     + '<body>\n'
     + '<table style="border:1px solid black;background-color:#e0e0e0;border-collapse:collapse;" cellpadding=4 cellspacing=4>\n'
     + '<tr style=' + rs + '><td>Host</td><td>'        + host     + '</td></tr>\n'
     + '<tr style=' + rs + '><td>Agent</td><td>'       + agent    + '</td></tr>\n'
     + '<tr style=' + rs + '><td>Client IP</td><td>'   + clientIp + '</td></tr>\n'
     + '<tr style=' + rs + '><td>Method</td><td>'      + method   + '</td></tr>\n'
     + '<tr style=' + rs + '><td>URI</td><td>'         + uri      + '</td></tr>\n'
     + '<tr style=' + rs + '><td>Raw Request</td><td>' + sreq     + '</td></tr>\n'
     + '</table>\n'
     + '</body>\n'
     + '</html>'

    /* Generate HTTP response */
    const response = {
        status: '200',
        statusDescription: 'HTTP OK',
        httpVersion: httpVersion,
        body: body,
        headers: {
            'vary':          [{key: 'Vary',          value: '*'}],
            'last-modified': [{key: 'Last-Modified', value:'2017-01-13'}]
        },
    };

    callback(null, response);
};

핸들러를 구성하고 Basic Edge Lambda 권한을 사용하여 새 IAM 역할을 만들도록 요청합니다.

다음 페이지에서 (일반적인 람다 함수처럼) 설정을 확인하고 Create function을 클릭한다.

이렇게 하면 람다 함수가 만들어지고, 코드 배포 기능이 실행되어 각 CloudFront에 함수 복제가 시작됩니다. 내 배포 상태가 복사 기간 동안 In Progress으로 변경됩니다 (일반적으로 5-8 분).

복제가 완료되면 즉시 상태가 Deployed로 변경됩니다.

그런 다음 배포본 (https://dogy9dy9kvj6w.cloudfront.net/) 루트에 접근하면 함수가 실행되는 것을 볼 수 있습니다.

코드를 실행하려면 이미지를 클릭하십시오 (내 배포판의 루트에 링크되어 있음)!

늘 그렇듯이 간단한 예이며, 이 후 여러분이 훨씬 더 잘할 수 있다고 확신합니다. 다음은 시작하기 위한 몇 가지 아이디어입니다.

  • 복구 사이트 관리 – 전체 동적 웹 사이트를 오프라인으로 전환하고, 유지 관리 또는 재해 복구 작업 중 중요한 페이지를 Lambda@Edge 기능으로 대체 할 수 있습니다.
  • 대용량 정적 콘텐츠 – 스코어 보드, 일기 예보 또는 공공 안전 페이지를 작성하여, 엣지에서 빠르고 비용 효율적으로 사용할 수 있습니다.

멋진 것을 만들고 의견이나 블로그 게시물에서 공유하십시오. 그러면 살펴 보겠습니다.

알아 두어야 할 점들
Lambda@Edge를 응용 프로그램에서 사용하는 방법을 생각할 때 염두에 두어야 할 몇 가지 사항이 있습니다.

  • Timeouts – Origin Request 및 Origin Response 이벤트를 처리하는 함수는 3 초 이내에 완료되어야 합니다. 뷰어 요청 및 뷰어 응답 이벤트를 처리하는 기능은 1 초 이내에 완료되어야합니다.
  • 버전 관리 – 람다 콘솔에서 코드를 업데이트 한 후에는 새 버전을 게시하고 이에 대한 새로운 트리거 세트를 설정 한 다음 복제가 완료 될 때까지 기다려야합니다. 버전 번호를 사용하여 항상 코드를 참조해야합니다. $LATEST 및 별칭은 적용되지 않습니다.
  • 헤더 – 내 코드에서 볼 수 있듯이 HTTP 요청 헤더는 배열로 액세스 할 수 있습니다. 헤더는 네 가지 범주로 나뉩니다.
    • 액세스 가능 – 읽기, 쓰기, 삭제 또는 수정할 수 있음
    • 제한됨 – 원본으로 전달 필요
    • 읽기 전용 – 읽을 수는 있지만 어떤 방식 으로든 수정할 수는 없음
  • 블랙 리스트 – 코드에서 볼 수 없으며 추가 할 수 없음
  • 런타임 환경 – 런타임 환경은 각 기능에 128MB의 메모리를 제공하지만 내장 라이브러리 나 / tmp에 대한 액세스는 제공하지 않습니다.
  • 웹 서비스 접근 – Origin Request 및 Origin Response 이벤트를 처리하는 기능이 3 초 이내에 완료되어야 AWS API에 액세스하고 HTTP를 통해 컨텐츠를 가져올 수 있습니다. 이러한 요청은 항상 원본 요청 또는 응답에 대한 요청과 동 기적으로 이루어집니다.
  • 함수 복제 – 앞에서 언급했듯이 함수는 중국의 AWS 영역을 제외한 모든 공용 AWS 영역에 복제됩니다. 복제본은 람다 콘솔의 “기타”영역에서 볼 수 있습니다.

CloudFront 동작에 대해 이미 알고 있는 모든 것이 Lambda@Edge와 관련이 있습니다. 각 동작에서 여러 동작 (최대 4 개의 Lambda@Edge 함수 포함)을 사용하고, HTTP 헤더 및 쿠키 전달을 사용자 정의 할 수 있습니다. 동작을 편집하는 동안 이벤트 버전과 함수 (함수 버전을 포함하는 ARN을 통해)를 연결할 수도 있습니다.

정식 출시
Lambda@Edge는 현재 이용 가능하며, 지금 바로 사용하실 수 있습니다. 가격은 기능 호출 횟수 및 실행 시간을 기준으로 합니다 (자세한 정보는 Lambda@Edge 가격 책정 페이지 참조).

Jeff;

이 글은 Lambda@Edge – Intelligent Processing of HTTP Requests at the Edge의 한국어 번역입니다.