본문 바로가기

프로그래밍

AWS EC2 INSTANCE SCHEDULER로 INSTANCE 자동으로 켜고 끄기

AWS EC2 INSTANCE SCHEDULER로 INSTANCE 자동으로 켜고 끄기

banner

  • 소속된 개발팀에서 데스크탑을 개발서버(DB포함)로 사용하고 있었다. 해당 장비들 대부분 노후화되었고 일부는 인터넷 연결이 간헐적으로 끊켜 재부팅을 해줘야 다시 연결되는 상황이었다. 우여곡절이 있었지만 AWS의 EC2를 개발서버로 도입하자고 제안드렸고 승인이 떨어졌다. 모든 것을 혼자서 구축해야하지만 방대하면서도 자세한 AWS의 매뉴얼, 구글링 그리고 나보다 먼저 삽질하신 분들의 글을 믿고 진행했다.
  • EC2를 사용하여 개발서버를 구축하고자 제안할 수 있었던 이유는 다음과 같은 경험이 있었기 때문이다. 코드스쿼드 백엔드 과정 중 학생들은 스프링부트를 사용하여 만든 웹 애플리케이션을 배포할 외부 서버가 필요했다. 1인당 1대의 EC2인스턴스를 할당해주셨다. 이 때 경험했던 프로세스는 다음과 같았다.
    1. AWS의 IAM을 통해 코드스쿼드 루트 계정 밑으로 내 계정이 생성된다
    2. 스스로 사용할 EC2 인스턴스를 생성하고 관리한다
    3. 저녁 8시 이후에 running중인 인스턴스의 정보가 코드스쿼드 슬랙 특정 채널로 알림으로 전달된다
  • 그 때의 경험했던 것을 떠올리며 핵심 키워드 검색과 AWS의 매뉴얼을 토대로 개발서버를 구축하고 있다. 개인적으로는 EC2만 사용하고 있었지만 이번 개발서버 구축을 통해 IAM, Lambda, CloudWatch 등을 맛보았다.
  • 이 글에서 다룰 부분은 EC2 인스턴스 스케줄러를 사용하여 EC2 인스턴스를 업무시간(오전9시~오후6시)에 맞게 켜고 끄는 것을 자동화하는 것이다.
  • 이 다음 글에서는 인스턴스 스케줄러가 동작함에 따라 EC2 인스턴스의 상태[pending, running, stopping, stopped ..]가 변경되는데 이를 슬랙 메시지로 받을 수 있게 하는 방법을 다룰 것이다.
  • 좌충우돌 삽질기다. 정확하지 않은 정보들이 있다. 그래도 [무작정 따라하기]시리즈처럼 일단 따라하면 기능이 동작할 수 있게, 내가 나중에 다시 찾아보고 따라할 수 있게 썼다. 잘못된 부분이나 더 나은 방법이 있다면 말씀 부탁드립니다.

목차

1. 루트 관리자 계정 생성

2. IAM 그룹 및 사용자 생성

3. EC2 생성 및 실행

4. AWS Instance Scheduler 적용


1. 루트 관리자 계정 생성

  • 루트 관리자라고 특별한 생성 방법이 있는 것은 아니다. 그냥 AWS에 가입하면 된다. 추후 생성될 IAM 그룹을 관리할 계정을 지칭해서 루트 관리자라고 한다.

2. IAM 그룹 및 사용자 생성

