What? 무슨 문제야?
최종 프로젝트 서버는 데브코스 규칙에 따라 일괄적으로 켜지고, 꺼지는 시간이 정해져있다.
평일에는 오전 9시에 서버가 켜지고, 오후 6시에 자동 종료되는데,
자동 종료된 이후 작업을 하고 싶을 때 '서버 켜주세요~' 라는 요청을 해야 하는 불편함이 있었다.
백엔드 팀원들만이 aws ec2를 켤 수 있는데,
팀원들이 부재중이거나 aws에 접속하기 어려운 상황일 경우 서버를 즉각적으로 켜주기가 어려웠다.
How? 어떻게 해결했어?
이런 문제를 해결하고자 프론트 팀원들도 원하는 시간에 aws에 접속하지 않고도 서버를 켤 수 있는 API를 만들기로 했다.
AWS Lambda 를 사용했다.
1. AWS Lambda 서비스에 접속해서 함수를 생성한다.
이때 IAM role도 같이 생성된다.
고급 설정에서 함수 URL 활성화를 체크하였다.
API Gateway를 사용하면 내가 원하는 형태로 api 주소를 만들 수 있다. 하지만 Lambda 로 함수 URL을 활성화하면 https가 적용된 임의의 주소가 발급된다. IAM 권한이 없어도 호출할 수 있도록 인증 유형을 NONE으로 설정하였다.
2. 함수를 생성한뒤, 코드를 수정한다.
나는 실행하고자 하는 인스턴스가 두 개여서 구성 > 환경변수에 인스턴스 ID를 추가한 후
아래와 같이 코드를 작성하였다.
서버가 꺼져 있을 때, URL을 호출하면 서버가 자동으로 시작되고,
서버가 켜져 있을 때, URL을 호출하면 서버가 자동으로 중지된다.
import boto3
import os
def lambda_handler(event, context):
# 환경 변수에서 인스턴스 ID 가져오기
instance_id1 = os.environ['INSTANCE_ID1']
instance_id2 = os.environ['INSTANCE_ID2']
instance_ids = [instance_id1, instance_id2]
# boto3 EC2 클라이언트 생성
ec2 = boto3.client('ec2')
# 인스턴스 상태 확인
response = ec2.describe_instances(InstanceIds=instance_ids)
start_instances = []
stop_instances = []
for reservation in response['Reservations']:
for instance in reservation['Instances']:
instance_id = instance['InstanceId']
instance_state = instance['State']['Name']
# 인스턴스가 중지 상태인 경우 시작할 목록에 추가
if instance_state == 'stopped':
start_instances.append(instance_id)
# 인스턴스가 실행 중인 경우 중지할 목록에 추가
elif instance_state == 'running':
stop_instances.append(instance_id)
# 인스턴스 시작
if start_instances:
ec2.start_instances(InstanceIds=start_instances)
print(f'Started instances: {start_instances}')
# 인스턴스 중지
if stop_instances:
ec2.stop_instances(InstanceIds=stop_instances)
print(f'Stopped instances: {stop_instances}')
return {
'statusCode': 200,
'body': f'Started instances: {start_instances}, Stopped instances: {stop_instances}'
}
3. 이대로 테스트를 하면 권한 문제가 발생한다. (Unauthorized) IAM role에 권한을 부여해야 한다.
구성 > 권한 > 실행 역할 > 편집 > 맨 아래 기존 역할 확인에서 역할을 편집한다.
++ 제한 시간 3초로 부족한것 같아서 30초로 늘렸다.
Default로 AWSLambdaBasicExecutionRole이 들어가 있다.
나는 ec2에 대한 권한을 주기 위해 권한 추가 > 인라인 정책 생성을 클릭했다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:DescribeInstances",
"ec2:StopInstances"
],
"Resource": "*"
}
]
}
위와 같이 입력하였다. (AmazonEC2FullAccess 는 매우 넓은 권한을 부여하기 때문에 필요한 작업에 국한된 사용자 정의 IAM 정책을 생성하도록 하자)
이렇게 수정하면 권한 문제가 해결될 것이다.
이제 함수 URL을 호출하면 내가 원하는 동작이 수행될 것이다!