AWS

[AWS] Lambda를 활용한 요금 SNS 서비스 구축하기 핸즈온 리뷰

graph-dev 2023. 11. 27. 16:45
728x90

 

 

AWS Lambda

 

람다는 AWS의 서버리스(Serverless) 상품군입니다.  간단하게, Hands-on에서 배운 내용을 복습해보고자 합니다.

 

목표는 SNS 서비스를 만드는 것입니다. AWS의 요금을 매일 기록해서 문자로 보내주는 서비스입니다. 람다를 사용한다면, 서버리스 이므로 API 호출될 때만 요금이 부과되며, 별도의 구동을 위한 서버가 필요하지는 않습니다. 서버를 사용하는 것 맞는데, 서버를 만들 필요가 없다는 것이죠. 바로, 완전 관리형 서비스라는 말이죠.

 

AWS Lambda를 검색합니다.

 

먼저 아키텍처를 그려봅니다.

 

핸즈온 아키텍처

 

 

 

 

복잡해보이지만, 하나씩 살펴보면 간단합니다.

 

먼저, AWS에서 Cost를 검색해서 들어갑니다. 아래는 제 비용 관리 화면입니다.

비용 관리 홈

 

따끈따끈한 신규 고객이므로 $0.00이 나올 것입니다.

 

AWS Lambda로 이동

 

함수를 생성해보겠습니다. 이름은 testSMS로 할게요.

런타임 Python 3.11, 아키텍처 x86_64, 기본 실행 역할 변경은 기본 Lambda 권한을 가진 새 역할을 생성하도록 합니다.

Lambda 함수 생성 화면

 

그리고 함수 생성버튼을 누릅니다. 생성이 완료되면, 아래와 같은 다이어그램이 나타납니다.

 

이 화면에서, 아래로 가면 소스 코드를 편집할 수 있는 영역이 보입니다.

람다 함수의 코드 소스 편집기

 

 

여기에 아래의 코드를 넣습니다. 

import json
import boto3
from datetime import datetime
from dateutil.relativedelta import *

def lambda_handler(event, context):
    client = boto3.client('ce')
    
    today = datetime.today()
    this_month_first_day = datetime(today.year, today.month, 1)
    
    str_today = str(today.strftime('%Y-%m-%d'))
    str_first_day = this_month_first_day.strftime('%Y-%m-%d')
    
    #Cost Expolorer
    result = client.get_cost_and_usage(
        Granularity= 'MONTHLY',
        TimePeriod={
        'Start': str_first_day,
        'End': str_today
        },
        Metrics=[ 'UnblendedCost',] 
    )
    
    #Send Message with Amazon SNS
    sns = boto3.client('sns', region_name='ap-northeast-1')
    cost = float(result['ResultsByTime'][0]['Total']['UnblendedCost']['Amount'])
    cost_round = round(cost, 2)
    str_cost = str(cost_round)
    
    message_content  = "금일 %s 일 기준 이번 달 사용 금액은 %s 달러입니다."%(str_today, str_cost)
    
    #Change phone number 
    sns.publish(PhoneNumber="+8210휴대폰번호입력", Message=message_content ) 
    
    return {
        'statusCode': 200,
        'body': json.dumps('Message was sent successfully!')
    }

 

이렇게 Python으로된 Handler 메서드를 잘 채워주고, 중간에 휴대폰번호를 입력해주면 됩니다.

 

코드 소스를 저장하려면, Deploy 버튼을 눌러주셔야 합니다. 안그러면 새로고침시 다시 처음으로 돌아가버립니다.

코드는 Deploy로 저장

 

배포가 언제부터 저장하는 건지 모르겠지만, AWS는 그렇다고 하니 그렇게 합니다. 이렇게 함수가 업데이트되었다고 우측 사진처럼 나오면 일단 코드가 잘 저장된 것입니다.

 

다음은, Test라는 버튼을 누르면 나오는 이벤트 설정 영역입니다. 테스트 이벤트는 람다 함수 호출을 위한 JSON 객체이며, 이것으로 함수의 호출 결과를 확인할 수 있습니다. 이벤트 이름은 testEvent로 하고, 저장을 누르겠습니다.

 

 

 

이렇게 저장하고 다시 Test를 누르면 아래와 같은 에러가 발생합니다.

 

An error occurred (AccessDeniedException) when calling the GetCostAndUsage operation: User: arn:aws:sts::647939632718:assumed-role/testSMS-role-3czipujm/testSMS is not authorized to perform: ce:GetCostAndUsage on resource: arn:aws:ce:us-east-1:647939632718:/GetCostAndUsage because no identity-based policy allows the ce:GetCostAndUsage action

 

먼저 권한이 없다는 것으로 보입니다. 작업을 더 해줘야겠습니다.

 

구성 > 권한으로 이동합니다. 실행 역할에 있는, 역할 이름 중 testSMS로 시작하는 것을 누릅니다.

실행 역할 누르기

 

우측 사진에 있는 것처럼, inline policy(인라인 역할)을 추가해주겠습니다. 

 

역할 설정 세부 내용

 

Cost Explorer Service에서 GetCostAndUsage를 추가하고, SNS Service에서는 Publish + All 리소스를 선택하여 추가합니다. 다음을 누르고, 이렇게 만든 정책을 forTestSMSPolicy 이라고 명명합니다. 정책 생성을 누릅니다.

 

정책 생성

 

이렇게 정책이 생성됩니다. 권한이 매우 최소화된 것을 확인할 수 있습니다. 단 두 개의 Action으로 설정되어있고, JSON파일로도 확인할 수 있습니다.

 

 

SNS 서비스에 휴대폰 번호 등록

휴대폰 번호를 등록하겠습니다. SNS 서비스로 이동합니다.

전화번호 등록

 

문자로 전달된 인증번호까지 입력해주시면 인증이 성공되며, 전화번호가 위와 같이 '확인됨'으로 정상 등록됩니다.

 

트리거 추가: API Gateway

이제 람다 함수로 가서, 트리거를 추가해주겠습니다. 이벤트가 발생하면 잡아주는 친구입니다. 이번에 사용할 트리거는 API Gateway입니다.

트리거 추가

 

아래와 같이 트리거를 구성해서 추가합니다.

트리거 구성 옵션

 

 

최종적으로 람다 함수 구조는 아래와 같이 설정하고, 아래 트리거도 확인할 수 있습니다.

람다 함수 구조와 트리거

 

이제 이 트리거를 확인해보겠습니다. API 엔드 포인트를 눌러봅니다.

메시지 성공적으로 보냈습니다

 

이렇게 메시지가 성공적으로 보냈다는 말이 나타날 것입니다.

 

이제 다시 한번 테스트를 누릅니다. 아래와 같이 결과가 나오면 성공입니다.

 

 

등록된 휴대폰 번호로 문자로도 옵니다. 아래는 예시 문자 사진입니다. 국외 발신이라 속도가 좀 느리네요.

문자 예시

 

아직 오지 않고 있는데, 문자가 오면 다시 추가하겠습니다.