AWS에서는 EC2에 대해서 정말 많은 기능을 제공하고 있지만, 특이하게도 스케쥴링 기능을 네이티브로 제공하고 있지 않습니다. 필요하면 알아서 만들어서 사용하라고 가이드는 하고 있습니다. (관련 문서)

이러나 저러나, 사용자가 직접 만들어야 한다면 역시 태그를 기반으로 하는 스케쥴러가 가장 좋은 방법일 것입니다. 그래서 본 글에서는 OpsNow의 개발계에서 사용하는 EC2 스케쥴링 방법과 그 사용 방법을 소개하고자 합니다.

Lambda 함수

EC2 스케쥴러와 같이 소규모의 코드를 이용하기 위해서는 Lambda가 가장 적합합니다. 1년 내내 하루 수십번을 사용해도 1달러조차 나오지 않을테니까요! 저희는 Python의 boto3 패키지를 이용하여 스케쥴러를 운용하고 있습니다.

import boto3
import logging
log = logging.getLogger()
log.setLevel(logging.INFO)ec2 = boto3.resource(‘ec2’)

def lambda_handler(event, context):

try:
log.info(event)

tag_key = event[‘Key’] tag_val = event[‘Value’]

filter = [{‘Name’: f’tag:{tag_key}, ‘Values’:[tag_val]}] instances = ec2.instances.filter(Filters=filter)

ids = [instance.id for instance in instances]

if len(ids) == 0:
log.info(‘There is no target instances’)
return 200

log.info(ids)

if tag_key == ‘AutoStart’:
response = ec2.instances.filter(InstanceIds=ids).start()
elif tag_key == ‘AutoStop’:
response = ec2.instances.filter(InstanceIds=ids).stop()
else:
response = ‘something is wrong!’

log.info(response)
return response

except Exception as err:

log.error(err)
return 500

Code language: Python (python)

특정 팀에서만 사용할 스케쥴러가 아니라면 역시 입력값을 받아서 누구나 사용할 수 있게 하는 것이 좋겠지요. 그래서 스케쥴러를 이용하려면 사전에 정의된 AutoStartAutoStop 태그 키를 선택하고 태그 값을 다르게 제공함으로써 인스턴스 그룹을 동시에 시작, 중지할 수 있게 하였습니다.

위 Lambda 함수는 VPC 내에 위치할 필요는 없습니다. 함수 실행 시간만 20초 정도로 잡아놓으면 해당 태그에 속한 모든 인스턴스를 시작, 중지할 수 있습니다.

IAM 정책

함수를 적절하게 실행하기 위해서는 EC2을 시작, 중지할 수 있는 권한이 있어야 하겠지요. 그리고 태그 기반으로 인스턴스를 조회하기 위한 권한도 필요할 겁니다.

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ec2Scheduler",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:StartInstances",
"ec2:StopInstances"
],
"Resource": "*"
}
] }
Code language: JSON / JSON with Comments (json)

위와 같은 정책을 생성하고 EC2 스케쥴러 Lambda 함수의 롤에 할당해주면 됩니다.

EventBridge 규칙

스케쥴러의 기증은 준비되었으니, 이제 주기적으로 시작, 중지를 전달하기 위한 EventBridge 규칙을 설정합니다.

이벤트 규칙 설정

주기적으로 EC2를 실행하기 위한 일정을 생성합니다. 그리고 이벤트를 전달할 Lambda 함수를 선택하면 됩니다.

JSON 텍스트에 주목하세요!

Lambda 함수를 지정하고 꼭 설정해야 할 중요한 포인트는 바로 입력 구성입니다. 함수가 외부 입력을 받게 설정되어 있으므로, 그에 맞게 이벤트를 제공해야 하기 때문입니다. 앞서 함수에서 정의한 것처럼, EC2 시작을 위한 것이므로 Key는 AutoStart를 제공하고 Value는 EC2에서 사전에 정의해놓은 특정 값을 제공하면 됩니다.

즉, 방금 설정한 규칙은 EC2가 AutoStart를 태그 키로 가지고, Value를 태그 값으로 가지는 모든 인스턴스에 대해서 적용되어, 정해진 시간에 자동 시작하게 됩니다. 그리고 EventBridge 규칙을 하나 더 생성해서 AutoStop 키를 제공하면 자동 중지가 되는 것입니다. 이러한 과정을 반복함으로써 같은 태그를 가지는 인스턴스 그룹들에 대해서 스케쥴링을 여럿 구성할 수 있습니다.

{"Key":"AutoStart","Value":"service_1"} -- 주중08
{"Key":"AutoStop", "Value":"service_1"} -- 주중21
{"Key":"AutoStart","Value":"service_2"} -- 주중09
{"Key":"AutoStop", "Value":"service_2"} -- 주중18
{"Key":"AutoStart","Value":"batch_1"} -- 주말02
Code language: JavaScript (javascript)

이처럼 함수에 제공할 입력만 바꿔가면서 같은 함수를 재사용할 수 있기 때문에 많은 사람들이 부담없이 사용할 수 있게 됩니다. 😁