EC2 인스턴스 자동으로 켜고 끄기

개발자 왜?전·2020년 12월 15일
2

왜?

열심히 개발하던 나에게 어느날 이메일 하나가 찾아왔다.

AWS EC2 프리티어 750시간 중 85%의 사용량을 초과했다고 알려주는 이메일이었다.

당황했다. 750시간이면 하루 24시간으로 나눠도 31일이 넘는데 고작 15일 남짓한 기간에 사용량을 다 썼단다.

다시 잘 읽어보니 인스턴스당 750시간이 아니었다. FrontBack 두 개의 인스턴스를 유지하던 나에게 딱 맞는 계산이었다.

서둘러 요금제를 확인했다. 물론 750시간을 더 쓴다고 가정했을 때 서울 리전 기준으로 약 11달러정도였다. 이정도 가격이면 괜찮다고 생각했지만 그래도 사람들이 찾아올 시간에, 내가 개발할 시간에만 인스턴스들이 실행중이었으면 좋겠다는 생각을 했다.

자동화 하기

먼저 LambdaCloudWatch에 대해 이해가 필요하다.
AWS Lambda는 서버를 프로비저닝하거나 관리하지 않고도 코드를 실행할 수 있게 해주는 컴퓨팅 서비스다. 쉽게말해 코드를 등록해놓고 원하는 상황에 해당 코드가 실행되도록 할 수 있다는 소리이다.
CloudWatch는 AWS 리소스와 AWS에서 실시간으로 실행 중인 애플리케이션을 모니터링한다. 지표를 감시하고 설정된 값에 도달할 경우 경보를 보내거나 설정한 규칙에 따라 이벤트를 발생시킬 수 있다.

이 두가지를 가지고 작업을 시작한다.

IAM정책, 역할 생성

먼저 AWS의 리소스에 대해 접근하기 위해서 IAM이 필요하다. Lambda를 실행하기 위한 권한이 필요한 것이다.

먼저 정책을 만든다. IAM에 들어가서 왼쪽 메뉴에서 정책을 클릭 후 화면에서 정책 생성을 누르면 된다.

이후 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": "*"
    }
  ]
}


이후 정책검토를 누르고 원하는 이름을 적고 마무리 한다.

정책을 생성했으니 이제 역할을 생성할 차례이다.
정책과 마찬가지로 IAM 역할 메뉴에서 역할 만들기를 클릭한다.
이후 사용사례선택에서 Lamda를 선택 후 다음으로 넘어간다.

다음으로는 이전단계에서 만들어두었던 정책을 연결한다. (이전 정책을 ec2-on-off로 해두었다.)

다음 태그는 필요하다면 작성하고 검토에서 역할 이름을 잘 설정한 후 역할만들기를 클릭하면 역할이 만들어진다.

Lambda생성하기

AWS Lambda에 접속 후 함수생성 버튼을 클릭한다.
먼저 인스턴스를 끄는 lambda를 생성한다. 함수 이름을 끄는 함수에 걸맞는 이름을 지정한다. 런타임은 python을 선택한다. 권한은 기본 실행 역할 변경을 클릭 후 기존 역할 사용을 클릭 후 이전에 만든 역할을 선택 후 함수생성한다.

함수 생성을 완료했다면 이제 함수를 수정할 차례이다. 생성한 함수의 구성 탭에는 함수코드라는 항목이 있다. 이 곳에서 코드를 수정할 수 있다. 그전에 자신의 리전과 EC2의 인스턴스 ID가 필요하다.

코드에 아래와 같은 코드에 본인의 리전과 인스턴스 ID를 알맞게 넣으면 된다.

import boto3
region = 'us-west-1'
instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.stop_instances(InstanceIds=instances)
    print('stopped your instances: ' + str(instances))

해당코드는 stop에서 볼 수 있듯이 인스턴스를 중단하는 코드이다.

이후 해당 구성탭의 하단에 있는 기본설정에 제한시간을 10초로 바꿔준다.

이후 Lamda를 생성하는 과정을 한 번 더 반복한다. 인스턴스를 끄는 함수를 생성했으니 켜는 함수도 생성해야한다.

생성함수의 python코드는 다음과 같다. 이것또한 마찬가지로 해당 리전과 인스턴스 ID를 본인에 맞게 설정해준다.

import boto3
region = 'us-west-1'
instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.start_instances(InstanceIds=instances)
    print('started your instances: ' + str(instances))

Lambda 함수는 테스트 할 수도 있는데 원하는 함수를 클릭 후 뜨는 창에서 테스트를 클릭하면 된다.

해당 Lambda는 JSON코드를 사용하지 않기 때문에 테스트클릭 후 뜨는 modal창에서 생성을 클릭하면 된다. 이훟 다시 테스트를 클릭하면 테스트 결과가 나온다.

CloudWatch 생성하기

CloudWatch 규칙에 접속한다. CloudWatch의 왼쪽메뉴에서 이벤트 하위항목에 규칙이 있다. 해당 페이지에서 규칙생성을 클릭한다.

이후 뜨는 창에서 일정을 선택한다. 일정에서는 cron표현식과 고정비율이 있는데 매일 한 번 켜고 끄기 때문에 cron표현식을 사용했다. 설정에 어려움이 있다면 설명을 클릭하면 된다.
새벽 1시, 그러니까 1 AM에 인스턴스를 중단하고 싶기 때문에 아래와 같은 방식을 사용했다. 시간은 UTC를 사용하기 때문에 -9시간을 해주면 된다.

이후 해당 설정에 맞는 lambda 함수를 설정해준다. 위의 사진은 중단설정이므로 중단하는 Lambda 함수를 설정해줬다.

이후 해당 규칙의 이름과 설명을 설정하면 된다.

이 규칙을 만드는 것 또한 끄는 것과 켜는 것, 각각 만들어주면 된다.
시간 설정해당 Lambda설정에 유의하자.

확인

Lambda페이지에서 원하는 lambda를 선택 후 모니터링탭을 선택하면 아래와 같은 화면이 나온다. 이후 CloudWatch에서 로그보기를 클릭한다.

클릭하면 아래와 같은 창이 보이고 해당 lambda에 대한 로그 기록을 확인할 수 있다. 성공적으로 실행된 모습이다.

마무리

그러나 이미 85%를 넘었고 요금이 부과될 예정이다. 인스턴스 작동시간을 하루 12시간으로 설정하면 프리티어로 2개의 인스턴스를 운영할 수 있을 것이다. 그러나 사용자의 접속시간대를 쉽게 예측할 수 없다는 점으로 봤을 때 효율적인 운영인지에 대해 의문이 든다.

어렵게만 느껴진던 AWS였지만 정보가 잘 정리되어있었다. AWS의 다양한 기능을 다 써보기는 쉽지 않겠지만 내가 원하는 기능이 이미 구현되어 있음에 놀라움의 연속이었다. 어려워하지말고 하나씩 해봐야겠다.

profile
하고 싶어 개발하는, 능동개발자

0개의 댓글