2.1 IAM 그룹 생성

  • IAM을 쉽게 말하면 AWS 리소스(이 글 기준에서는 EC2)에 대한 권한을 관리하는 것이라 보면 된다. 루트 계정(이하 관리자) 아래에 생성되는 계정들은 관리자가 지정한 정책에 따라 리소스 사용에 대한 권한을 부여받는다. 예를 들면 관리자가 설정한 정책에 따라 EC2 인스턴스를 생성할 수 있는 권한은 없지만 EC2 인스턴스에 접속할 수 있다거나 중지시킬 수 있다.
  • 서비스 - IAM - 액세스 관리 - 새로운 그룹 생성을 통해 팀에서 사용할 IAM 그룹을 생성한다.
    AWS_SERVICE_IAM_GROUP
    AWS_SERVICE_IAM_GROUP
    AWS_SERVICE_IAM_GROUP
  • 생성할 그룹에 허용해줄 정책을 선택해야 한다. 해당 그룹은 개발서버(EC2)에 대한 권한만 있으면 되므로 필터에 EC2를 입력하여 EC2와 관련된 정책을 검색한 뒤 AmazonEC2FullAccess 정책만 연결했다. 정책의 종류는 굉장히 많았으며 아마존의 모든 서비스에 대해 제공하는 것 같았다.
    AWS_SERVICE_IAM_GROUP
  • 검토 후 그룹을 생성한다. 아직 사용자를 추가하지 않았으므로 사용자가 0인 것을 확인할 수 있다.
    AWS_SERVICE_IAM_GROUP

