Amazon Web Services 한국 블로그
AWS Lambda Function URL 발표 – 단일 기능 마이크로서비스용 내장 HTTPS 엔드포인트
AWS Lambda를 사용하여 탄력적이고 확장 가능한 애플리케이션을 구축하기 위해 마이크로서비스 아키텍처를 채택하고 있습니다. 이러한 애플리케이션은 비즈니스 로직을 구현하는 다수의 서버리스 함수로 구성됩니다. 각 함수는 Amazon API Gateway 및 Application Load Balancer와 같은 서비스를 사용하여 API 엔드포인트, 메서드 및 리소스에 매핑됩니다.
하지만 때로는 Lambda 외에 추가 서비스를 학습, 구성 및 운영할 필요 없이 함수 앞에 HTTPS 엔드포인트를 구성하는 간단한 방법만 있으면 됩니다. 예를 들어 개별 Lambda 함수 내에서 실행되는 웹후크 핸들러 또는 간단한 양식 유효성 검사기를 구현해야 하는 경우가 있습니다.
오늘, AWS Lambda 함수에 HTTPS 엔드포인트를 추가하고 선택적으로 Cross-Origin Resource Sharing(CORS) 헤더를 구성할 수 있는 새로운 기능인 Lambda 함수 URL의 정식 출시를 발표하게 되어 기쁩니다.
이를 통해 가용성이 높고 확장 가능하며 안전한 HTTPS 서비스를 구성하고 모니터링하면서 중요한 사항에 집중할 수 있습니다.
Lambda Function URL의 작동 방식
새 함수 URL을 만들어 임의의 함수에 매핑합니다. 각 함수 URL은 전역적으로 고유하며 함수의 별칭 또는 $LATEST
버전을 암시적으로 호출하는 함수의 정규화되지 않은 ARN과 연결될 수 있습니다.
예를 들어 함수 URL을 $LATEST
버전에 매핑하면 함수 URL을 통해 각 코드 업데이트를 즉시 사용할 수 있습니다. 반면에 새 버전을 안전하게 배포하고 통합 테스트를 수행한 다음 준비가 되었을 때 별칭을 업데이트할 수 있도록 하려면 함수 URL을 별칭에 매핑하는 것이 좋습니다. 또한 가중치 기반 트래픽 이동 및 안전한 배포를 구현할 수 있습니다.
함수 URL은 Lambda API에서 기본적으로 지원되며 AWS 관리 콘솔 또는 AWS SDK 및 AWS CloudFormation, AWS SAM, AWS Cloud Development Kit(AWS CDK)와 같은 코드형 인프라(IaC) 도구를 통해 사용할 수 있습니다.
Lambda 함수 URL 활용
새 함수나 기존 함수에 대한 함수 URL을 구성할 수 있습니다. 웹후크를 처리하기 위해 새 함수를 구현하는 방법을 살펴보겠습니다.
새 함수를 생성할 때 고급 설정(Advanced Settings)에서 함수 URL 활성화(Enable function URL)를 선택합니다.
여기서는 인증 유형 AWS_IAM 또는 없음을 선택하겠습니다. 내 웹후크는 HTTP 헤더에 제공된 서명을 기반으로 사용자 지정 권한 부여 로직을 사용합니다. 따라서 AuthType 없음을 선택하겠습니다. 즉, Lambda는 함수를 호출하기 전에 AWS IAM Sigv4 서명을 확인하지 않습니다. 대신 권한 부여를 위해 함수 핸들러에서 사용자 정의 헤더를 추출하고 유효성을 검사합니다.
AuthType 없음을 사용할 때 내 함수의 리소스 기반 정책은 퍼블릭 액세스를 명시적으로 허용해야 하는 점에 주의하세요. 그렇지 않으면 인증되지 않은 요청이 거부됩니다. AddPermission API를 사용하여 프로그래밍 방식으로 권한을 추가할 수 있습니다. 이 경우 사용 중인 IAM 역할에 내 계정에서 AddPermission API를 호출할 권한이 부여되므로 Lambda 콘솔이 자동으로 필요한 정책을 추가합니다.
클릭 한 번으로 CORS를 활성화할 수도 있습니다. 기본 CORS 구성에서는 모든 오리진을 허용합니다. 그런 다음 함수를 생성한 후 좀 더 세분화된 제어를 추가하겠습니다. CORS가 익숙하지 않은 분들에게 설명드리자면, 특정 호스트만 리소스를 로드하고 API를 호출할 수 있도록 브라우저에서 구현한 헤더 기반 보안 메커니즘입니다. 웹 사이트에서 API를 사용하도록 허용된 경우 허용되는 오리진, 메서드 및 사용자 지정 헤더를 선언하는 CORS 헤더를 몇 개 포함해야 합니다. 새 함수 URL이 이를 처리하므로 Lambda 핸들러에서 이 모든 것을 구현할 필요는 없습니다.
몇 초가 지나면 함수 URL을 사용할 수 있습니다. 또한 Lambda 콘솔에서 쉽게 찾아서 복사할 수 있습니다.
Node.js에서 웹후크를 처리하는 함수 코드는 다음과 같습니다.
exports.handler = async (event) => {
// (optional) fetch method and querystring
const method = event.requestContext.http.method;
const queryParam = event.queryStringParameters.myCustomParameter;
console.log(`Received ${method} request with ${queryParam}`)
// retrieve signature and payload
const webhookSignature = event.headers.SignatureHeader;
const webhookPayload = JSON.parse(event.body);
try {
validateSignature(webhookSignature); // throws if invalid signature
handleEvent(webhookPayload); // throws if processing error
} catch (error) {
console.error(error)
return {
statusCode: 400,
body: `Cannot process event: ${error}`,
}
}
return {
statusCode: 200, // default value
body: JSON.stringify({
received: true,
}),
};
};
이 코드는 요청 헤더, 쿼리 문자열 및 본문에서 몇 가지 파라미터를 추출합니다. API Gateway 또는 Application Load Balancer에서 제공하는 이벤트 구조에 대해 이미 잘 알고 있다면 이 코드가 매우 친숙하게 보일 것입니다.
코드를 업데이트한 후 HTTP 클라이언트로 함수 URL을 테스트하기로 결정했습니다.
예를 들어, curl
을 사용하여 테스트하는 방법은 다음과 같습니다.
$ curl "https://4iykoi7jk2kp5hhd5irhbdprn40yxest.lambda-url.us-west-2.on.aws/?myCustomParameter=squirrel"
-X POST
-H "SignatureHeader: XYZ"
-H "Content-type: application/json"
-d '{"type": "payment-succeeded"}'
또는 Python 스크립트를 사용할 수도 있습니다.
import json
import requests
url = "https://4iykoi7jk2kp5hhd5irhbdprn40yxest.lambda-url.us-west-2.on.aws/"
headers = {'SignatureHeader': 'XYZ', 'Content-type': 'application/json'}
payload = json.dumps({'type': 'payment-succeeded'})
querystring = {'myCustomParameter': 'squirrel'}
r = requests.post(url=url, params=querystring, data=payload, headers=headers)
print(r.json())
테스트에서 요청의 Content-type
을 application/json
또는 text/*
로 설정해야 합니다. 그렇지 않으면 본문이 기본적으로 base64로 인코딩되며 Lambda 핸들러에서 이를 디코딩해야 합니다.
물론 여기서는 웹후크에 대해 얘기하고 있기 때문에 이 함수는 제가 통합하려는 외부 시스템으로부터 직접 요청을 받습니다. 따라서 퍼블릭 함수 URL을 제공하고 이벤트 수신을 시작하기만 하면 됩니다.
이 특정 사용 사례에서는 CORS 구성이 필요하지 않습니다. 브라우저에서 함수 URL이 호출되는 다른 경우에는 Access-Control-Allow-Origin
, Access-Control-Allow-Methods
, Access-Control-Expose-Headers
와 같은 CORS 파라미터를 몇 개 구성해야 합니다. Lambda 콘솔 또는 IaC 템플릿에서 이러한 CORS 파라미터를 쉽게 검토하고 편집할 수 있습니다. 콘솔에서 보이는 모습은 다음과 같습니다.
또한 각 함수 URL은 고유하며 함수의 특정 별칭 또는 $LATEST
버전에 매핑됩니다. 이렇게 하면 동일한 함수에 대해 여러 URL을 정의할 수 있습니다. 예를 들어 개발 중에 $LATEST
버전을 테스트하기 위한 버전과 스테이징
, 프로덕션
등과 같은 각 단계 또는 별칭에 대한 버전을 정의할 수 있습니다.
코드형 인프라(IaC) 지원
AWS CloudFormation, AWS SAM 및 AWS Cloud Development Kit(AWS CDK)를 사용하여 지금 바로 IaC 템플릿에서 Lambda 함수 URL을 구성할 수 있습니다.
예를 들어, AWS SAM을 사용하여 Lambda 함수 및 해당 퍼블릭 URL을 정의하는 방법(별칭 매핑 등)은 다음과 같습니다.
WebhookFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: webhook/
Handler: index.handler
Runtime: nodejs14.x
AutoPublishAlias: live
FunctionUrlConfig:
AuthType: 없음
Cors:
AllowOrigins:
- "https://example.com"
IaC 템플릿에 기존 Lambda 함수가 있는 경우 몇 줄의 코드로 새 함수 URL을 정의할 수 있습니다.
함수 URL 가격
함수 URL은 Lambda의 요청 및 기간 요금에 포함됩니다. 예를 들어 128MB의 메모리와 평균 호출 시간이 50ms인 단일 Lambda 함수를 배포한다고 가정해 보겠습니다. 이 함수는 매달 5백만 건의 요청을 수신하므로 요청 비용은 1.00 USD가 되고 기간 요금은 0.53 USD가 됩니다. 미국 동부(버지니아 북부) 리전의 총 합계는 월 1.53 USD입니다.
함수 URL을 사용하는 경우와 Amazon API Gateway를 사용하는 경우
함수 URL은 요청 검증, 제한, 사용자 지정 권한 부여자, 사용자 지정 도메인 이름, 사용 계획 또는 캐싱과 같은 API 게이트웨이 고급 기능이 필요하지 않은 퍼블릭 엔드포인트로 단일 기능 마이크로서비스를 구현해야 하는 모든 사용 사례에 적합합니다. 예를 들어 웹후크 핸들러, 양식 유효성 검사기, 모바일 결제 처리, 광고 배치, 기계 학습 추론 등을 구현할 때가 있습니다. 또한 Lambda 콘솔을 벗어나거나 추가 서비스를 통합하지 않고도 연구 개발 중에 Lambda 함수를 호출하는 가장 간단한 방법이기도 합니다.
Amazon API Gateway는 모든 규모에서 API를 손쉽게 생성, 게시, 유지 관리, 모니터링 및 보호할 수 있는 완전관리형 서비스입니다. API Gateway를 사용하여 JWT/사용자 지정 권한 부여자, 요청/응답 검증 및 변환, 사용 계획, 기본 제공 AWS WAF 지원 등의 기능을 활용할 수 있습니다.
지금 이용 가능
함수 URL은 AWS 중국 리전을 제외한 현재 Lambda를 사용할 수 있는 모든 AWS 리전에서 정식으로 사용할 수 있습니다. Datadog, Lumigo, Pulumi, Serverless Framework, Thundra 및 Dynatrace 등의 많은 AWS Lambda 파트너를 통해서도 지원을 받을 수 있습니다.
이 새로운 기능을 사용하여 서버리스 아키텍처를, 특히 간단하게 비용 최적화를 유지하려는 단일 기능 사용 사례에서 어떻게 간소화하려는 계획이신지 알려주시기 바랍니다.
— Alex