본문 바로가기
IT & Tech 정보

🚀 AWS Lambda + API Gateway 서버리스 애플리케이션 구현

by 지식과 지혜의 나무 2025. 5. 25.
반응형


안녕하세요!
이번에는 AWS Lambda와 API Gateway를 활용해 서버리스 애플리케이션을 구축하는 과정을 단계별로 정리해드립니다.
핸들러 함수 작성부터 IAM 역할 설정, API Gateway 연동, 배포 스크립트(CLI/CloudFormation) 예시까지 포함했습니다.



📋 목차
1. 아키텍처 개요
2. IAM 역할 생성
3. Lambda 함수 작성
4. AWS CLI로 함수 배포
5. API Gateway(HTTP API) 연동
6. 테스트 및 검증
7. CloudFormation 템플릿 예시
8. 실전 팁



1️⃣ 아키텍처 개요

Client ──▶ API Gateway ──▶ Lambda 함수 ──▶ DynamoDB / 외부 서비스

• API Gateway: HTTP 요청을 수신해 Lambda에 전달
• Lambda: 비즈니스 로직 실행
• IAM 역할: Lambda가 AWS 리소스에 안전하게 접근



2️⃣ IAM 역할 생성

# 1) 실행 역할(Role) 생성
aws iam create-role \
  --role-name lambda-exec-role \
  --assume-role-policy-document file://trust-policy.json

# trust-policy.json 내용 예시
# {
#   "Version": "2012-10-17",
#   "Statement": [{
#     "Effect": "Allow",
#     "Principal": { "Service": "lambda.amazonaws.com" },
#     "Action": "sts:AssumeRole"
#   }]
# }

# 2) 기본 실행 정책 연결 (로그 작성 권한)
aws iam attach-role-policy \
  --role-name lambda-exec-role \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole




3️⃣ Lambda 함수 작성

// index.js
exports.handler = async (event) => {
  console.log("Received event:", JSON.stringify(event));
  
  const name = event.queryStringParameters?.name || "World";
  const response = {
    statusCode: 200,
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ message: `Hello, ${name}!` })
  };
  
  return response;
};

• event.queryStringParameters에서 쿼리 파라미터 추출
• JSON 응답 구조



4️⃣ AWS CLI로 함수 배포

# 1) 핸들러 코드 패키징
zip function.zip index.js

# 2) Lambda 함수 생성
aws lambda create-function \
  --function-name hello-world \
  --runtime nodejs14.x \
  --handler index.handler \
  --zip-file fileb://function.zip \
  --role arn:aws:iam::123456789012:role/lambda-exec-role

# 3) 코드 업데이트 (함수 수정 시)
aws lambda update-function-code \
  --function-name hello-world \
  --zip-file fileb://function.zip




5️⃣ API Gateway(HTTP API) 연동

# 1) HTTP API 생성
API_ID=$(aws apigatewayv2 create-api \
  --name hello-api \
  --protocol-type HTTP \
  --target arn:aws:lambda:us-east-1:123456789012:function:hello-world \
  --query 'ApiId' --output text)

# 2) 권한 부여 (Lambda에 API 호출 권한 추가)
aws lambda add-permission \
  --function-name hello-world \
  --statement-id apigw-invoke \
  --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-arn "arn:aws:execute-api:us-east-1:123456789012:${API_ID}/*/*"

# 3) 배포(Stage 생성)
aws apigatewayv2 create-deployment \
  --api-id $API_ID

aws apigatewayv2 create-stage \
  --api-id $API_ID \
  --stage-name prod \
  --auto-deploy

# 4) 엔드포인트 확인
echo "Invoke URL: https://${API_ID}.execute-api.us-east-1.amazonaws.com/prod?name=AWS"




6️⃣ 테스트 및 검증

curl "https://${API_ID}.execute-api.us-east-1.amazonaws.com/prod?name=Lambda"
# -> {"message":"Hello, Lambda!"}

• CloudWatch Logs에서 Received event 로그 확인



7️⃣ CloudFormation 템플릿 예시

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal: { Service: lambda.amazonaws.com }
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

  HelloFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: hello-world
      Runtime: nodejs14.x
      Handler: index.handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile: |
          exports.handler = async (event) => {
            const name = event.queryStringParameters?.name || "World";
            return {
              statusCode: 200,
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({ message: `Hello, ${name}!` })
            };
          };

  HttpApi:
    Type: AWS::ApiGatewayV2::Api
    Properties:
      Name: hello-api
      ProtocolType: HTTP
      Target: !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:hello-world

  ApiDeployment:
    Type: AWS::ApiGatewayV2::Deployment
    Properties:
      ApiId: !Ref HttpApi

  ApiStage:
    Type: AWS::ApiGatewayV2::Stage
    Properties:
      ApiId: !Ref HttpApi
      StageName: prod
      AutoDeploy: true




8️⃣ 실전 팁
• 환경 변수 관리: Lambda 환경 변수에 DB 엔드포인트·비밀값 저장
• 버전·별칭(Alias): aws lambda publish-version + create-alias로 트래픽 분할 배포
• 모니터링: CloudWatch Alarms, X-Ray로 성능·지연 추적
• 패키지 최적화: 불필요 모듈 제거, Lambda Layer로 공통 라이브러리 공유



위 단계를 따라 하면
간단한 서버리스 REST API를 **“무상태 인프라”**로 운영할 수 있습니다.
다음 포스트에서 GitHub Actions CI/CD 파이프라인 구성 방법을 다뤄보겠습니다!

반응형