본문 바로가기
카테고리 없음

AWS Lambda로 API 만들기

by Rena B 2024. 4. 1.

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을 호출하면 내가 원하는 동작이 수행될 것이다!