AWS Lambda로 API 만들기
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을 호출하면 내가 원하는 동작이 수행될 것이다!