AWS

SNS와 Lambda를 이용한 AutoScaling Group 인스턴스 EBS 스냅샷 생성

Joon0464 2021. 7. 4. 17:39

SNS란?

  • 클라우드에서 손쉽게 알림 기능을 설정하고 작동 및 전송할 수 있는 AWS 서비스이다.
  • 게시 - 구독 메시징 방식이며 Push 메커니즘을 사용하여 클라이언트에게 알림을 전달한다.
  • 각 주제는 SNS 앤드포인트를 식별하는 고유한 이름을 가지기 때문에 게시자는 메시지를 게시하고 구독자는 알림을 받도록 등록이 가능하다.
  • 구독자는 구독하는 주제에 게시된 모든 메시지를 수신하며, 특정 주제에 대한 알림은 모든 구독자가 동일하게 수신한다.

사용 사례

  • AutoScaling Group에 Scale in, Scale out과 같은 특정 변경 사항이 발생했을 때, 사용자가 알림을 받을 수 있다.
  • SNS를 사용하여 구독자에게 이메일 또는 문자메시지로 특정 뉴스 헤드라인을 Push할 수 있다.
  • 업데이트가 가능함을 알리는 메시지를 앱으로 전송할 수 있다.

구성도 및 동작 방식

실습

1. AutoScaling Group 생성(단순 조정 정책)

1.1 시작 템플릿 생성

EC2 콘솔에서 시작 템플릿을 생성한다. 시작 템플릿이 있어야 AutoScaling Group을 생성할 수 있다.
이름 및 태그를 지정한다.
원하는 대로 설정하면 된다.
보안 그룹은 22번 포트정도만 열어주면 된다. 테스트할 때 ssh로 접속할 것이기 때문이다.
다음과 같이 시작 템플릿이 생성되었다.

1.2 AutoScaling Group생성

EC2 콘솔에서 AutoScaling Group을 생성한다.
이름을 지정하고 시작 템플릿은 직접 생성한 템플릿을 지정한다.
VPC를 지정한다. ELB를 생성하지 않고 간단한 테스트정도로 구축할 것이므로 Public Subnet으로 지정하였다.
이번 실습에서는 로드벨런서를 지정하지 않았다. 만약 지정한다 해도 구성도나 기능상에 전혀 문제가 없다.
인스턴스 용량을 지정하고 조정 정책은 이후에 단순 조정 정책으로 따로 설정할 것이므로 없음을 선택한다.
특별히 설정하지 않고 다음으로 넘어간다.
원하는 태그를 지정하고 다음으로 넘어간다.
마지막으로 검토를 마친뒤 AutoScaling Group를 생성한다.
ASG를 생성하면 인스턴스가 정상 실행된다.

1.2 단순 조정 정책을 위한 CloudWatch Alarm 생성

CloudWatch 콘솔에서 경보를 생성한다.
지표 선택을 클릭한다.
EC2 > AutoScaling 그룹별 경로로 이동하여 JoonTest의 CPUUtilization 지표를 선택한다.
지표를 위와 같이 설정하고 다음으로 넘어간다.
SNS 설정은 이후에 할 것이므로 제거를 클릭하고 다음으로 넘어간다.
생성할 경보의 이름을 지정하고 다음으로 넘어간다.
검토를 마치고 경보를 생성한다.
이번에는 CPU가 낮을 때 울릴 경보를 생성한다. 지표는 CPUHIGH 경보를 생성할 때와 동일하게 선택한다.
나머지 설정은 동일하며 지표 이름만 CPULOW로 설정하고 다음으로 넘어간다.
마지막으로 검토를 하고 경보를 생성한다.
다음과 같이 경보가 생성된다.

1.3 AutoScaling Group에 단순 조정 정책 적용

EC2 콘솔에서 AutoScaling Group탭에 생성했던 JoonTest를 클릭한다.
자동 조정탭에 Create dynamic scaling policy를 클릭한다.
CPULOW 경보를 선택하고 Scale in 정책으로 인스턴스를 1개 제거하도록 설정한다.
CPUHIGH 경보를 선택하고 Scale out 정책으로 인스턴스를 1개 추가하도록 설정한다.
다음과 같이 경보가 생성된다.

2. SNS 설정

2.1 SNS 주제 생성

SNS 콘솔에서 주제를 생성한다.
다음과 같이 설정하고 나머지는 기본값으로 생성한다.
주제가 생성되었다.

