본문 바로가기
Cloud/AWS

[AWS]EC2 Auto start, Auto stop 하는 방법 (lambda, event bridge 사용)

by 양눈 2025. 2. 9.
반응형

lamda 함수를 사용하여 간단하게 ec2를 업무시간인 평일 08시~18시까지 시작하고 주말과 업무시간 외에는 끄도록 설정 하는 테스트를 해보았다. 

순서는 아래와 같다. 

1. 시간에 따라 ec2를 start, stop 하는 lamda 함수를 만든다. 
2. lamda함수에 ec2 관련된 IAM권한을 추가한다. 
3. Amazon EventBridge를 사용해서 해당 해당 함수를 실행하도록 규칙 및 스케줄을 설정 한다. 

1. Lambda 함수 생성

AWS Lambda에서 Python으로 코드를 작성하여 EC2 인스턴스를 주말에는 종료하고, 평일 오전 8시부터 오후 6시까지 실행되도록 설정합니다.

1) 함수생성 

2) IAM권한 추가 

2. Python 코드 작성 및 붙여넣기 

import boto3
import datetime

# EC2 클라이언트 생성
ec2 = boto3.client('ec2', region_name='ap-northeast-2')  # 서울 리전 (필요에 따라 변경)

# 제어할 EC2 인스턴스 ID 설정
INSTANCE_IDS = ['i-xxxxxxxxxxxxxxxxx']  # 대상 EC2 인스턴스 ID 입력

def lambda_handler(event, context):
    now = datetime.datetime.now()
    current_hour = now.hour
    current_weekday = now.weekday()  # 0: 월요일, 6: 일요일

    if current_weekday >= 5:  # 주말 (토요일:5, 일요일:6)
        print("주말이므로 EC2 종료")
        ec2.stop_instances(InstanceIds=INSTANCE_IDS)
    elif 8 <= current_hour < 18:  # 평일 08:00 ~ 18:00 사이
        print("업무 시간이므로 EC2 시작")
        ec2.start_instances(InstanceIds=INSTANCE_IDS)
    else:
        print("업무 시간이 아니므로 EC2 종료")
        ec2.stop_instances(InstanceIds=INSTANCE_IDS)

    return {
        'statusCode': 200,
        'body': 'EC2 instance schedule updated'
    }

deploy를 누를후 TEST를 눌러 본다 .
output에 아래와 같이 status code가 보여진다. 

3. Lambda 트리거 설정 (CloudWatch Events)

Lambda 함수를 일정에 맞게 실행하려면 Amazon EventBridge (CloudWatch Events) 를 사용합니다.

Amazon EventBridge 콘솔 접속 -> 규칙 생성

  1. 규칙 세부정보 정의 

2. 매 시간 실행 되도록 설정 
- cron(0 * * * ? *) (매 정각 실행)

3. 대상 선택 
- lamda함수 
- 생성한 함수를 선택 "ec2_stop_start"

4. 태그 구성 
5. 검토 및 생성 

#. CloudFomation으로 생성시 아래 코드를 사용하면 됩니다. 

AWSTemplateFormatVersion: '2010-09-09'
Description: EC2 인스턴스를 주말에는 종료하고, 평일 오전 8시~오후 6시까지 실행하는 Lambda & EventBridge 설정

Resources:

  # Lambda 실행을 위한 IAM 역할
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: LambdaEC2ControlRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: 
                - lambda.amazonaws.com
            Action: 
              - sts:AssumeRole
      Policies:
        - PolicyName: LambdaEC2ControlPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - ec2:StartInstances
                  - ec2:StopInstances
                Resource: "*"  # 보안을 위해 특정 인스턴스로 제한하는 것이 좋음
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"

  # Lambda 함수 생성
  EC2ScheduleLambda:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: EC2SchedulerLambda
      Runtime: python3.9
      Handler: index.lambda_handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Timeout: 10
      Code:
        ZipFile: |
          import boto3
          import datetime

          ec2 = boto3.client('ec2', region_name='ap-northeast-2')  # 원하는 리전으로 변경
          INSTANCE_IDS = ['i-0abcd1234efgh5678', 'i-1wxyz9876mnop5432']  # EC2 인스턴스 ID 입력

          def lambda_handler(event, context):
              now = datetime.datetime.now()
              current_hour = now.hour
              current_weekday = now.weekday()  # 0: 월요일, 6: 일요일

              if current_weekday >= 5:  # 주말 (토요일:5, 일요일:6)
                  print("주말이므로 EC2 인스턴스 종료")
                  ec2.stop_instances(InstanceIds=INSTANCE_IDS)
              elif 8 <= current_hour < 18:  # 평일 08:00 ~ 18:00 사이
                  print("업무 시간이므로 EC2 인스턴스 시작")
                  ec2.start_instances(InstanceIds=INSTANCE_IDS)
              else:
                  print("업무 시간이 아니므로 EC2 인스턴스 종료")
                  ec2.stop_instances(InstanceIds=INSTANCE_IDS)

              return {
                  'statusCode': 200,
                  'body': 'EC2 instance schedule updated'
              }

  # EventBridge (CloudWatch Events) 트리거 생성
  EC2ScheduleRule:
    Type: AWS::Events::Rule
    Properties:
      Name: EC2ScheduleRule
      Description: "매시간 실행하여 EC2 인스턴스를 스케줄링"
      ScheduleExpression: "cron(0 * * * ? *)"  # 매시간 실행
      State: ENABLED
      Targets:
        - Arn: !GetAtt EC2ScheduleLambda.Arn
          Id: "EC2SchedulerLambdaTarget"

  # Lambda에 EventBridge 트리거 연결
  PermissionForEventsToInvokeLambda:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref EC2ScheduleLambda
      Action: lambda:InvokeFunction
      Principal: events.amazonaws.com
      SourceArn: !GetAtt EC2ScheduleRule.Arn

Outputs:
  LambdaFunctionArn:
    Description: "EC2 스케줄러 Lambda ARN"
    Value: !GetAtt EC2ScheduleLambda.Arn

  EventRuleArn:
    Description: "CloudWatch Events 규칙 ARN"
    Value: !GetAtt EC2ScheduleRule.Arn
반응형

댓글