...
Lambda 트리거 기능
람다 트리거란, 람다 함수를 실행할 수 있는 이벤트를 일컫는다.
간단하게 예를 들면, S3에 파일이 적재되면 이를 이벤트로 받아 람다 함수를 실행 할 수도 있고, 브라우저에 url을 치면 rest api로서 람다 함수를 실행 할 수도 있다.
이처럼 람다는 다른 AWS 서비스와 유기적으로 연동될 수 있다는 점에서 굉장히 파워풀 하다고 볼 수 있다.
람다 함수를 테스트할때 눌렀던 테스트 버튼 역시 람다 트리거의 일종이라고 볼 수 있다.
람다 트리거는 다음과 같이 변화나 호출 같은 이벤트가 발생할 경우 함수 코드가 돌아가게 하여 값을 반환하게 할 수 있다.
- 데이터변화 : DB 데이터가 바뀌면 람다 함수 실행
- API Endpoint와 결합을 시켜서 직접 또는 Endpoint로 호출
- 리소스 상태 변화 : (CloudWatch를 통해) 리소스 상태가 어떻게 변화가 되었다면 람다 함수를 실행해서 이벤트에 대응
- Cron 주기별로 실행 : 정기적인 작업이 있을 경우 람다 활용
- API로 접근 가능한 모든 서비스/기능 호출 가능하기 때문에 외부 서비스 호출 가능
Lambda 모델 종류
- 동기식 (Synchronous) : 람다 함수 앞단에다가 API Gateway Endpoint를 결합시켜놓으면, 브라우저에 rest api 방식으로 myapi.com/call 이런식으로 URL을 호출시에 람다함수를 실행 할 수 있다.
- 비동기식 (ASynchronous) : SNS, CloudWatch, S3를 트리거로 사용을 하면, S3에 파일이 업로드 되거나 하는 이벤트가 발생할때 비동기로 람다함수를 자동으로 실행 시키게 할 수 있다.
- 스트림 베이스 (Stream-based) : Kinesis(실시간으로 데이터 스트림을 수집, 처리, 분석해주는 서비스)나 dynamodb와도 함께 사용 가능하다.
람다 트리거 실전 구축
람다 함수 메뉴를 보면, 중앙 내 함수 영역 박스가 있고 양쪽에 트리거 추가와 대상 추가가 있는 것을 볼 수 있다.
[트리거 추가]는 특정 요청(API GateWay)이나 정해진 시간(Event Bridge)을 신호로 람다 함수가 작동하게 설정할 수 있고,
[대상 추가]에서는 비동기 실행이나 조건 성립 후 다른 람다 함수 실행 등 작업을 정할 수 있다.
람다 트리거 + S3 설정
람다와 S3 서비스간의 트리거를 만들어보자.
S3 버킷에 파일을 올리면 람다함수에서 버킷에 업로드된 파일명을 알수 있는 로직을 구현해볼 예정이다.
우선 S3 버킷을 만들어 준비하자.
그리고 람다 함수 코드를 다음과 같이 코딩해준다.
exports.handler = async (event) => {
console.log(JSON.stringify(event));
return 'S3';
};
준비됬으면, 람다 트리거를 추가한다.
트리거 추가 버튼을 누르면 AWS의 다른 서비스들을 선택 할 수 있다.
- API 게이트웨이는 어떤 URL로 접속했을 때 람다가 실행되도록 하는 것
- DynamoDB는 DynamoDB 서비스에 어떤 일이 발생 했을 때 람다 함수를 호출하는 것
- S3는 파일이 업로드 되었을 때 람다함수를 실행.
위 메뉴에서 S3 서비스를 고르고 다음과 같이 구성을 마친다.
이벤트 유형으로는 파일이 업로드(PUT) 되거나 복사(COPY) 되거나 삭제 등 행동에 대해 상세히 구분하여 설정도 가능하다.
여기서는 연습을 위해 모든 객체 생성 행동 이벤트를 선택한다.
이렇게 다음과 같이 myLamba 라는 람다 함수를 실행시키는 트리거로서 S3 설정이 추가된 것이다.
람다함수에 S3 트리거를 추가하게되면, S3 메뉴쪽에서도 람다함수가 등록되게 된다.
S3 버킷에 가서 [ 속성 탭 ]에 가 스크롤을 쭉 내려 [ 이벤트 알림 탭 ]을 봐보자.
따로 설정을 하지 않았는데도 람다 함수가 등록됨을 확인 할 수 있다.
이제 람다 트리거가 잘 작동되는지 확인하기 위해, S3 버킷에 이미지 파일을 업로드 해보자.
그리고 CloudWatch 로그 스트림에 있는 로그를 보면 다음과 같이 리턴값으로 객체를 받게 된다.
{
"Records": [
{
"eventVersion": "2.1",
"eventSource": "aws:s3",
"awsRegion": "ap-northeast-2",
"eventTime": "2022-04-25T11:03:05.217Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "AWS:AIDAYXPEPKI7JH2G44W3T"
},
"requestParameters": {
"sourceIPAddress": "220.117.48.100"
},
"responseElements": {
"x-amz-request-id": "ZM8KFVFHWGBSW0XQ",
"x-amz-id-2": "YVV0GxWdaP7DR2oCWZDHvhDAmhpHhAIGYMpKi0OBBDx8/V0h8TyDcTT9LO/ZprsIUBWbezD31ZqLgc0AtDKqJl2g4xjxDR2DKMuUij6ioyk="
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "cc63115c-2060-4c20-b7ab-c225d027a5b4",
"bucket": {
"name": "testbucket-010",
"ownerIdentity": {
"principalId": "A1OP8TBWXPIMOQ"
},
"arn": "arn:aws:s3:::testbucket-010"
},
"object": {
"key": "img+%2832%29.png",
"size": 57001,
"eTag": "082434d9d24cc88234a3ddc1d23c0a62",
"sequencer": "0062667FE92A07604C"
}
}
}
]
}
여기서 우리가 알고 싶은것은 S3 버킷에 업로드한 파일명이다.
JSON 객체를 보니, event.Records[0].s3.object.key 을 통해 업로드 파일명을 조회할수 있음을 알 수 있다.
람다 함수 코드를 다음과 같이 업데이트 해준다.
exports.handler = async (event) => {
//console.log(JSON.stringify(event));
return console.log(decodeURIComponent(event.Records[0].s3.object.key));
};
다시 S3에 업로드해보면 다음과 같이 람다 함수에서 이미지 파일명이 리턴됨을 알수 있다.
람다 트리거 + API Gateway Http api 설정
이번에는 url로 람다함수를 실행하는 트리거를 세팅해보자.
람다함수 코드를 다음과 같이 설정한다.
exports.handler = async (event) => {
const response = {
statusCode : 200,
body: "hello Lambda !!"
};
return response;
};
그리고 트리거 메뉴에 들어가 API Gateway 항목을 추가한다.
[AWS API Gateway]
Amazon API Gateway는 규모와 관계없이 REST 및 WebSocket API를 생성, 게시, 유지, 모니터링 및 보호하기 위한 AWS 서비스로 API의 '관문' 역할을 한다.
API에 대한 단일 진입점으로 사용자 요청을 각 API 서버로 라우팅해주고, API에 대한 로깅, 엑세스 제어, 모니터링, 인증 처리를 해준다.
구성 트리거 메뉴에서 이때까지 우리가 등록한 트리거 목록을 볼수 있다.
API 게이트웨이에 API 엔드포인트 URL을 복사해 브라우저에 쳐보자.
API 라우팅 설정하기
단순히 url을 치면 똑같은 결과값을 송출하는 람다 트리거에서, url에 경로(path)를 다양하게 줘서 다양한 값을 출력하는 정적이 아닌 동적인 애플리케이션 서버를 만들어보도록 하자.
아래 경로 와 같이 echo/ 경로 뒤에 path 동적값과 쿼리스트링 값에 따라 람다가 이들을 동적으로 출력하도록 설정해 볼 것이다.
경로에 특정한 값을 줘서, 람다 함수 결과가 다른 값이 나오게 하도록 하기위해 우선 API Gateway 콘솔에서 경로 설정을 해야 한다.
여기서 중요한 점이, 중괄호로 감싸진 {id} 인데, 이 뜻은 경로변수(와일드카드)로서, 람다에 id 라는 변수값으로 들어오게 된다는 뜻이다.
예를들어,
- localhost:8080/echo/1
- localhost:8080/echo/55
- localhost:8080/echo/991
이런식으로 url path 값들이 제각각 들일때 이를 id 라는 경로변수로 받아 함수 코드에서 동적으로 값을 처리할 수 있다.
경로를 설정해줬으니, 이 경로로 외부에서 접속할 경우 어떠한 통합 동작을 할지, 통합 연결을 설정해준다.
이렇게 람다와 API 게이트웨이 라우팅 연결을 맞추었다.
잘되는지 테스트 하기위해 람다 함수 코드를 다음으로 변경해준다.
exports.handler = async (event, context, callback) => {
console.log(event);
};
그리고 경로 등록한 API Endpoint로 경로(path)와 쿼리스트링을 줘서 접속 해준다.
정상적으로 응답이 왔으면 람다의 console.log(event) 가 출력될 것인데, 이는 클라이언트에서는 출력이 안되고 CloudWatch 로 가서 로그를 봐야 한다.
위의 콘솔 로그에서 우리가 출력하길 원하는 객체 키 값을 찾는다.
그리고 다시 람다 함수 코드를 다음과 같이 바꾸어 준다. (Node.js 는 callback() 을 해야 클라이언트에 응답을 하게 된다)
exports.handler = async (event, context, callback) => {
//console.log(event);
callback(null, {
"statusCode": 200,
"headers": {
"Content-Type": "application/json", // json 형식으로 지정
},
"body": JSON.stringify({
method : event.requestContext.http.method, // http 메소드
id : event.pathParameters.id, // 경로 파라미터
query: event.queryStringParameters.filter, // 쿼리트스링 값
})
});
};
그리고 다시 url을 접속해보면, 다음과 같이 클라이언트에 json으로 값을 응답 받게 된다.
이렇게 따로 api 서버를 올려 서비스하지않고도, 정말 간단하게 AWS API 게이트웨이와 AWS Lambda 만으로 api 서비스를 만들어 보았다. 이것이 바로 서버리스의 강점이라 말할 수 있다.
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.