Terraform으로 서버리스 구현하기 - AWS Lambda 함수 배포
요약
Terraform을 사용하여 AWS Lambda 함수를 배포하고 서버리스 아키텍처를 구축하는 방법을 설명합니다. EC2 대비 비용 효율적인 서버리스 모델의 장점과 API Gateway, S3 트리거, IAM 역할 설정을 포함한 실무 가이드를 제공합니다.
핵심 포인트
- Terraform을 이용한 Lambda 함수 및 API Gateway 배포 방법
- S3 파일 업로드를 통한 Lambda 트리거 구성
- 최소 권한 원칙을 적용한 IAM 역할 및 CloudWatch 로깅 설정
- 이벤트 기반 워크로드에서 서버리스를 통한 비용 최적화 전략
👋 안녕하세요, 기술 애호가 여러분!
저는 복잡한 기술적 과제를 우아한 솔루션으로 변환하는 데 열정을 가진 클라우드 아키텍트(Cloud Architect) Sarvar입니다. Cloud Operations (AWS & Azure), Data Operations, Analytics, DevOps, 그리고 Generative AI를 아우르는 폭넓은 경험을 바탕으로, 실제 비즈니스 임팩트를 창출하는 글로벌 기업들을 위한 솔루션을 설계하는 특권을 누려왔습니다. 이번 아티클 시리즈를 통해 기술 세계에서의 여정에서 얻은 실질적인 통찰, 베스트 프랙티스(best practices), 그리고 실무 경험을 공유하고자 합니다. 여러분이 숙련된 전문가이든 이제 막 시작하는 단계이든, 복잡한 개념을 프로젝트에 바로 적용할 수 있도록 이해하기 쉽게 풀어내는 것이 저의 목표입니다.
"서버는 먹이를 주고, 간호하며, 죽었을 때 슬퍼해야 하는 반려동물(pets)과 같습니다. Lambda 함수는 생성하고, 사용하고, 잊어버리는 가축(cattle)과 같습니다."
🎯 다시 오신 것을 환영합니다!
Article 7에서 로드 밸런서(load balancer)와 함께 웹 서버를 배포했던 것을 기억하시나요? 당시에는 ALB 뒤에서 24시간 내내 실행되는 EC2 인스턴스를 구축했습니다. 이는 트래픽이 많은 웹 앱에는 훌륭한 방식입니다. 하지만 가끔씩만 실행되는 워크로드(workloads)는 어떨까요?
현실은 이렇습니다: 아무도 사용하지 않을 때조차 EC2 인스턴스 비용을 24시간 내내 지불해 왔습니다. 하루에 한 번 파일을 처리하는 내부 도구가 있다면? 실제 작업 시간은 5분뿐인데 t3.medium 인스턴스를 위해 월 $30를 지불하고 있는 셈입니다.
Lambda는 이 방정식을 바꿉니다:
- 코드가 실행될 때만 비용 지불
- 패치하거나 유지 관리할 서버가 없음
- 0에서 수천 개까지 자동으로 확장(Scales)
- IAM 역할(roles)이 권한을 관리 (이제 여러분도 알고 계시죠!)
이 아티클을 마칠 때쯤 여러분은 다음을 수행할 수 있게 됩니다:
- ✅ Terraform으로 Lambda 함수 배포
- ✅ HTTP 접속을 위한 API Gateway 엔드포인트(endpoints) 생성
- ✅ S3 파일 업로드를 통한 Lambda 트리거(Trigger)
- ✅ 최소 권한 원칙(least privilege)을 적용한 IAM 역할 구성
- ✅ CloudWatch 로깅 자동 설정
- ✅ 실제 호출(invocations)을 통한 모든 과정 테스트
소요 시간: 45분 (읽기 20분 + 실습 25분)
비용: $0 (Lambda 프리 티어 기준)
난이도: 중급 (Intermediate)
서버리스의 세계로 떠나봅시다! 🚀
💔 문제점: 유휴 서버에 지불하는 비용
경각심을 일깨우는 순간
월간 AWS 청구서 검토 중. 무언가 계산이 맞지 않습니다:
EC2 인스턴스 (EC2 Instances):
- file-processor (t3.medium) → $30.37/month
실제 컴퓨팅 시간: 하루 12분
...
총합: 사용 시간이 1% 미만인 서비스에 월 $54 지불.
Lambda를 사용하면 동일한 워크로드가 월 $1 미만으로 줄어듭니다. 오타가 아닙니다. 1달러 미만입니다.
EC2가 적절하지 않은 경우:
❌ 이벤트 기반 처리 (Event-driven processing): 파일 업로드 → 처리 → 완료
❌ 트래픽이 낮은 API (Low-traffic APIs): 시간당 수십 건의 요청
❌ 예약된 작업 (Scheduled tasks): 하루 또는 한 시간에 한 번 실행
❌ 웹훅 핸들러 (Webhook handlers): 외부 이벤트를 대기
❌ 데이터 변환 (Data transformations): 입력 → 변환 → 출력
익숙한 상황인가요? 이 작업들을 Lambda로 옮겨봅시다.
🌟 AWS Lambda란 무엇인가?
간단한 정의
Lambda = 트리거(Trigger)가 발생할 때만 코드가 실행됩니다. 서버가 없습니다. 패칭(Patching)도 필요 없습니다. 스케일링(Scaling) 설정도 필요 없습니다.
이렇게 생각해보세요:
- EC2는 집에 있든 없든 매달 비용을 지불해야 하는 아파트를 임대하는 것과 같습니다.
- Lambda는 실제로 숙박한 밤에 대해서만 비용을 지불하는 호텔 객실과 같습니다.
Lambda의 작동 방식:
트리거 (API 호출, S3 업로드, 스케줄) (Trigger)
↓
AWS가 함수를 실행 (밀리초 단위) (AWS spins up your function)
...
Lambda + Terraform = 완벽한 조합
왜 Lambda에 Terraform을 사용할까요?
- 함수의 구성을 버전 관리 (Version control) 할 수 있습니다.
- 환경 간에 일관된 배포 (Consistent deployments) 가 가능합니다.
- 함수와 함께 IAM 역할 (IAM roles) 을 정의할 수 있습니다 (Article 9 기술!)
- 연결된 리소스 (Connected resources) (API Gateway, S3, CloudWatch)를 하나의 설정 파일에 담을 수 있습니다.
📋 사전 요구 사항
시작하기 전에:
- ✅ Terraform 설치 완료 (Article 2)
- ✅ AWS 자격 증명 (Credentials) 설정 완료
- ✅ VPC 및 보안 그룹 (Security Groups)에 대한 이해 (Article 6)
- ✅ 기본적인 Python 지식 (Lambda 코드 작성용)
🏗️ 우리가 구축할 것
┌─────────────────────────────────────────────────────┐
│ 우리의 아키텍처 │
│ │
...
두 개의 Lambda 함수:
- Hello API - API Gateway를 통한 HTTP 엔드포인트(endpoint), JSON 반환
- S3 Processor - S3에
.txt파일이 업로드될 때 트리거(Trigger)됨
소스 코드 (Source Code)
이 기사에서 사용된 전체 소스 코드와 Terraform 설정은 GitHub에서 확인할 수 있습니다:
simplynadaf / terraform-by-sarvar
Terraform 시리즈
🚀 Terraform By Sarvar
기초부터 고급 개념까지 아우르는 완전한 Terraform 튜토리얼 시리즈
📖 시리즈 읽기 • 🌐 포트폴리오 • 💼 LinkedIn
📚 시리즈 개요
이 저장소(repository)에는 Terraform By Sarvar 튜토리얼 시리즈를 위한 Terraform 코드 예제만 포함되어 있습니다.
⚠️ 중요: 이 저장소에는
.tf파일과 인프라 코드만 포함되어 있습니다. 기사는 dev.to에 게시되며, 여기에 저장되지 않습니다.
📖 dev.to에서 시리즈 읽기: https://dev.to/sarvar_04/series/36963
🎯 학습 내용
- ✅ 코드로서의 인프라 (Infrastructure as Code (IaC)) 기초
- ✅ Terraform 기초부터 고급 개념까지
- ✅ AWS 리소스 프로비저닝 (provisioning)
- ✅ 베스트 프랙티스 (Best practices) 및 실무 패턴
- ✅ 프로덕션 환경에 적합한 설정 (Production-ready configurations)
📊 시리즈 진행 상황
📖 아티클 시리즈
📘 기초 (Foundation) (Articles 1-5) ✅ 완료
- Terraform 및 IaC 소개 - ✅ 게시됨
- 설치 및 설정 - ✅ 게시됨
- 첫 AWS 리소스 - ✅ 게시됨
- Terraform 상태 이해하기 - ✅ 게시됨
- 변수 및 출력값 - ✅ 게시됨
📗 실제 인프라 (Real Infrastructure) (Articles 6-10)
시작하기 (Getting Started)
로컬 머신에서 프로젝트를 실행하려면 다음 단계를 따르세요:
- 저장소 복제(Clone)하기:
git clone https://github.com/simplynadaf/terraform-by-sarvar.git
- 프로젝트 디렉토리로 이동하기:
cd terraform-by-sarvar/articles/08-lambda-serverless
🔧 1단계: Lambda 함수 작성하기 (Write the Lambda Functions)
Terraform을 사용하기 전에 실제 코드가 필요합니다. lambda/ 디렉토리를 생성하세요:
mkdir -p lambda
lambda/hello.py - 간단한 API 핸들러:
import json
def lambda_handler(event, context):
...
lambda/s3_processor.py - 업로드된 파일을 처리합니다:
import json
import urllib.parse
...
핵심 사항 (Key points):
lambda_handler는 AWS가 호출하는 진입점 (entry point)입니다.event는 트리거 데이터 (HTTP 요청, S3 이벤트 등)를 포함합니다.context는 런타임 정보 (요청 ID, 함수 이름, 메모리 등)를 가집니다.- 항상
statusCode를 포함한 적절한 응답을 반환해야 합니다.
🔧 2단계: Terraform 설정 (Terraform Configuration)
main.tf - 여기는 전체 인프라 구성입니다:
terraform {
required_version = ">= 1.0"
required_providers {
...
archive 프로바이더 (provider)에 주목하세요. Terraform은 이를 사용하여 Python 파일들을 배포 패키지로 압축(zip)합니다. 수동으로 압축할 필요가 없습니다.
Lambda 코드 패키징:
data "archive_file" "hello_lambda" {
type = "zip"
source_file = "${path.module}/lambda/hello.py"
...
archive_file 데이터 소스 (data source)는 플랜(plan) 시점에 zip 파일을 생성합니다. Python 코드를 변경하면 Terraform이 해시(hash) 변경을 감지하고 자동으로 재배포합니다.
🔧 3단계: IAM 역할 (IAM Role) (제9조 지식 적용)
resource "aws_iam_role" "lambda_role" {
name = "${var.project_name}-lambda-role"
...
주요 결정 사항:
AWSLambdaBasicExecutionRole: CloudWatch Logs 접근을 위한 AWS 관리형 정책 (managed policy)입니다. 모든 Lambda에는 이것이 필요합니다.- 커스텀 S3 정책 (Custom S3 policy): 우리의 특정 버킷에 대해서만
GetObject및PutObject권한을 부여합니다. 제9조에 따른 최소 권한 원칙 (Least privilege)을 적용합니다. - 역할 수락 정책 (assume role policy)은 "오직 Lambda 서비스만이 이 역할을 사용할 수 있음"을 명시합니다. 사람이나 다른 서비스는 사용할 수 없습니다.
🔧 4단계: Lambda 함수 (Lambda Functions)
resource "aws_lambda_function" "hello" {
filename = data.archive_file.hello_lambda.output_path
function_name = "${var.project_name}-hello"
...
이러한 설정의 이유:
source_code_hash: 코드가 변경될 때 Terraform이 재배포(redeploy)를 수행하도록 합니다. 이 설정이 없으면 업데이트를 감지하지 못합니다.timeout = 10(Hello 함수용: API 호출은 빨라야 함),timeout = 30(S3 프로세서용: 파일 처리에 더 많은 시간이 필요함)memory_size = 128(Hello 함수용: 최소 사양),256(S3 프로세서용: 더 많은 처리 능력 필요)handler = "hello.lambda_handler"형식은파일명.함수명입니다.
🔧 Step 5: CloudWatch Log Groups
resource "aws_cloudwatch_log_group" "hello_lambda" {
name = "/aws/lambda/${aws_lambda_function.hello.function_name}"
retention_in_days = 7
...
Lambda는 로그 그룹을 자동으로 생성하지만, Terraform으로 관리되는 그룹을 사용하면 다음과 같은 이점이 있습니다:
- 제어 가능한 보관 기간 (무한정이 아닌 7일)
terraform destroy시 적절한 정리(cleanup)- 비용 제어 (오래된 로그가 쌓이지 않음)
🔧 Step 6: S3 Bucket with Lambda Trigger
resource "aws_s3_bucket" "lambda_trigger" {
bucket = var.s3_bucket_name
...
중요한 세부 사항: aws_lambda_permission은 버킷 알림(bucket notification)보다 먼저 정의되어야 합니다. depends_on이 이를 보장합니다. 이 설정이 없으면 권한이 아직 존재하지 않기 때문에 S3가 Lambda를 호출할 수 없습니다.
filter_suffix = ".txt"는 .txt 파일 업로드만 함수를 트리거한다는 의미입니다. .jpg를 업로드하면 아무 일도 일어나지 않습니다. 이는 Lambda가 동일한 버킷에 다시 파일을 쓸 경우 발생할 수 있는 예기치 않은 무한 루프를 방지합니다.
🔧 Step 7: API Gateway
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기