2.2 AutoScaling Group과 SNS 주제 연동

EC2 콘솔에서 AutoScaling Group탭에 생성했던 JoonTest를 클릭한다.
활동 탭에서 알림 생성을 클릭한다.
생성했던 SNS 주제를 지정하고 이벤트 유형을 시작만 지정한 다음 생성한다.
알림이 다음과 같이 등록된다.

3. Lambda 함수에 필요한 IAM 역할 생성

IAM 콘솔에서 역할 만들기를 클릭한다.
Lambda를 선택하고 다음으로 넘어간다.
첫 번째 정책으로 AWSLambdaExecute를 선택한다.
두 번째 역할로 EC2 Full 권한을 선택한다.
원하는 태그를 지정하고 다음으로 넘어간다.
검토 페이지에서 역할 이름을 지정하고 검토를 마친후 역할을 생성한다.
해당 역할에는 AutoScaling Group에 의해 생성되는 인스턴스에 태그를 지정하거나 스냅샷을 생성하기 위한 EC2FullAccess가 포함되어있다.

4. Lambda 함수 생성

이 작업에서는 AutoScaling Group에 의해 Scale out 이벤트가 발생하면 SNS가 호출할 AWS Lambda를 생성할 것이다. Lambda 함수가 실행되면 새로 생성된 인스턴스에 태그를 지정하고 EBS 볼륨의 스냅샷을 생성한다.

AWS Lambda 콘솔에서 함수 생성을 클릭한다.
함수 이름을 지정하고 런타임 언어는 Python 2.7을 선택하며 기존에 생성한 역할을 선택한 뒤 함수를 생성한다.
AutoScaling Group에 의해 생성되는 새로운 인스턴스에 태그 지정 및 EBS 볼륨 스냅샷 생성을 하기 위한 코드를 작성한다.

from __future__ import print_function

import json, boto3

def lambda_handler(event, context):
    print("Received event: " + json.dumps(event, indent=2))
    
    # AutoScaling 이벤트 알림에서 EC2 Instace ID를 추출한다.
    message = event['Records'][0]['Sns']['Message']
    autoscalingInfo = json.loads(message)
    ec2InstanceId = autoscalingInfo['EC2InstanceId']
    
    # 새로 생성되는 인스턴스에 연결된 EBS 볼륨 스냅샷을 뜬다.
    ec2 = boto3.resource('ec2')
    for v in ec2.volumes.filter(Filters=[{'Name': 'attachment.instance-id', 'Values': [ec2InstanceId]}]):
        description = 'Autosnap-%s-%s' % ( ec2InstanceId, v.volume_id )

        if v.create_snapshot(Description = description):
            print("\t\tSnapshot created with description [%s]" % description)
            
    # 새로 생성되는 인스턴스에 태그를 추가한다.        
    ec2 = boto3.client('ec2')
    response = ec2.create_tags(
        Resources=[ec2InstanceId],
        Tags=[{'Key': 'Snapshots', 'Value': 'Created'}]
    )
    print ("***Tag added to EC2 instance with id: " + ec2InstanceId)

    return ec2InstanceId

구성 탭의 일반구성의 편집을 클릭한다.
위와 같이 수정하고 저장한다.

5. SNS를 트리거로 지정

Lambda 함수에서 트리거 추가를 클릭한다.
SNS를 트리거로 선택하고 직접 생성했던 SNS 주제를 선택하고 추가를 클릭한다.

6. Scale Out하여 동작 테스트 해보기

6.1 실행중인 인스턴스 접속 및 Stress 패키지로 CPU 부하 발생하기

EC2에 접속한다. 자세한 접속 방법은 https://cumulus.tistory.com/2?category=953833 을 참고 바람

 

sudo amazon-linux-extras install epel -y
sudo yum install stress -y

 인스턴스에서 상단의 명령어를 입력해준다. 첫 번째 명령어 실행 후 다음 두 번째 명령어는 동작까지 시간이 좀 걸릴 수 있다.

스트레스 패키지를 사용하여 CPU에 부하를 발생시킨다.

stress --cpu 2 --timeout 5000

6.2 테스트 결과

CloudWatch에서 CPUHIGH 경보가 울린다.
새로운 인스턴스가 생성된다.
EBS 볼륨 스냅샷이 생성된다.
태그도 자동으로 생성된 것을 볼 수 있다.