내 소소한..

AWS에서 람다(Lambda)로 커스텀 VPC에 EC2 인스턴스 추가하기 본문

IT/AWS

AWS에서 람다(Lambda)로 커스텀 VPC에 EC2 인스턴스 추가하기

쿠르릉 2021. 1. 21. 18:30

AWS 환경에서 Lambda로 당연히 EC2 인스턴스를 추가/삭제/정지/시작할 수 있다.

그 외 자원도 당연히 추가/삭제가 가능하다.

인터넷에 널려 있는 가이드를 따라 EC2 인스턴스를 추가해 봤지만, VPC를 만져서 그런지 잘 추가가 되지 않았다.

기본 VPC를 사용하지 않을 때 Lambda 스크립트를 실행해 EC2 인스턴스를 추가하는 방법을 정리해 본다.

참고로 아래 작업은 무료 티어 계정에서 별도 비용이 발생하지 않는다.

문제점

인터넷에 있는 EC2를 추가하는 람다 가이드는 대부분 기본 VPC가 존재하는 것을 가정하고 있다. (그런 내용이 써 있지는 않지만.. 모두 동일하다.)

VPC를 처음 주어진 상태에서 사용한다면 별 문제가 없겠지만,

뭔가 VPC의 네트워크에 손을 댄 상태로 해당 가이드를 따라가 보면 3초 timeout 에러가 발생한다.

lambda의 실행 시간을 늘려도 당연히 timeout 에러가 발생한다.

짐작해보면, timeout이 난다는 것은 뭔가 접속이 불가능한 상황일 것이다. 

 

목표

커스텀 VPC에 퍼블릭 IP가 할당된 인스턴스를 추가한다.

 

VPC 구성

VPC, EC2 인스턴스 등이 모조리 없는 상태라고 가정하자. 즉 아래처럼 VPC가 깨끗한 상태에서 시작한다.

VPC가 하나도 없는 깨끗한 상태

물론 EC2도 없다. 다만 키 페어는 또 쓸거라 만들어진 것을 유지한다.

EC2 인스턴스도 하나 없는 깨끗한 상태

커스텀 VPC 추가

커스텀 VPC를 추가해보자.

예전같으면 VPC, 서브넷, 인터넷 게이트웨이, 라우팅 테이블을 일일이 추가해야 했지만 마법사가 생겨 작업이 편해졌다.

VPC 콘솔로 이동해서 VPC 대시보드 왼쪽 상단에 있는  VPC 마법사 시작  버튼을 클릭한다.

이어서 1단계: VPC 구성 선택에서 "단일 퍼블릭 서브넷이 있는 VPC"를 선택한다. 예제에서는 퍼블릿 서브넷만 있으면 충분하다.

단일 퍼블릭 서브넷이 있는 VPC면 충분하다.

이어서 2단계에서는 주어진 설정 그대로를 사용한다. CIDR이 마음에 안들면 바꿔도 무방하겠지만..

10.0.0.0~255 까지의 퍼블릿 서브넷을 생성한다.

그대로 VPC 생성 버튼을 클릭한다. 순식간에 VPC가 생성된다.

오기가 있어서 1단계에서 프라이빗 서브넷도 있는 옵션을 선택했다면 NAT 게이트웨이 생성에 시간이 제법 걸릴 것이다. 문제가 있는 것이 아니니 조금 기다리면 된다.

이제 VPC 대시보드에서 아래와 같은 내용이 나타나야 한다.

퍼블릿 서브넷이 추가된 VPC

요약해서 설명하면,

  • VPC를 하나 추가했으며 (10.0.0.0~10.0.255.255)

  • 퍼블릭 용도로 사용할 서브넷을 하나 추가했다. (10.0.0.0~255)

  • 퍼블릭이니 인터넷 게이트웨이를 하나 추가해서 붙였으며

  • 10.0.0.0대 트래픽을 처리할 라우팅 테이블과, 인터넷 트래픽을 처리할 라우팅 테이블을 하나씩(총 2개) 추가했다.

  • 보안그룹은 기본으로 하나 생성된다. (외부에서 접속을 허용하지 않는..)

이제 EC2를 추가하면서 위 VPC/서브넷을 선택하면(하나밖에 없으니 선택하기 쉽다.) 해당 EC2는 인터넷에 접근할 수 있다.

(다만, 외부에서 SSH 접속이 불가능하므로 잘 떠있는지 알 수가 없다. 아래 설명대로 보안그룹을 추가하고 해당 보안그룹을 EC2에 지정하면 접속이 가능하다.)

이 VPC는 기본 VPC 옵션을 주고 생성하지 않았으므로 AWS는 해당 VPC를 기본 VPC가 아닌 것으로 취급한다. (하나밖에 없음에도..)

따라서 우리가 생성한 것은 커스텀 VPC라고 생각하면 된다.

 

