AWS EC2 중지/시작 자동화: 사람도 퇴근, 서버도 퇴근! 태그 기반 EC2 스케줄링

최근 전 세계적으로 클라우드 기술이 폭발적으로 성장하면서, 개인과 기업 모두 이를 적극 도입하고 있습니다. 가장 큰 이유 중 하나는 초기 인프라 구축 비용을 크게 줄이고, 필요한 만큼만 유연하게 인프라를 확장하거나 축소할 수 있다는 데 있습니다. 전통적인 온프레미스 환경에서는 서버를 구매/설치/관리하는 데 막대한 비용과 시간이 들었지만, 클라우드에서는 사용한 만큼 과금(Pay-as-you-go) 되는 특성을 통해 한층 탄력적인 운영이 가능합니다.

특히 개발/테스트용 서버는 실제로 업무 시간에만 쓰이는 경우가 많습니다. 그럼에도 별도의 스케줄 없이 사용한다면 불필요한 인프라 비용이 계속 발생하게 됩니다. 이번 글에서는 AWS EventBridge + Lambda를 활용해 특정 태그가 달린 EC2 인스턴스를 업무 시간에만 자동으로 시작(ON) 하고, 퇴근 후나 주말에는 자동으로 중지(OFF) 하는 방법을 소개합니다.

아키텍처

  • Event Bridge: 특정 시간에 Lambda 함수를 호출하여 EC2 중지 또는 시작 이벤트를 발생시키는 역할
  • Lambda 함수: 트리거에 의해 실제 EC2 중지 또는 시작하는 로직을 수행
  • EC2: 중지 또는 시작 대상 서버

동작 흐름

※ 업무 시간은 월-금 09:00 ~ 18:00으로 정의

※ 스케줄링 적용을 원하는 EC2에 태그 정보("Scheduler": "OfficeHours")를 미리 설정

EC2 시작

  1. Event Bridge 규칙을 통해 업무 시작 시간(월-금, 09:00)에 Lambda로 동작("action": "start")과 태그 정보("Scheduling": "OfficeHours")를 전달
  2. Lambda 함수에서 해당 태그가 달린 EC2 인스턴스 검색 후, StartInstances API 호출하여 일괄 시작

EC2 중지

  1. Event Bridge 규칙을 통해 퇴근 시간(월-금, 18:00)에 Lambda로 동작("action": "stop")과 태그 정보("Scheduling": "OfficeHours")를 전달
  2. Lambda 함수에서 해당 태그가 달린 EC2 인스턴스 검색 후, StopInstances API 호출하여 일괄 중지

구성 절차 실습

※ 사전에 EC2는 생성하여 존재한다고 가정합니다.

※ 본 실습 과정에서는 Lambda 함수 런타임 환경은 Python 3.13을 사용하며, 리전은 현재 EC2가 위치하는 리전을 대상으로 합니다.

스케줄링 적용 EC2 태그 설정

해당 EC2 태그에 아래의 Key: Value를 추가합니다.

추후 Lambda 함수 구성 시, 아래의 Key/Value 쌍이 존재하는 EC2 인스턴스를 대상으로만 스케줄링 적용되도록 구성합니다.

  • Scheduling: OfficeHours

Lambda 함수 생성

이미지와 같이 AWS Management Console에서 Lambda 함수 생성 화면으로 접속한 후, 아래와 같이 설정합니다.

  • 함수 이름: EC2-Scheduler-By-Tag
  • 런타임: Python 3.13
  • 아키텍처(선택사항): arm64
    (기본 값인 x86_64로 진행하셔도 무방하며, arm64의 경우 본 예제에서 구성하는 단순 EC2 스케줄링 구성에는 문제가 없으나, 임의로 코드 변경 시 호환성 이슈가 발생할 수 있습니다.)
  • 실행 역할: 기본 Lambda 권한을 가진 새 역할 생성

Lambda 함수 권한 추가

Lambda 함수를 통해 EC2를 시작/중지하기 위해서는 Lambda 함수에 할당된 IAM 역할(Role)에 EC2 목록 조회, 시작/중지에 대한 IAM 정책(Policy)을 추가해야 합니다.

Lambda 함수 상단의 구성 – 권한 – 실행 역할 이름을 클릭합니다.

권한 추가 – 인라인 정책 생성을 클릭합니다.

화면 우측 상단의 JSON을 클릭하고, 아래의 정책을 기입합니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": "*"
        }
    ]
}

아래 이미지와 같이 정책이 추가된 것을 확인할 수 있습니다.

Lambda 코드 소스

import boto3
import json

ec2 = boto3.client('ec2')

def lambda_handler(event, context):
    # EventBridge에서 전달받은 파라미터
    action = event.get("action")    # start 또는 stop
    tag_key = event.get("tagKey")   # 예: Scheduling
    tag_value = event.get("tagValue")  # 예: OfficeHours
    
    # 필수 파라미터 유무 확인
    if not action or not tag_key or not tag_value:
        return "필수 파라미터 누락: action, tagKey, tagValue."
    
    # 특정 태그가 달린 인스턴스 조회
    response = ec2.describe_instances(
        Filters=[
            {
                'Name': f'tag:{tag_key}',
                'Values': [tag_value]
            }
        ]
    )
    
    # 인스턴스 ID 추출
    instance_ids = []
    for reservation in response['Reservations']:
        for instance in reservation['Instances']:
            instance_ids.append(instance['InstanceId'])

    if not instance_ids:
        return f"해당 태그가 구성된 EC2 인스턴스를 찾을 수 없습니다. {tag_key}={tag_value}"
    
    # 액션에 따라 start 또는 stop
    if action == "start":
        ec2.start_instances(InstanceIds=instance_ids)
        return f"EC2 시작됨: {instance_ids}"
    elif action == "stop":
        ec2.stop_instances(InstanceIds=instance_ids)
        return f"EC2 중지됨: {instance_ids}"
    else:
        return "잘못된 action입니다. 'start' 또는 'stop' 둘 중 하나만 입력 가능합니다."

