본문 바로가기

AWS

AWS Lambda를 이용한 EC2 인스턴스 정기 시작, 중지

반응형

인스턴스 정기 시작, 중지 (Lambda)

  • 매일 출근할 때, 퇴근할 때 인스턴스를 수동으로 켰다 끄는 일은 다소 피곤할 수 있다. 파이썬과 AWS의 람다 서비스, 클라우드와치 서비스, EC2의 태그 기능으로 간단하게 지정된 시간마다 인스턴스를 실행시키고 종료시키는 행위를 자동화할 수 있다.
  • EC2 인스턴스를 정기적인 시간마다 자동으로 시작, 종료하는 파이썬 코드를 통해 자동화하는 작업을 실습해보았다.
  • Tag가 AutoStart: True일 시 정해진 시간마다 자동 시작되며, Tag가 AutoStop: True일 시 정해진 시간마다 자동 종료되는 Lambda 함수 + CloudWatch Event 스택을 구현해 볼 것이다.

전체적인 원리, 과정

  • 정해진 시간마다 실행, 종료시키고 싶은 EC2 인스턴스에 Tag를 부여하고, Python을 통해 해당 인스턴스가 Tag가 할당 되어 있으면 실행시키거나 종료시키는 Lambda 함수를 생성한다. 그리고 CloudWatch의 Event에서 CronJob을 발생시켜 특정 시간마다 Lambda 함수를 Trigger 시켜 Lambda 함수를 실행시킨다.
## 참고 사항 ##

## AWS에서 CronJob은 UTC 시간대이기 때문에 Seoul Region으로 적용시켜주기 위해 +9시간을 해주어야 한다.

## 월~금 19시 30분마다 동작시키고 싶다면
30 10 ? * MON-FRI *

1. IAM Policy 정의

 

2. IAM Role 생성

⇒ 정의한 IAM Policy를 Attach함

 

3. Lambda 함수 생성

: Auto Start 함수

: Auto Stop 함수

 

4. CloudWatch Event 생성

1. IAM

IAM Policy

  • IAM Policy를 생성해준다.

    Name : EC2_Auto_On_Off_Policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "ec2:DescribeInstances",
                "ec2:DescribeTags",
                "logs:CreateLogGroup",
                "logs:PutLogEvents",
                "ec2:DescribeInstanceStatus"
            ],
            "Resource": "*"
        }
    ]
}

 

  • 검토

 

 

IAM Role

  • Name : EC2_Auto_On_Off_Role
  • Service : Lambda 선택

 

  • Policy 연결

 

  • 확인

2. Lambda

  • 람다 함수를 생성해준다. 언어는 Python 3.8로 해준다.

 

EC2 Auto Start

  • 함수 생성

    Function Name : EC2AutoOnOff

    Runtime ( 실행 환경 ) : Python 3.8

    Permission : 기존 역할 사용 ( EC2_Auto_On_Off_Role )

 

  • 함수 코드 삽입

    vim Editor라면 :w 로 저장해준다.

    그 후, Deploy를 클릭한다.

import boto3
import logging

# setup simple logging for INFO
logger = logging.getLogger()
logger.setLevel(logging.INFO)

# define the connection
ec2 = boto3.resource('ec2', region_name='ap-northeast-2')

def lambda_handler(event, context):

    # all stopped EC2 instances.
    filters = [{
            'Name': 'tag:AutoStart',
            'Values': ['True']
        },
        {
            'Name': 'instance-state-name', 
            'Values': ['stopped']
        }
    ]

    # filter the instances
    instances = ec2.instances.filter(Filters=filters)

    # locate all stopped instances
    RunningInstances = [instance.id for instance in instances]


    # print StoppedInstances 

    if len(RunningInstances) > 0:
        # perform the startup
        AutoStarting = ec2.instances.filter(InstanceIds=RunningInstances).start()
        print("AutoStarting")
    else:
        print("Nothing to see here")

 

 

 

  • 기본 설정 편집

제한 시간을 3초 → 30초로 늘려준다.

 

  • Test 이벤트 생성

    이벤트 이름은 임의로 EC2AutoStartTest로 해주었다.

 

Test

  • 현재 Tag가 AutoStart : True 인 EC2 Instance 2대가 종료된 상태임을 확인할 수 있다.

 

  • Tag는 아래와 같이 설정되었음

 

  • 확인

    Lambda 함수 수행 결과 Logging 값에서 성공적으로 완료 되었다고 나오고 있다.

 

  • EC2 인스턴스 2대가 Lambda 함수에 의해 자동으로 실행되었다.

 

Auto Stop

import boto3
import logging

#setup simple logging for INFO
logger = logging.getLogger()        # Instance : logger, Module : logging, Method : getLogger()
logger.setLevel(logging.INFO)

# define the connection and set the region
# Instance : ec2, Module : boto3, Method : resource, Parameter : 'ec2', region_name : 'ap-northeast-2'
ec2 = boto3.resource('ec2', region_name='ap-northeast-2')

def lambda_handler(event, context):

    # All running EC2 instances.
    filters = [{
            'Name': 'tag:AutoStop',
            'Values': ['True']
        },
        {
            'Name': 'instance-state-name', 
            'Values': ['running']
        }
    ]

    # Filter the instances which are stopped
    instances = ec2.instances.filter(Filters=filters)

    # Get all id of running EC2 Instances
    RunningInstances = [instance.id for instance in instances]

    # Print the instances for logging purposes
    # Print RunningInstances 

    if len(RunningInstances) > 0:
        # Perform Shutdown EC2 Instances
        shuttingDown = ec2.instances.filter(InstanceIds=RunningInstances).stop()
        print(shuttingDown)
    else:
        print("Nothing to see here")

 

 

  • Auto Stop도 Auto Start와 동일하게 진행해주면 된다.

    Test 해본 결과 Logging에 성공적으로 람다 함수를 실행시켰다고 기록되었다.

 

  • 아래와 같이 2개의 Lambda 함수가 생성되었다.

 

3. CloudWatch events

  • CloudWatch Events를 이용해 자동으로 EC2 Instance를 실행, 시작할 수 있도록 스케줄링을 해줘야 설정한 시간에 맞게 자동화를 할 수 있다.

 

Auto Start Event 규칙 생성

  • 트리거 추가 클릭

 

  • 트리거 구성 → EventBridge ( CloudWatch Events ) 클릭

 

  • 새 규칙 생성
  • EC2 Auto Start
  • 규칙 유형 : 예약 표현식 ( CronJob )

 

  • 적용 된 모습

 

Auto Stop Event 규칙 생성

  • EC2AutoStop 규칙을 생성한다.
  • 규칙 유형 : 예약 표현식 ( CronJob으로 동작함 )
    • UTC 기준으로 계산해야 한다. KST와 9시간 차이나기 때문에 고려해줘야 함
    • 월요일 ~ 금요일까지 19시 (저녁 7시)에 해당 Lambda를 Trigger한다.

 

 

  • 적용

 

  • 확인

 

4. 결과

  • Ref

https://aws.amazon.com/ko/premiumsupport/knowledge-center/start-stop-lambda-cloudwatch/

https://www.rsupernova.com/how-to-auto-stop-and-auto-start-aws-ec2-instances-at-regular-intervals-using-aws-lambda/

https://aws.amazon.com/ko/premiumsupport/knowledge-center/stop-start-instance-scheduler/

반응형