Lambda로 EC2 제어하기 (1) 인스턴스 시작하고 중지하기

Yihoon·2024년 6월 4일
0

AWS활용기

목록 보기
6/7

이 포스팅을 쓰게 된 건 이 한 줄에서 시작된다...

원래 Lambda와 Eventbridge를 활용하여 주기적으로 간단한 파이썬 코드를 실행시키려 했는데, 레이어 용량 문제로 실행이 되지 않는 대참사가 벌어진 것.
패키지를 뜯어서 손보려 했으나 그건 도저히 못 하겠고, 대안으로 EC2를 사용해서 코드를 돌리는 방법을 택했다.

실행 스케줄에 맞춰서 EC2를 켜고, EBS에 저장해 둔 코드를 실행하고, 실행 후 EC2를 다시 중지하는 무식한 방법. 그 모든 제어는 Lambda가 담당한다.
사실 나의 경우는 이게 최선이라고 판단한 거지만, 누군가가 이 방법을 응용해서 무척 요긴한 솔루션이 탄생할 지도 모르니 그 구현 과정을 정리해 본다.

1편에서는 간단하게 인스턴스를 시작/중지하는 방법을 다룰 것이며,
2편에서는 인스턴스에 실제 쉘 스크립트를 전달하는 방법을 다룰 것이다.

2편은 여기!

EC2

먼저 인스턴스를 하나 만들자. 나의 경우 간단한 파이썬 파일 실행이 목적이기 때문에 Amazon Linux 환경을, 인스턴스 유형은 t2.micro를 사용하였다.


그 외 보안 세팅 등은 각자 상황에 맞게 하자. 어차피 Lambda가 접근할 거라 Public으로 설정할 필요는 없다.
준비를 마쳤다면 해당 인스턴스의 ID를 복사하자.

IAM

이제 Lambda가 EC2를 실행할 수 있도록 IAM을 세팅해야 한다.
여담이지만 초보자에게 가장 어려운 건 각 서비스들을 구축하는 것보다도 IAM으로 적절한 권한과 정책을 부여하는 과정인 것 같다...
먼저 EC2 시작/정지를 위한 정책을 만들자.

나는 start_stop_ec2라는 이름의 정책을 만들었고, json문을 아래와 같이 작성해 주었다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:Start*",
                "ec2:Stop*"
            ],
            "Resource": "*"
        }
    ]
}

이제 이 정책을 역할과 연결해 준다.

Lambda

마지막으로 람다 함수를 구현하자. python 3.9를 기준으로 설명하겠다.
나의 경우는 인스턴스를 시작하는 함수, 그리고 인스턴스를 중지하는 함수를 따로 만들었는데,
다음으로 설명할 코드를 제외하고 나머지 구성은 모두 동일하다.

  • 사전 준비사항: labmda에 올릴 boto3 레이어

아래 내용을 참고하여 코드를 작성하자.
먼저 인스턴스를 시작하는 코드는 다음과 같다.

import boto3
region = 'ap-northeast-2' #서울 리전
instances = ['i-************'] #인스턴스 ID는 반드시 리스트로 입력하기
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.start_instances(InstanceIds=instances) #인스턴스 시작
    print('started your instances: ' + str(instances))

다음으로 인스턴스를 중지하는 코드는 다음과 같다. 밑에서 둘째 줄만 다르다.

import boto3
region = 'ap-northeast-2'
instances = ['i-************'] #마찬가지로 인스턴스 ID는 리스트로 입력
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.stop_instances(InstanceIds=instances) #인스턴스 중지
    print('stopped your instances: ' + str(instances))

이어서 boto3 레이어를 업로드하고,

실행 시간은 조금 넉넉하게 10초 이상으로 잡아 주자. (3초로 잡아 두어도 나의 경우에는 문제가 없었긴 하나, 참고한 소스들에서는 10초 이상을 권장하고 있었다.)

마지막으로 앞에서 만든 역할을 Lambda와 연결한다. 리소스 요약 화면에서 Allow:ec2:Start, Allow:ec2:Stop 두 권한이 알맞게 부여되어 있는지 확인하자.

이렇게 함수를 Deploy하고 정상 작동하는지 테스트해 보자. EC2 인스턴스 목록에 들어가서 시작/중지가 잘 되는지 확인해 보자.
이제 인스턴스를 켜고 끌 수 있으니, 원하는 타이밍에 스크립트만 전달해 주면 된다. 2편에서 계속!

profile
딴짓 좋아하는 데이터쟁이

0개의 댓글

관련 채용 정보