2.2 IAM 그룹에 사용자 추가

  • 액세스 관리 - 사용자 - 사용자 추가를 통해 사용자를 추가한다.
    AWS_SERVICE_IAM_USER
  • 사용자 이름은 개발팀 정책에 따라 이메일로 할 것이다. 꼭 이메일이 아니어도 괜찮다. 사용자 이름은 개발서버 사용을 위해 AWS Management Console 접근에 필요한 ID다. 한 번에 여러 사용자를 추가할 수 있으므로 미리 팀원들의 이메일 또는 희망하는 ID를 수집 후 추가하면 된다.
  • 웹브라우저를 통해 개발서버로 접근할 것이므로 AWS Management Console 액세스만 허용한다. 콘솔 비밀번호는 사용자ID에 대한 비밀번호이므로 나중에 사용자 추가 후 사용자들에게 공유한다. 사용자 모두가 동일한 비밀번호를 쓸 것이 아니라면 비밀번호 재설정 필요를 체크하여 비밀번호를 재설정할 수 있게 한다.
    AWS_SERVICE_IAM_USER
  • 이전에 생성한 그룹을 선택한다.
    AWS_SERVICE_IAM_USER
  • 검토한 뒤 사용자를 생성하면 생성된 사용자의 목록과 로그인 방법을 이메일로 발송할 수 있는 기능이 제공된다. 마지막 화면에서 제공되는 주소(https://숫자.signin.aws.amazon.com/console) 접속하면 생성된 아이디와 비밀번호로 로그인할 수 있는 화면이 나온다.
    AWS_SERVICE_IAM_USER
    AWS_SERVICE_IAM_USER
    AWS_SERVICE_IAM_USER

2.3 사용자 권한 확인

  • 생성된 사용자로 로그인을 하게 되면 이전에 설정한 그룹의 정책에 의해 EC2서비스만 접근할 수 있다. 만약 권한이 없는 다른 서비스에 접근하면 다음과 같이 접근할 수 없음을 알려준다. 그에비해 EC2 서비스에는 원활하게 접근할 수 있다.
    AWS_SERVICE_IAM_USER
    AWS_SERVICE_IAM_USER

3. EC2 생성 및 실행

  • 서비스 - EC2를 선택한다.
    AWS_SERVICE_EC2
  • 우측 상단에 보면 아이디 옆에 리전명이 나와있다. AWS는 다양한 리전을 지원하고 있으며 한국에도 리전이 있다. 한국인이라고 무조건 서울 리전을 선택하는 것이 합리적인 것은 아니다. 만약 한국이 아닌 해외로 서비스를 한다면 서비스 국가와 가까운 리전을 선택할 수도 있기 때문이다. 나는 서울리전을 선택했다. 주의할 점은 서울 리전에 EC2 인스턴스를 생성했다고 해서 다른 리전에도 동일하게 생성되지 않는 것이다.
    AWS_SERVICE_EC2
  • 리전을 선택했다면 인스턴스를 생성한다.
    AWS_SERVICE_EC2
  • 개발서버는 linux를 사용할 것이며 이미지는 Amazon Linux AMI 2를 사용한다. Amazon Linux AMI는 2020년까지 지원, Amazon Linux AMI 2는 2023년까지 지원된다.
    AWS_SERVICE_EC2
  • 서버 사양은 각자의 상황에 맞게 고르자. 본인이 속한 팀은 t3.xlarge(4 cpu, 16GB)면 충분하여 이걸로 결정했다. t2와 t3 시리즈가 동시에 나와있는데 t3 시리즈가 t2의 차세대이며 가성비도 좋다.
    AWS_SERVICE_EC2
  • 인스턴스 세부 정보 구성에서 아래쪽에 있는 T2/T3 무제한활성화 체크를 풀어준다.
    AWS_SERVICE_EC2
  • 스토리지 역시 얼마든지 추가할 수 있지만 현재 상황에는 30GB면 충분하기에 30GB를 할당했다.
    AWS_SERVICE_EC2
  • 태그는 필요없어서 그냥 넘어간다
  • 보안 그룹 구성은 해당 EC2 인스턴스의 방화벽 정책을 구성하는 것이다. ssh 연결을 위해 22 포트, http와 https 연결을 위해 80, 443을 열어주었다. 소스는 0.0.0./0으로 했을 때 모든 사람이 해당 포트로 접근할 수 있다. 개발서버의 경우 특별한 이유가 없다면 사내에서 접근할 것이므로 개발팀에게 할당된 IP만 열어준다.
    AWS_SERVICE_EC2
  • 검토 후 시작하기를 누르면 키 페어를 선택하라고 한다. ssh로 EC2 인스턴스에 접근하려면 키 페어의 프라이빗 키 파일이 있어야 한다. 새 키 페어 생성을 선택한 뒤 적당한 이름을 입력하고 키 페어 다운로드를 통해 프라이빗 키를 다운받자. 해당 파일은 언제든지 aws에서 다운 받을 수 있다. 그러나 ssh로 접속할 때 필요하므로 적절한 위치에 잘 보관하자.
    AWS_SERVICE_EC2
  • 다음과 같은 화면이 보이면 정상적으로 생성된 것이다
    AWS_SERVICE_EC2
  • EC2 인스턴스 목록을 보면 생성된 인스턴스가 보이며 인스턴스의 상태는 pending(or running)일 것이다. 인스턴스의 상태가 running이 되면 정상적으로 부팅된 것이며 해당 인스턴스를 우클릭하여 연결을 선택한다.
    AWS_SERVICE_EC2
    AWS_SERVICE_EC2
  • 인스턴스에 연결하는 여러 방법이 있는데 EC2 인스턴스 연결을 선택하면 브라우저에서 인스턴스에 바로 접근할 수 있다. 사용자 이름은 ec2-user가 기본값이다.
    AWS_SERVICE_EC2
  • 익숙한 터미널 창이 브라우저를 통해 보이면 연결이 된 것이다.
    AWS_SERVICE_EC2
  • 인스턴스를 중지하고 싶다면 인스턴스 목록에서 중지하고 싶은 인스턴스를 우클릭 후 중지를 누르자. 중지(stop)종료(terminate)는 다르다. 만약 종료를 선택하면 인스턴스가 삭제된다.
    EC2 인스턴스의 라이프 사이클을 참고하면 어떤 상태를 가지는지 알 수 있다.
    AWS_SERVICE_EC2
    AWS_SERVICE_EC2

4. AWS Instance Scheduler 적용

  • AWS Instance Scheduler Mannual
  • 이 글을 쓰게 된 계기를 만들어준 매뉴얼이다. AWS의 매뉴얼은 꽤 상세하고 친절한 편이지만 그래도 모르는 용어가 난무하기 때문에 나만의 언어로 정리해서 미래에 반복될 수 있는 삽질을 줄이고 싶었다.

4.1 AWS CLI 설치

  • AWS CLI 1, AWS CLI 2가 있다. AWS CLI 2는 AWS CLI 1의 개선된 버전이다.별다른 이유가 없다면 AWS CLI 2를 설치한다.
    AWS_CLI
  • AWS CLI 2에 나와있듯이 Linux, MacOS, Windows 모두 지원한다. 본인의 OS 환경에 알맞게 AWS CLI 2를 설치한 뒤 AWS CLI 2가 잘 설치되었는지 Terminal에서 AWS CLI Version을 확인한다.
    AWS_CLI
    AWS_CLI
  • Windows의 경우 AWS CLI 2를 설치했지만 명령 프롬프트에서 aws --version의 명령이 동작하지 않는다면 환경변수에 AWS CLI 2 설치 경로를 추가한 뒤 다시 확인해본다.
    AWS_CLI

4.2 AWS CLI 설정

  • AWS로 이동하여 IAM 서비스를 선택한 뒤 IAM의 대시보드를 선택하면 아래와 같은 화면이 나온다. AWS에서 권장하는 보안 정책은 루트 액세스 키를 사용하지 않는 것이다. 그렇지만 진행을 위해 루트 액세스 키를 생성해보자. 보안 상태 - 루트 액세스 키 삭제 - 보안 자격 증명 관리에 들어간다. 추후에 AWS에서 권장하는 방식대로 루트 액세스 키 대신 다른 방식으로 액세스 키를 발급받는 방법을 추가해야겠다.
    AWS_CLI
  • 보안 자격 증명 - 액세스 키 - 새 액세스 키 만들기를 통해 즉시 액세스 키를 만들 수 있다. 액세스 키가 생성되면 액세스 키 ID보안 액세스 키를 적당한 곳에 옮겨둔다. 특히나 루트 액세스 키라서 유출되면 곤란하다. 액세스 키 ID보안 액세스 키는 AWS CLI 설정에 필요하다.
    AWS_CLI
    AWS_CLI
  • 다시 명령 프롬프트(또는 터미널)로 돌아와서 aws configure 명령을 실행하면 다음과 같이 aws_access_key_id, aws_secret_access_key, region, output을 입력하라고 나온다. 조금 전 생성한 액세스 키 ID보안 액세스 키를 순서대로 입력한다. region은 EC2를 생성했던 서울리전의 코드네임인 ap-northeast-2을 입력했다. 마지막으로 outputjson으로 설정을 하게 되면 홈디렉토리(~)아래에 .asw디렉토리가 생성되고 그 안에는 방금 우리가 설정한 값이 들어있는 config, credentials 파일이 생성된다. Windows의 홈디렉토리 경로는 C:\Users\PC사용자이름이다.
    AWS_CLI
    AWS_CLI
    AWS_CLI
    AWS_CLI

4.3 Instance Scheduler CLI 설치

  • AWS Instance Scheduler를 사용하려면 Instance Scheduler CLI를 설치해야 한다.
  • Instance Scheduler CLI에 접속하여 Install the Scheduler CLI항목에서 Scheduler CLI Package를 다운받는다.
  • Scheduler CLI Package는 파이썬으로 제작되었다. 따라서 해당 패키지를 설치하려면 파이썬이 필요하다. 본인 PC에 설치된 파이썬의 버전이 2.7.16인데 문제없이 잘 설치된다. 파이썬 2의 경우 최신 릴리즈가 2.7.17인데 파이썬 공식 홈페이지에서 다운받을 수 있다. 설치 후 명령 프롬프트에서 Python --version 명령을 실행하여 잘 설치되었는지 확인하자. 만약 정상적으로 실행되지 않으면 환경변수에 파이썬 설치 경로를 추가한 뒤 다시 해보자.
    AWS_CLI
    AWS_CLI
    AWS_CLI
    AWS_CLI
  • 다운받은 Scheduler CLI Package를 적당한 곳에 압축을 푼다. 명령 프롬프트에서 압축을 푼 경로로 찾아 간 뒤 python setup.py install을 실행하자. 주의할점은 파일 경로에 한글이 있을 경우 해당 경로 인코딩 문제가 발생하고 정상적으로 설치되지 않는다. 폴더명이 한글이라면 수정하면 되지만 Windows 사용자의 이름이 한글이라면 조금 귀찮아진다.
    AWS_CLI

4.4 AWS CloudFormation에서 스택 생성

  • CloudFormation은 AWS의 자원 생성과 배포를 자동화하는 도구다. 더 자세한 내용은 링크에 매우 자세히 나와있다. 해당 블로그의 내용은 발췌가 불가능하므로 링크로 대체한다.
  • 스택 생성은 다음 매뉴얼을 따라해야 한다. Instance scheduler deployment mannual
  • AWS에 로그인을 한 상태로 Launch Solution을 누른다. 그러면 자동으로 템플릿이 적용되어 스택 생성하는 화면으로 넘어간다. 자동으로 적용된 템플릿은 기본 리전이 US EAST(버지니아 북부)로 설정된다. 각자의 상황에 맞게 리전을 지정해주자. 나는 서울리전으로 변경했다.
    AWS_CloudFormation
    AWS_CloudFormation
  • 만약 Launch Solution 링크가 정상적으로 동작하지 않으면 아래에 있는 download template을 통해 템플릿을 다운받고 CloudFormation서비스로 찾아들어가서 스택생성을 통해 스택을 생성해준다. AWS_CloudFormation AWS_CloudFormation AWS_CloudFormation
    • 스택 이름은 Ec2instanceScheduler로 지정한다. 그리고 아래 파라미터 중 Region(s) 항목이 있는데 만약 아무것도 쓰지 않으면 현재 지정되어 있는 리전에서만 사용할 수 있는 스택이 생성된다. 나는 서울 리전에서만 사용할 것이므로 아무것도 적지 않았다. Region(s) 항목 바로 아래 Default time zone 항목이 있다. Default time zone의 기본값이 UTC이지만 국내 시간 기준으로만 사용할 것이기 때문에 UTC대신 Asia/Soeul로 설정하였다. Frequency(빈도)의 경우 필요하다면 더 짧게 조정해도 좋다. 나는 기본값인 5분을 그대로 사용할 것이다.
      AWS_CloudFormation
      AWS_CloudFormation
    • 만약 Default timezoneUTC면 스케줄러 동작시간을 UTC를 기준으로 작성해야 한다. 즉, 스케줄러 동작 시간을 설정할 때 UTC와 한국시간은 9시간 차이가 나므로 이를 고려하여 작성해야 한다.
    • 계속해서 파라미터 중 CloudWatch Logs 활성화 항목을 Yes로 설정하고 Started tags에는 state=startedStopped tags에는 state=stopped를 입력해준다. 다음으로 넘어가서 상세옵션은 건너뛰고 검토 항목으로 가면 제일 아래쪽에 IAM 리소스 생성에 대한 승인을 체크해주자. 그러면 스택을 생성할 수 있다. 스택 생성이 정상적으로 진행되었다면 스택 대시보드에서 생성된 스택 정보를 확인할 수 있다.
      AWS_CloudFormation
      AWS_CloudFormation
      AWS_CloudFormation

4.5 Scheduler CLI에서 period 및 schedule 생성

  • Windows 기준 Scheduler CLI를 설치한 폴더에 보면 instance-scheduler-cli-runner.py 파일이 있다. 명령 프롬프트에서 해당 파일을 통해 Scheduler CLI로 period, schedule을 생성할 수 있다.
  • 명령 프롬프트에서 instance-scheduler-cli-runner.py 파일이 있는 경로로 이동한다. 먼저 period를 생성해보자. 인스턴스를 끄고 켤 기간과 시간은 월~금, 오전9시~오후6시이다. 기본적으로 업무시간에 맞춰 자동으로 켜고 끌 것이다. 생성하는 명령어는 다음과 같다. python instance-scheduler-cli-runner.py create-period --name "weekdays" --begintime 09:00 --endtime 18:00 --weekdays mon-fri --stack Ec2instanceScheduler
  • --name은 지금 생성하는 period의 이름, --stack은 이전에 생성했던 스택의 이름이다. --weekdays는 요일을 지정하는 옵션이다. 요일 이외에도 다양한 옵션이 있으니 필요한 것을 골라 사용해보자. 명령이 제대로 실행되면 JSON 포맷의 형태로 결과를 반환한다.
    AWS_CloudFormation
  • 생성된 period는 AWS의 DynamoDB 서비스를 통해 확인할 수 있다. DynamoDB의 테이블 항목을 들어가면 2개의 테이블이 이미 만들어져 있을 것이다. 이는 CloudFormation의 템플릿에서 만들어둔 것이다. 그 중 ConfigTable을 선택하고 상단에 항목이라는 메뉴로 들어가면 방금 생성된 weekdays라는 period을 확인할 수 있다. 해당 테이블에는 period뿐만 아니라 schedule도 함께 볼 수 있다.
    AWS_CloudFormation
    AWS_CloudFormation
    AWS_CloudFormation
  • schedule을 생성할 차례다. 다시 명령 프롬프트로 돌아가서 다음 명령을 실행하면 schedule을 생성할 수 있다. python instance-scheduler-cli-runner.py create-schedule --stack Ec2instanceScheduler --name weekdayworking --region ap-northeast-2 --periods weekdays --timezone Asia/Seoul
  • --periods는 이전에 생성했던 period의 이름을 적어주고 --timezone의 경우 UTC 대신 Aisa/Seoul을 설정해주었다. --stack은 이전에 생성했던 스택의 이름, --region서울리전의 코드네임인 ap-northeast-2를 적어주었다. 정상적으로 생성되면 JSON 포맷 형태로 결과를 반환한다.
    AWS_CloudFormation
  • 마찬가지로 DynamoDB의 ConfigTable에 접근하여 방금 추가한 schedule이 있는지 확인해보자. type이 schedule인 workdayworking이 생성된 것을 확인할 수 있다.
    AWS_CloudFormation

4.6 EC2 인스턴스에 Schedule 태그 추가하기

  • EC2 인스턴스에는 태그를 추가할 수 있다. 태그를 통해 다수의 자원을 효과적으로 관리할 수 있다.
  • 이전에 생성한 Schedule(weekdayworking)을 EC2 인스턴스의 태그에 등록하여 스케줄링이 될 때 해당 인스턴스를 식별하여 스케줄링에서 의도한 동작을 수행하게 한다.
  • EC2 인스턴스 목록에서 Schedule 태그를 등록할 인스턴스를 선택한다. 그리고 아래 메뉴 중 태그를 선택한다. 태그 추가/편집을 눌러 새로운 태그를 추가하자. 태그 생성을 누르고 에는 Schedule을, 에는 이전에 생성한 Schedule의 이름을 추가한다. 나는 에 이전에 생성한 Schedule의 이름인 weekdayworking을 넣어주었다.
    AWS_CloudFormation
    AWS_CloudFormation
  • 만약 등록한 스케줄에 따라 잘 동작하는지 즉시 확인하려면 DynamoDB의 ConfigTable에 내가 등록한 period를 찾아 beginTime을 현재 시간과 가깝게 조정하자. 다만, 이전에 스택 생성할 때 frequency를 5분으로 설정했기 때문에 beginTime을 최소 5분 뒤의 시간으로 설정해야 정상적으로 스케줄링이 동작하는 것을 확인할 수 있다.
  • 인스턴스 스케줄러에 따라 정지된 인스턴스가 자동으로 다시 켜지는 것을 확인할 수 있다.
    AWS_CloudFormation
    AWS_CloudFormation
  • 다음 시리즈는 이렇게 스케줄러가 작동할 때 EC2 인스턴스의 상태가 바뀐다. 상태가 바뀔때마다 Slack의 특정 채널에서 인스턴스의 상태를 메시지로 받아볼 수 있게 해본다.