이전 자료들을 보면 heroku를 사용하여 프로젝트를 배포하는 것이 정석으로 여겨질 정도였으나, heroku 유료화 후 다들 배포 서비스 유목민이 된 것 같아 다른 배포처를 알아보았습니다. fly.io, 렌더, 레일웨이 등 여러 옵션을 고려하던 와중, 디스코드 봇 서버를 AWS Lambda로 배포한 후기글들을 읽고 Lambda로 결정하게 되었습니다.
AWS Lambda란?
AWS Lambda는 클라우드 컴퓨팅 서비스 중 하나로, 서버리스 컴퓨팅 환경에서 코드를 실행하고 관리하는 데 사용됩니다. 서버를 구축할 필요 없이 단순히 코드를 작성하고, Lambda에 업로드하고, 코드가 실행될 트리거를 설정하기만 하면 됩니다. Lambda는 이 코드를 자동으로 실행하고 필요할 때 스케일링하여 더 많은 요청을 처리합니다.
장점
- 서버리스 아키텍처: 서버리스는 서버를 직접 관리할 필요가 없으므로 운영 및 관리 부담이 적습니다.
- 저비용: Lambda는 사용한 컴퓨팅 리소스만큼만 비용을 지불하므로 효율적입니다. 코드가 실행되지 않는 동안은 비용이 발생하지 않습니다. 컴퓨팅 리소스만 고려하면 EC2에 비해 비싸보일 수 있지만, 사용하는 영역에 대해서만 비용을 지불하고 사용하지 않는동안은 비용이 청구되지 않으므로 효율적입니다.
- 자동 스케일링: 트래픽이 증가하면 Lambda는 자동으로 스케일링하여 추가 요청을 처리합니다. 이로써 확장성이 높아집니다.
- 다양한 트리거: Lambda는 다양한 이벤트 소스에서 트리거될 수 있습니다. 예를 들어 HTTP 요청, 데이터베이스 변경, 파일 업로드 등 다양한 이벤트에 대응할 수 있습니다.
- 테스트 자동화: 단위 테스트를 손쉽게 작성할 수 있습니다. 이는 람다의 구조가 간단하기 때문인데, Input이 들어오면 Output을 보내는 구조이기 때문입니다. 예를 들면 POST 요청이 들어오면 그 데이터를 처리하고, 처리한 내용을 콜백함수로 응답을 보냅니다. 뿐만 아니라 자체 테스트 기능도 제공합니다.
사용법
- 코드 작성: 원하는 작업을 수행하는 서버단 코드를 작성합니다. 이 코드는 특정 이벤트가 발생했을 때 실행됩니다.
- 코드 업로드: 작성한 코드를 AWS Lambda 서비스에 업로드합니다. 이 코드는 AWS에서 관리 및 실행됩니다.
- 트리거 설정: Lambda 함수를 언제 실행할 것인지 설정합니다. 예를 들어, HTTP 요청이 들어왔을 때 Lambda 함수를 실행하도록 설정할 수 있습니다.
- 실행 및 모니터링: Lambda 함수가 트리거되고 실행됩니다. 실행 로그와 모니터링 데이터를 AWS CloudWatch와 같은 도구를 사용하여 확인할 수 있습니다.
활용법
- 웹 애플리케이션에서 HTTP 요청을 처리하거나 API 서버를 구축할 수 있습니다.
- 데이터베이스 변경 시 데이터 처리 및 분석 작업을 자동화할 수 있습니다.
- 파일 업로드 시 파일 처리 작업을 실행할 수 있습니다.
- 스케줄링된 작업을 실행하거나 이벤트 소스에서 발생하는 이벤트에 대응할 수 있습니다.
AWS Lambda로 배포하기
Lambda로 배포하고자 하는 경우, 먼저 AWS Lambda 서비스를 사용하여 함수를 생성하고 배포해야 합니다. 과정은 간단하지만 옵션을 잘 몰라 헤맸기에 찾아본 내용을 정리했습니다.
함수 배포 과정
- 우선 AWS 계정을 생성한 후, AWS Management Console에 로그인한 다음 Lambda 서비스로 이동합니다.
- Lambda 콘솔에서 "함수 생성"을 클릭합니다.
- "기능" 페이지에서 함수 이름을 입력하고 런타임 환경을 선택합니다. (ex. Node.js)
- 함수 생성 버튼을 클릭하면 생성됩니다.
- 함수 페이지로 이동합니다. 여기서 함수 코드를 업로드하거나 직접 작성할 수 있습니다. 업로드는 zip 파일만 대응하는 것으로 보입니다.
- 함수 페이지의 테스트 항목에서 이벤트 생성 및 작성하는 것으로 테스트를 실행할 수 있습니다. 간단한 코드로 함수가 제대로 동작하는지 확인합니다.
- Lambda 함수 배포가 완료되면 해당 함수의 엔드포인트 URL 또는 트리거에 대한 정보를 확인할 수 있습니다. 또한 해당 함수를 호출하거나 트리거 이벤트를 발생시켜 결과를 확인할 수 있습니다.
이렇게 매번 압축하여 콘솔에서 업로드하는 과정이 번거로웠기에, AWS Lambda CLI로 업로드하는 방법에 대해 알아보았습니다. 자세한 내용은 아래 링크에서 확인할 수 있습니다.
함수 아키텍처 옵션
- arm64 아키텍처:
- 64비트 ARM 아키텍처를 사용합니다.
- GB/s당 비용이 일반적으로 더 저렴합니다.
- Graviton2 프로세서를 사용하므로 일부 워크로드에서 더 높은 성능을 제공할 수 있습니다.
- x86_64 아키텍처:
- x86 기반 프로세서용 64비트 x86 아키텍처입니다. 이것이 기본 아키텍처입니다.
- 일부 기존 코드나 종속성이 x86_64 아키텍처에 의존하는 경우 유용할 수 있습니다.
아래의 요인에 따라 아키텍처를 선택합니다. 기존 코드나 종속성에 의존성이 없고 비용을 최소화하려는 경우, arm64 아키텍처를 사용하는 것이 좋다고 합니다.
- 성능 요구 사항: 프로젝트의 성능 요구 사항에 따라 적절한 아키텍처를 선택합니다. Graviton2 기반의 ARM 아키텍처는 일부 워크로드에서 더 높은 성능을 제공할 수 있으므로 해당 워크로드에 대해 더 낮은 비용으로 더 많은 성능을 얻을 수 있을 수 있습니다.
- 코드 및 종속성: 기존 코드 또는 종속성이 특정 아키텍처에 의존하는 경우 해당 아키텍처로 배포해야 합니다. 종속성이 x86_64 아키텍처에 종속된 경우 해당 아키텍처를 선택해야 합니다.
- 비용 관리: GB/s당 비용을 고려하여 예산을 관리하고자 할 때 적절한 아키텍처를 선택합니다.
함수 역할(role)
이 역할은 Lambda 함수가 다른 AWS 리소스와 상호 작용하거나 특정 작업을 수행할 수 있는 권한을 부여합니다. 권한 설정에 따라 세 가지 옵션이 있습니다.
- 기본 Lambda 권한을 가진 새 역할 생성:
- 이 옵션을 선택하면 AWS에서 미리 정의한 기본 Lambda 실행 역할을 새로 생성합니다.
- 이 역할에는 Lambda 함수를 실행하는 데 필요한 권한이 미리 구성되어 있습니다.
- 가장 간단한 방법이지만, 추가적인 권한이 필요한 경우에는 사용하기 어려울 수 있습니다.
- 기존 역할 사용:
- 이미 생성한 AWS Identity and Access Management (IAM) 역할 중에서 Lambda 함수에 필요한 권한을 가진 역할을 선택합니다.
- 사용자 정의 역할을 만들고 그 역할에 필요한 권한을 직접 추가하는 경우에 유용합니다.
- 특별한 권한 설정이 필요한 경우에 맞게 구성할 수 있습니다.
- AWS 정책 템플릿에서 새 역할 생성:
- AWS에서 제공하는 정책 템플릿 중에서 하나를 선택하여 새로운 IAM 역할을 생성합니다.
- 선택한 템플릿에 정의된 권한을 가진 역할이 생성됩니다.
- 이 방법은 특정 AWS 서비스와 통합할 때 유용할 수 있습니다.
가장 간단한 방법은 "기본 Lambda 권한을 가진 새 역할 생성"을 선택하는 것이며, 추가적인 권한이 필요한 경우 "기존 역할 사용" 또는 "AWS 정책 템플릿에서 새 역할 생성" 중에서 선택하실 수 있습니다. (추후 변경 가능)
함수 URL
첫 생성 시 설정하지 않은 경우 Configuration 에서 설정 가능합니다.
Auth type
- AWS_IAM
- AWS Identity and Access Management (IAM)을 통해 권한을 부여하지 않은 사용자나 역할(role)은 AWS Lambda 함수에 액세스할 수 없습니다. 누구나 함수에 접근할 수 없도록 보안을 강화하는 방법 중 하나입니다.
- 클라이언트(웹 페이지 또는 애플리케이션)가 자격증명을 사용하여 액세스 권한을 부여하고 이러한 권한을 관리해야 합니다.
- NONE
- 누구나 함수에 접근이 가능합니다.
- 간단한 웹 애플리케이션 또는 공개적으로 액세스할 수 있는 서비스의 경우에는 NONE 인증을 사용하여 일반 사용자도 쉽게 액세스할 수 있도록 설정할 수 있습니다.
이에 대한 자세한 내용은 하단 링크에서 확인할 수 있습니다.
CORS (Cross-Origin Resource Sharing) 설정
웹 애플리케이션에서 다른 도메인의 리소스에 접근할 수 있도록 해주는 중요한 부분입니다.
- Allow origin: 이 설정은 특정 도메인에서 Lambda 함수 URL로의 접근을 허용합니다.
- *: 모든 도메인에서 접근을 허용합니다. 개발 초기 단계나 테스트할 때 유용합니다.
- 특정 도메인을 지정하여 그 도메인에서만 접근을 허용합니다. 보안 측면에서 더 안전합니다.
- Expose headers: 클라이언트(브라우저)가 JavaScript 등을 통해 접근할 수 있도록 서버에서 노출하는 특정한 HTTP 응답 헤더를 지정합니다.
- 일반적인 REST API 요청에서는 이 설정을 변경할 필요가 없으나, 특정 헤더를 클라이언트가 읽을 필요가 있는 경우 (ex. 사용자 지정 헤더) 해당 헤더를 추가해야 합니다.
- 표준 HTTP 요청 및 응답을 사용하고 있으며 특별한 헤더를 사용하지 않는 경우 기본값으로 두어도 충분합니다.
- Allow headers: 브라우저가 요청 시에 포함할 수 있는 HTTP 헤더를 지정합니다.
- 즉 서버가 클라이언트로부터 받아들일 수 있는 특정 요청 헤더입니다. 예를 들어, Content-Type, X-Requested-With, 사용자 인증 헤더 등을 포함시킬 수 있습니다.
- 표준 HTTP 요청 및 응답을 사용하고 있으며 특별한 헤더를 사용하지 않는 경우 기본값으로 두어도 충분합니다.
- Allow methods: 해당 Lambda 함수 URL에 대해 허용할 HTTP 메서드를 지정합니다. 일반적으로 GET, POST, PUT, DELETE 등이 있습니다. * 를 사용하면 모든 메서드를 허용합니다.
- Max age: 브라우저가 CORS preflight 요청의 결과를 캐시할 수 있는 최대 시간(초)을 지정합니다. 이 시간 동안은 동일한 요청에 대해 서버로 preflight 요청을 다시 보내지 않습니다. 예를 들어, 86400 (24시간)이 일반적인 값입니다.
- Allow credentials: 요청에서 쿠키나 인증 관련 데이터를 허용할지 여부를 설정합니다. 대부분의 경우 이 옵션은 비활성화(Off) 상태로 두는 것이 좋습니다. 활성화(On) 시에는 보안상의 문제가 발생할 수 있습니다.
이러한 설정은 어플리케이션의 요구사항과 보안 정책에 따라 달라질 수 있습니다. 예를 들어, 공개적으로 접근 가능한 API는 Allow origin을 *로 설정할 수 있지만, 회사 내부나 제한된 사용자에게만 서비스를 제공하는 경우에는 특정 도메인을 지정하는 것이 좋습니다.
CORS 관련하여 발생한 오류 해결 내용을 아래 링크에 정리하였습니다.
함수에 환경 변수 추가하기
API KEY 등 환경 변수는 Lambda에 직접 추가할 필요가 있습니다.
- 함수 설정 페이지에서 "Configuration" 섹션으로 이동합니다.
- "Environment variables" 옵션을 찾아 클릭합니다.
- "Environment variables" 설정 화면에서 "Edit" 또는 "Add environment variable" 버튼을 클릭합니다.
- "Key"와 "Value" 필드가 표시됩니다. "Key"에는 환경 변수의 이름을 입력하고 "Value"에는 해당 환경 변수의 값을 입력합니다. 여기서 "Key"에는 API_KEY를 입력하고 "Value"에는 해당 API 키 값을 입력하세요.
- 원하는 만큼 많은 환경 변수를 추가할 수 있습니다. 추가한 환경 변수는 Lambda 함수 내에서 사용할 수 있게 됩니다.
- 환경 변수를 추가한 후에는 "Save" 버튼을 클릭하여 변경 사항을 저장해야 합니다.
이렇게 하면 Lambda 함수가 실행될 때 해당 환경 변수에 액세스할 수 있게 됩니다. 이렇게 API 키와 같은 중요한 정보를 안전하게 관리하고 사용할 수 있습니다.
기존 코드도 수정해야할까?
환경 변수를 Lambda 함수에 업로드한 후에는 코드를 수정할 필요가 없습니다. import dotenv from "dotenv"; 및 dotenv.config(); 코드는 로컬 개발 환경에서 환경 변수를 읽어오는 것이며, Lambda 함수 실행 환경에서는 이미 설정된 환경 변수를 사용합니다.
따라서 Lambda 함수가 실행될 때, 설정된 환경 변수를 자동으로 로드하므로 코드 수정이 필요하지 않습니다.