보안그룹 추가

람다 스크립트로 EC2를 만들어도 외부에서 접속이 불가능하면 정말 잘 떠있는건지 확인할 길이 없다. 대시보드에는 잘 떠 있는 것으로 나오겠지만 사람 마음이란 직접 접속해보지 않으면 "과연 그런가.."라는 의심을 갖기 마련이다.

따라서 외부에서 SSH 접속이 가능한 보안 그룹을 하나 생성한다.

VPC 콘솔의 VPC 대시보드나 왼쪽 메뉴에서 "보안 그룹"을 선택한다. 그 뒤 오른쪽 상단의  보안 그룹 생성  버튼을 클릭한다.

보안그룹 생성하기

  • 보안 그룹 이름: AllowSSH (나중에 람다 스크립트에서 사용)

  • 설명: 대충 입력한다. (왜 필수값인지..)

  • VPC: 하나밖에 없으므로 자동으로 선택된다.

  • 인바운드 규칙: 유형은 SSH 선택, 소스는 어디서 접속할지 모르니 위치 무관을 선택한다. 자동으로 CIDR(바로 오른쪽 아래 파란 부분)이 만들어진다.

이어서 보안 그룹 생성 버튼을 클릭하면 막바로 보안 그룹이 생성된다.

 

 

람다 스크립트 추가

Lambda 콘솔로 이동하자. 기본으로 아래같은 화면이 나타난다. 왼쪽 메뉴에서 "함수"를 클릭해도 들어올 수 있다.

Lambda > 함수 첫 화면

우측 상단에서  함수 생성  버튼을 클릭해 함수 생성 화면으로 이동한다.

새 람다 함수 생성하기

  • 함수 이름: LaunchEC2 라고 짓자. (아무거나..)

  • 런타임: Python 3.8을 선택한다.

  • 권한: 손대지 않아도 된다. 기본 값은 "기본 Lambda 권한을 가진 새 역할 생성"이다.

함수 생성 버튼을 클릭하고 잠시(제법) 기다리면 람다 함수 편집 및 설정 화면이 나타난다.

람다 함수 편집 및 설정 화면

권한 설정

먼저 권한을 설정하자. EC2를 생성하려면 EC2 접근 권한이 필요하다. 권한을 클릭한다.

새로 생성된 역할 이름 클릭!

새로 생성된 역할 이름이 나타난다. 역할 이름을 클릭하면 새 탭에 해당 역할을 편집할 수 있는 화면이 나타난다.

역할 정책 편집

화면이 나타나면 "Permissions policies" 왼쪽 화살표(▶)를 눌러 아래로 펼친다. 

이후 하나밖에 없는 AWSLambdaBasicExecutionRole-xxx 정책 왼쪽의 화살표(▶)를 눌러 정책 편집 화면을 펼친다.

이후 정책 편집 버튼을 클릭한다.

정책 편집

편해 보이는 "시각적 편집기"를 포기하고 JSON 탭을 클릭한다.

정책 내용이 json 문자열로 편집기에 나타난다. "Statement" 가장 아래에 ec2 접근 정책을 추가한다. 반드시 마지막 정책의 } 뒤에 콤마를 붙여야 한다. 아래 내용을 추가하자.

,
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "ec2:*"
            ],
            "Resource": "*"
       }   
 

이후 "정책 검토" 버튼을 클릭하면 검토 화면이 나타난다.

정책 검토

"변경 내용을 저장합니다" 버튼을 클릭해 정책 내용을 저장한다.

다시 요약 화면이 나타나며 항목을 펼쳐보면 EC2 모든 액세스 권한이 나타난다. 작업이 완료됐다.

만약 EC2의 전체 권한을 주는 것이 껄끄럽다면 위 정책 추가 부분을 조정해 주면 된다.

IAM 관리 콘솔 화면은 더는 필요가 없으므로 해당 탭은 닫아도 된다.

 

람다 함수 편집

권한을 추가했으니 이제 함수 코드를 편집할 차례이다. 편집에 앞서 몇 가지 항목을 확인해야 한다.

AMI ID 확인

생성하고자 하는 EC2가 사용할 AMI(Amazon Machine Image?)를 확인해야 한다.

기나긴 가이드는 docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/finding-an-ami.html

가장 간단한 방법은 EC2 생성 첫 화면에서 원하는 AMI의 ID를 복사하는 것이다.

바로 얘들(빨간 네모)이다.

서브넷 ID 확인

VPC 관리 콘솔의 "서브넷"에서 VPC의 퍼블릭 서브넷 ID를 확인해야 한다.

퍼블릿 서브넷 ID 확인

마법사로 생성했다면 친절하게 이름이 "퍼블릿 서브넷"이라고 돼 있다.

 

키 페어 이름 확인

