본문 바로가기
Computer Science/AWS

7장 서버 없이 알람 서비스 만들기

by netjung 2020. 12. 15.

chapter7

AWS 람다 서비스

특징

  1. 완전 관리형 서비스

    하드웨어, 네트워크, 운영체제까지 알아서 관리해주는 서비스

  2. 유연한 확장성

    다른 AWS 서비스들을 호출하여 자신만의 서비스 만들 수 있다.

  3. 고가용성

    99.9999% 가용성

  4. 유휴 용량없음

    요청이 올 때만 프로비저닝, 응답이 없을 때 비용 청구 되지 않는다.

  5. 마이크로서비스 호환성

    서버리스 컴퓨팅 함수로 특정 역할이나 활동을 수행하기 위해 작고 독립적인 코드 단위로 개발 가능하다. → 마이크로서비스의 전달 수단으로 사용 가능하다.

람다 함수 만들기

실습 아키텍처

AWS웹콘솔 - JSON 데이터 → AWS람다 - 입력받은 데이터 → AWS웹콘솔

실습 요약

  1. 람다 함수 만들기
  2. 람다 함수 입력에 해당하는 이벤트 테스트 구성
  3. 람다 함수 코드 작성
  4. 람다 함수 테스트 실행과 결과 확인

람다 서비스로 접속하여 람다 함수를 생성하여 줍니다.

그리고 함수 코드를 작성 할 수 있는데, 여기에

exports.handler=async (event) => {
    console.log(event.text)
    return event.text
}

이와 같이 작성하였습니다.

테스트를 눌러 실행하여보면

다음과 같이 함수 생성과 실행, 출력 모두 성공 된 것을 확인할 수 있습니다.

람다 함수 기반 문자 알림 서비스

실습 아키텍처

AWS 웹콘솔 → JSON 데이터 →AWS 람다 → SNS호출 → Amazon SNS → 핸드폰

실습 요약

  1. SNS 서비스 실행 권한을 위한 IAM 정책 설정
  2. SNS 람다 함수 만들기
  3. SNS 람다 이벤트 구성
  4. SNS 람다 함수 테스트

우선 정책 생성을 위해 IAM으로 가서 SNS 서비스를 찾아 쓰기 선택후 정책을 생성합니다.

이에 연결해줄 역할을 만들어야 합니다.

다음으로 람다 함수를 만듭니다.

만든 후 이벤트 구성을 하고자 드롭박스를 클릭하여

{
  "text": "let's win contes
  "number": "+821087654321"
}

보내고자 하는 메시지, 보내고자 하는 핸드폰의 번호를 입력합니다.

하단으로 이동하여 자바스크립트 코드를 입력합니다.

// AWS를 실행시키기 위한 라이브러리를 가져옵니다.
const AWS = require('aws-sdk');

// 이전과 다른 부분이 있다면 context와 callback이라는 변수가 추가되었습니다.
// callback은 현재 함수가 끝났다는 것을 알려줍니다.
exports.handler = (event, context, callback) => {

    // 위에 입력했던 json 값이 event, 즉 input으로 들어옵니다.
    // params에 Message와 PhoneNumber 변수를 선언합니다.
    const params = {
        Message: event.text,
        PhoneNumber: event.number
    };

    // SNS SDK를 가져옵니다.
    // SNS 서비스에서 메시지를 보내는 것은 한정된 리전에서만 사용할 수 있기 때문에 region을 도쿄 리전으로 설정해야 합니다.
    // 이를 위해 인자값으로 region에 도쿄 리전의 식별자인 'ap-northeast-1'을 입력합니다.
    const publishTextPromise = new AWS.SNS({
        apiVersion: '2010-03-31',
        region: 'ap-northeast-1'
    }).publish(params).promise();

    // SDK를 실행합니다.
    publishTextPromise.then(
        function(data) {

            // 메시지가 있다면 첫번째에 null, 두번째에 메시지를 리턴합니다.
            callback(null, "Message is " + data.MessageId);
        }).catch(
            function(err) {

                // 에러가 있다면 err를 리턴합니다.
                callback(err);
            });
};

이후 테스트를 실행하면 지정된 메시지가 지정된 번호로 전송되게 됩니다.

람다 함수 기반 AWS 지출 요금 모니터링

실습 아키텍처

AWS 웹콘솔 -SNS 호출 → AWS 람다 → Amazon SES → 이메일 전송

AWS 람다 ↔ 비용 탐색기 당월 요금 정보 요청, 요금 정보 반환

실습 요약

  1. SES 설정
  2. SES 서비스 실행 권한을 위한 IAM 정책 설정
  3. SES 람다 함수 생성
  4. SES 람다 코드 작성
  5. SES 이벤트 구성
  6. SES 클라우드 와치 이벤트 연동
  7. SES 트리거 구성