아래 이미지와 같이 Lambda 코드 작성 후 좌측의 Deploy 버튼을 클릭하여 배포합니다.

Lambda 코드 테스트

작성한 Lambda 함수의 코드가 정상적으로 작동하는지 테스트합니다.

아래와 같이 테스트 이벤트를 작성합니다.

EC2 시작(Start) 테스트

{
  "action": "start",
  "tagKey": "Scheduling",
  "tagValue": "OfficeHours"
}

EC2 시작 테스트 버튼을 클릭하면, 아래와 같이 해당 EC2가 시작된 것을 확인할 수 있습니다.

EC2 중지(Stop) 테스트

{
  "action": "stop",
  "tagKey": "Scheduling",
  "tagValue": "OfficeHours"
}

EC2 중지 테스트 버튼을 클릭하면, 아래와 같이 해당 EC2가 중지된 것을 확인할 수 있습니다.

EventBridge 규칙 추가

Amazon EventBridge 콘솔 – 버스 – 규칙 – 규칙 생성을 클릭합니다.

아래와 같이 이름 및 일정을 정의한 후, 규칙 생성으로 이동을 클릭합니다.

EC2 시작 규칙

다음 이미지와 같이 규칙 세부 정보를 정의합니다.

  • 이름: Start-EC2-On-OfficeHours
  • 규칙 유형: 일정
  • 규칙 생성으로 이동 버튼 클릭

일정 패턴은 cron식을 기반으로 정의합니다.

현재 업무 시간은 한국 시간(KST) 기준 월-금 09:00이며, cron식은 UTC를 기준으로 설정되어야 하므로 다음과 같습니다.

  • cron(0 0 ? * MON-FRI *)

아래 이미지와 같이 현지 시간대로 변경하면, 정상적으로 월-금 09:00에 트리거하는 것으로 설정된 것을 확인할 수 있습니다.

  • 대상 유형: AWS 서비스
  • 대상 선택: Lambda 함수
  • 함수: EC2-Scheduler-By-Tag
  • 추가 설정
    • 입력 대상 구성: 상수(JSON 텍스트)
    • JSON으로 상수를 지정
{
  "action": "start",
  "tagKey": "Scheduling",
  "tagValue": "OfficeHours"
}

아래 이미지와 같이 일정 건너뛰기 이후, 규칙 생성 버튼을 클릭합니다.

EC2 중지 규칙

다음 이미지와 같이 규칙 세부 정보를 정의합니다.

  • 이름: Stop-EC2-On-OfficeHours
  • 규칙 유형: 일정
  • 규칙 생성으로 이동 버튼 클릭

일정 패턴은 cron식을 기반으로 정의합니다.

현재 퇴근 시간은 한국 시간(KST) 기준 월-금 18:00이며, cron식은 UTC를 기준으로 설정되어야 하므로 다음과 같습니다.

  • cron(0 9 ? * MON-FRI *)

아래 이미지와 같이 현지 시간대로 변경하면, 정상적으로 월-금 18:00에 트리거하는 것으로 설정된 것을 확인할 수 있습니다.

  • 대상 유형: AWS 서비스
  • 대상 선택: Lambda 함수
  • 함수: EC2-Scheduler-By-Tag
  • 추가 설정
    • 입력 대상 구성: 상수(JSON 텍스트)
    • JSON으로 상수를 지정
{
  "action": "stop",
  "tagKey": "Scheduling",
  "tagValue": "OfficeHours"
}

아래 이미지와 같이 일정 건너뛰기 이후, 규칙 생성 버튼을 클릭합니다.

Lambda 함수 확인

다시 Lambda 함수로 돌아와 보면, 아래 이미지와 같이 2개의 트리거가 정상적으로 생성된 것을 확인할 수 있으며, 정상적으로 구성되었다면 업무 시간인 월-금 09:00에 대상 태그가 설정된 EC2가 시작되며, 월-금 18:00에 중지되는 것을 확인할 수 있습니다.

참고 문서

이상으로, 클라우드 환경에서 비용을 절감하기 위한 EC2 스케줄링 방법을 살펴보았습니다.
EventBridge를 이용해 액션(start/stop)과 태그 정보를 함께 넘기면, 원하는 시간대에 특정 태그가 달린 인스턴스만 일괄적으로 제어할 수 있어 편리하게 사용할 수 있습니다. 개발/테스트 서버뿐 아니라, 필요한 경우 다양한 업무 시나리오에도 응용해보세요!

NDS는 많은 클라우드 경험을 통해 서비스 도입에 도움을 드릴 수 있습니다.

AWS 관련 문의 사항 또는 클라우드 전문가의 도움을 받고 싶으시다면, 지금 바로 NDS Sales팀으로 연락주시길 바랍니다.

cloud.sales@nongshim.co.kr

SA 유윤종