EC2 컨테이너 생성 후 로그인에 필요한 키 페어의 이름을 확인해야 한다. (키 페어 생성은 가이드가 많으니 건너뛴다.)

EC2 관리 콘솔 대시보드에서 키 페어를 선택하거나 왼쪽 메뉴에서 네트워크 및 보안 > 키 페어를 선택한다. 

키 페어 이름 확인

ID가 아니고 이름이 필요하다.

 

보안 그룹 ID 확인

앞서 추가한 보안 그룹의 ID를 확인한다.

VPC 관리 콘솔에서 "보안 그룹"을 선택한다.

보안 그룹 ID 확인

앞서 추가한 AllowSSH 보안 그룹의 보안 그룹 ID를 확인한다.

 

람다 함수 코드 편집

열려 있는 람다의 함수 관리 화면에서 다시 "구성" 탭을 클릭해 코드 편집기 등의 화면으로 돌아간다.

람다 함수 코드 편집

이제 실제 작동할 코드를 입력할 시간이다.

다음 코드 내용을 붙여 넣은 후 상단의 AMI, KEY_NAME, SUBNET_ID, SECURITY_GROUPS_IDS 를 확인한 값으로 바꿔치기 한다.

import boto3

AMI = 'ami-0094965d55b3bb1ff'
INSTANCE_TYPE = 't3.micro'
KEY_NAME = 'my-key-n'
REGION = 'ap-northeast-2'
SUBNET_ID = "subnet-0ff12643b7c0b5c54"
SECURITY_GROUP_IDS = ["sg-078b16e8a5fc3f05f"]


ec2 = boto3.client('ec2', region_name=REGION)


def lambda_handler(event, context):

    instance = ec2.run_instances(
        ImageId=AMI,
        InstanceType=INSTANCE_TYPE,
        KeyName=KEY_NAME,
        NetworkInterfaces=[{
            'AssociatePublicIpAddress': True, 
            'DeviceIndex': 0,
            'SubnetId': SUBNET_ID,
            'Groups': SECURITY_GROUP_IDS,
        }],
        MaxCount=1,
        MinCount=1
    )
    
    print ("New instance created:")
    instance_id = instance['Instances'][0]['InstanceId']
    print (instance_id)

    return instance_id

코드에서는 퍼블릭 IP가 부여된 ec2 인스턴스를 서울 리전에 생성한다.

서울 리전은 t2.micro 인스턴스가 없나보다. t3.micro 인스턴스로 대체했다.

코드 실행

이제 편집할 코드를 실행해서 EC2 컨테이너를 생성할 때이다!

먼저 편집기 위 "Deploy" 버튼을 클릭해 코드를 배포한다. "Deployment package successfully saved"라는 메시지가 나오면 잘 배포된 것이다.

그 다음 왼쪽 "Test" 버튼을 클릭한다.

처음 실행할 때는 먼저 테스트 이벤트를 구성해야 한다. 자동으로 팝업이 나타난다.  

테스트 이벤트 구성 팝업

이벤트 이름을 적당히 test라 준다. 테스트 데이터를 별도로 공급할 필요가 없으므로 아래 테스트 데이터는 {}로 지정한 뒤 "생성" 버튼을 클릭한다.

팝업이 닫힌 뒤 다시 "Test" 버튼을 클릭한다. (드디어 첫 실행이다!!)

아래 "Execution Result" 탭을 확인하자

코드 실행 결과

코드 실행 결과 새 인스턴스가 실행되면 위와 같은 화면이 나타난다.

아무 메시지도 나타나지 않을 때는 접근 권한이 제대로 설정되지 않아서 그럴 수 있으며,

timeout이 날 때는 VPC 설정이 잘못돼서 그럴 수 있다.

 

EC2 확인 및 접근

생성된 EC2를 확인해보자.

EC2 관리 콘솔로 접근해서 EC2를 확인해보면!!

생성된 EC2 확인

행복하다. EC2가 생성됐고.. 퍼블릭 IP 주소가 할당됐다. 보안 탭을 확인해보면 AllowSSH 보안 그룹에 속하므로 외부에서 SSH 접속이 가능함을 알 수 있다.

실제로 Putty 등으로 접속을 확인해 보자. (키 페어로 EC2 인스턴스에 접근하는 상세 방법은 설명이 많으니 생략한다.)

 

생성된 EC2에 SSH 접근

생성된 EC2 컨테이너(내부 IP 10.0.0.117)에 접속했다.

 

※ 스크립트를 실행할 때마다 EC2 컨테이너가 생성된다. 여러 개를 동시에 돌려도 되지만 "종료" 시키지 않고 계속 실행해서 월 실행 허용시간이 초과되면 과금되니 주의하자.

'IT > AWS' 카테고리의 다른 글

AWS에서 람다(Lambda)로 EC2 시작/종료하기  (0) 2021.01.22
Comments