SES를 매니지 콘솔에서 검색하여 접속합니다

Identify→ Email Address

수신 받고자 하는 이메일을 입력합니다.

그리고 수신확인을 하면

증명이 되었다고 표시가 됩니다.

IAM에서 정책을 생성합니다.

하나는 비용 검색을 위한 Cost Explorer,

하나는 메일을 보내기 위한 SES

정책 검토 후 정책 생성을 완료합니다.

정책에 연결할 역할을 만들어 줍니다.

이와 같이 작성하여 역할도 만드는 것을 완료하였습니다.

이번엔 람다 함수를 작성하여 줍니다.

람다 함수를 생성을 완료한 모습입니다.

// AWS SDK를 가져옵니다.
var AWS = require('aws-sdk');
// 이메일 서비스를 이용하기 위해 SDK의 지역을 버지니아로 설정합니다.
AWS.config.update({region: 'us-east-1'});

// Event는 우리가 위에서 입력한 JSON 데이터를 가지고 있습니다.
// 함수가 끝날 때 오류가 없다면 callback(null), 오류가 있다면 callback("에러 메시지")를 리턴합니다.
// 일반적으로 return과 같은 역할을 합니다.
exports.handler = function(event, context, callback) {

    // Data 객체를 생성합니다.
    // 인자를 주지 않으면 오늘 데이터를 가져옵니다.
    var today = new Date();

    // Data 객체를 문자열로 바꾸어줍니다.
    var todayISOString = today.toISOString();

    // 연도, 월, 날짜를 생성자로 주어 new Date(year, month, day)를 통해 Data 객체를 만들 수 있습니다.
    // 오늘 날짜에서 -1을 주어 어제 데이터를 가져온 후 문자열로 바꾸어줍니다.
    var yesterdayISOString = new Date(today.getFullYear(), today.getMonth(), today.getDate()-1).toISOString();

    // 아래 문자열은 2018-12-22T21:42:27.218Z와 같이 날짜 정보와 시간 정보, 그리고 타임존 정보도 같이 가져오게 됩니다.
    console.log("firstDayOfMonth:" + todayISOString);
    console.log("firstDayOfNextMonth:" + yesterdayISOString);

    console.log("=========== slice string ============");

    // 뒤쪽의 필요 없는 텍스트를 자르고 YYYY-MM-DD 포맷으로 텍스트를 가져옵니다.
    todayISOString = todayISOString.slice(0, 10);
    yesterdayISOString = yesterdayISOString.slice(0, 10);

    console.log("firstDayOfMonth:" + todayISOString);
    console.log("firstDayOfNextMonth:" + yesterdayISOString);

    // 시작일을 어제로, 그리고 종료일을 오늘로 설정합니다.
    // End로 설정된 날은 포함되지 않습니다.
    // 가격 정보 기준은 Daily로 설정합니다.
    var costParams = {
        TimePeriod: {
            Start: yesterdayISOString,
            End: todayISOString,
        },
        Granularity: 'DAILY', Metrics: ['UnblendedCost'],
    };

    // AWS Cost Explorer를 통해 가격 정보를 가져옵니다.
    new AWS.CostExplorer().getCostAndUsage(costParams, function(err, costResult) {
        if (err) {
            callback(err);
        }
        console.log(JSON.stringify(costResult));

        // 가격 정보를 yesterdayBilling 변수로 선언합니다.
        // ResultsByTime은 가격 정보를 배열로 가지고 있기 때문에 가장 최근 데이터인 index 0번 데이터를 가져옵니다.
        var yesterdayBilling = costResult.ResultsByTime[0].Total.UnblendedCost.Amount;
        console.log("billing amount" + yesterdayBilling);

        var params = {
            Destination: {
                ToAddresses: [event.sender],
            },
            Message: {
                Body: {
                    Text: {
                        Data: "AWS Price: " + yesterdayBilling + "$",
                    },
                },
                Subject: {
                    Data: yesterdayISOString + "AWS Billing",
                },
            },
            Source: event.receiver,
        };

        new AWS.SES().sendEmail(params, function(err, result) {
            if(err) {
                callback(err);
            }
            else {
                callback(null);
            }
        })
    });
};

이제 함수 코드를 다음과 같이 입력 해주었습니다.

이번엔 테스트 이벤트 구성을 생성해주었습니다.

sender에는 인증한 이메일, receiver에는 받을 이메일을 지정합니다.

테스트를 해보면 메일이 잘오는 것을 확인 할 수 있습니다.

클라우드 와치 이벤트 연동

트리거 추가를 통해 매일 이메일이 오도록 해보겠습니다.

다음과 같이 트리거를 추가해줍니다.

추가된 것을 확인할 수 있습니다.


당신이 지금 알아야 할 AWS - 이영호, 한동수 지음 을 참고하였습니다.