AWS Lambda를 이용한 API 서비스 배포 (2/2) – API Gateway

지난 글에 이어서 AWS Lambda와 API Gateway를 연동하여 서비스 배포하는 과정을 소개합니다. 이 글에서는 AWS Lambda 보다는 API Gateway 사용에 포인트를 두고 있습니다. AWS Lambda가 더 궁금하신 분들은 이전 글을 봐주세요. 링크:[AWS Lambda를 이용한 API 서비스 배포 (1/2)]

API GateWay는 무엇인가?

AWS에서는 다음과 같이 설명하고 있습니다.
“Amazon API Gateway는 어떤 규모에서든 개발자가 API를 손쉽게 생성, 게시, 유지 관리, 모니터링 및 보안할 수 있게 해주는 완전관리형 서비스입니다.”

API GateWay를 사용하면 어떤 장점들이 있을까요?

AWS콘솔을 통해서 트래픽관리와 모니터링을 쉽게 할 수 있습니다.

트래픽 제어도 콘솔에서 비교적 간단하게 처리할수 있습니다. 또한 제공되는 대시보드를 통해서 API호출, 오류발생률, 응답시간등을 시각화된 UI로 쉽게 볼수 있습니다. 제 견해로는 이 부분이 사실 비용면에서도 유리하다고 생각합니다. 관리인원에 대한 비용, 시간비용을 절약할 수 있다고 봅니다.

기존 서비스를 위한 RESTful 엔드포인트 생성할 수 있습니다.

AWS콘솔에서 다뤄보면 아시겠지만 RESTFul API 서비스를 배포하기 쉽게 구성이 되어 있습니다.
개발자로서 주목할만한 점은 기존에는 웹프로그래밍으로 구현했던 GET, POST, PUT, DELETE등의 메서드들을 쉽게 콘솔조작으로 적용할 수 있다는 점이었습니다.

매우 쉽게 한개의 도메인(예: api.algopie.com)으로 엔드포인트를 만들고 실제로는 각 메서드들 혹은 각 리소스마다 다른 서버로 분산처리 할 수 있습니다.
AWS 사용 이전에 트래픽 분산처리를 위해 사용했던 시간과 기술비용등을 고려해 볼때 이 부분은 매우 큰 장점입니다.

AWS 서비스들과 쉽게 연동할 수 있습니다.

자사 제품을의 사용률을 높이기 위해 AWS에서 당연히 설계시 반영되었겠지만 그래도 쉽게 연동할 수 있다는점도 또한 장점입니다. AWS Lambda, CloudFront등 연동 작업을 매우 간결하게 할 수 있습니다.

 

API Gateway 시작하기

위와 같이 New API를 체크하고 API name과 Description을 쓰고 Create API 버튼을 누릅니다.

REST의 3요소

계속해서 진행하려면 먼저 Resource를 만들어야 하는데 RESTful API에 관심이 없으신 분들은 Resource 라는 단어는 갖고 있는 광범위한 의미때문에 약한 헷갈릴 수도 있는 단어입니다. REST는 HTTP 스펙 본연의 디자인에 충실하게 API를 구현하기 위하여 제안된  아키텍쳐입니다.  간단하게 REST는 Resource, Method, Message 이렇게 3가지 요소가 있습니다. API Gateway를 사용하기 위해 매우 간단하게만 다루겠습니다.

Resource

사용하고 행위(?)하고자 하는 목적이 되는 대상입니다. https://api.algopie.com/products 와 같은 형태의 URI로 표현합니다.

Method

대상 (Resource)에 대한 행동 방법입니다. 대상 Resource를 생성, 삭제, 수정, 불러오기(보기)등에 대한 행동 방법입니다. HTTP의 method를 그대로 사용합니다. GET (불러오기, 보기등), POST(생성), PUT(수정), DELETE(삭제)등의 HTTP method. 기존 구형의 레거시 스타일에서는 HTTP 요청시에 GET, POST만 주로 사용했었으며 생성, 삭제, 수정, 읽기등 모든 행동을 GET과 POST로 사용하거나 심지어 POST 하나만으로도 사용하는 경우도 있었습니다. REST 아키텍쳐에서는 똑같은 http URL 호출일지라도 method에 따라서 그 결과가 달라집니다.

https://api.algopie.com/products 라는 하나의 URI로도 GET으로 요청하면 product의 리스트를 응답하고 POST로 요청하면 새로운 product를 추가할 수 있습니다. 마찬가지로 DELETE로 요청하면 해당 product를 삭제하게 됩니다.

Message

대상에 대한 내용 입니다. 최근 트렌드는 JSON을 많이 사용합니다. XML로 통칭되는 확장된 마크업랭기지의 경우 JSON에 비하여 사용되는 패킷량도 많고 복잡도도 증가하여 요즈음에는 거의 JSON이 대세가 되었습니다. 위 예에서 https://api.algopie.com/proudcts 리소스를 GET으로 요청하면 product에 대한 아래와 같은 내용을 응답합니다.


[{\"url\": \"https://algopie.com\", \"name\": \"Algorithm Pie\", \"idx\": 1, \"description\": \"\\uc5ec\\ub7ec\\uac00\\uc9c0 \\ubb38\\uc81c\\ub97c \\ub2e4\\uc591\\ud558\\uace0 \\uc7ac\\ubc0c\\uac8c \\ud574\\uacb0\\ud558\\ub294 \\uc54c\\uace0\\ub9ac\\uc998 \\ud30c\\uc774\"}, {\"url\": \"https://biblepuzzle.algopie.com\", \"name\": \"Bible Puzzle\", \"idx\": 2, \"description\": \"\\uac00\\ub85c\\uc138\\ub85c \\uc131\\uacbd \\ud37c\\uc990!\"}]

REST에 대한 설명은 매우 부족하지면 본편을 위하여 이정도로 마무리 합니다. 이 글에서 주로 다루는 것은 Resource와 Method 입니다.

Resource 생성하기

다시 본편으로 돌아와서 아래 이미지와 같이 Resource를 생성합니다.

이 예제에서는 products 라는 리소스를 사용하겠습니다. 리소스 이름을 적어주시면 path는 자동으로 지정되는데 path는 수정 가능합니다. Create Resource 버튼을 눌러서 마무리 합니다.

Method 생성하기

Method를 아래와 같이 생성합니다.

이 글에서는 간단하게 GET 메서드만 배포하겠습니다. 메서드 생성시에 아래와 같이 GET을 선택하여 생성합니다.

우리는 API Gateway를 AWS Lambda와 연동 할 것이기 때문에 GET 메서드에 대한 셋팅을 AWS Lambda 사용을 휘한 셋팅으로 아래와 같이 합니다. 미리 만들어 놓은 lambda function을 아래와 같이 선택합니다. 참고로 저는 서울 region을 사용하기 때문에 Lambda Region은 ap-northeast-2 입니다.

먼저  AWS Lambda 에서 제대로 동작하는 function이 준비되어야 Lambda function을 사용할 수 있습니다. 이전 글에서 만든 function은 디비에 테이블을 생성하고 insert 하는 부분까지 있어서 그대로 사용하기엔 약간의 무리가 있지만 귀찮으신 분들은 그대로 사용하셔도 작동하긴 합니다. 다만 RESTful 하지 않을 뿐입니다. 되도록이면 이전 글을 보시고 응용하셔서 새로은 function을 만들어 보시는 것을 추천합니다. 링크:[AWS Lambda를 이용한 API 서비스 배포 (1/2)]

API 테스트

메서드 생성이 완료되면 아래와 같은 화면을 볼 수 있습니다. Request 부터 Response 까의 경로를 보여주고 있습니다.

가운데 TEST (번개표)를 누르시면 제대로 동작하는지 테스트 할 수 있습니다. 아래와 같이 잘 동작하는 군요. Response body 부분을 보시면 Json으로 된 body 응답을 보 실 수 있습니다. 레이턴시가 116 ms 로 나오는데 저의 경우 그때 그때 다릅니다. 이 경우는 매우 빠른 경우이고 느릴때도 있습니다. 추후 API 분산 처리를 위하여 CloudFront 연동시 보다 나은 퍼포먼스를 기대해 봅니다.

 

아직 끝이 아닙니다. 중요한 과정 하나가 더 남아 있습니다.

Deploy 하기

마지막 과정으로 우리가 생성한 API를 배포 하는 과정이 남았습니다. 리소스를 선택하고 메서드를 선택하고 Action 버튼을 눌러서 아래와 같이 Deploy 합니다.

Stage는 없으실 경우 New Stage로 새로 만들어 주세요. 제 기억이 가물가물해서 prod 스테이지가 위 과정중에 생성이 되었는지 제가 만들었는지 기억이 잘 나지 않네요.  필요한경우 추후에 업데이트 하겠습니다.

제대로 사용 하려면 Usage Plan, dl인증키관리 등도 함께 다뤄야겠지만 이번 글은 여기서 마치도록 하겠습니다.

AWS Lambda를 이용한 API 서비스 배포 (1/2)

AWS Lambda가 무엇 인가요?

AWS에서 설명하는 Lambda는 “이벤트에 응답하여 코드를 실행하고 자동으로 기본 컴퓨팅 리소스를 관리하는 서버 없는 컴퓨팅 서비스입니다.” (이전 AWS관련 글에도 적었지만 매번 씁니다. ^^ AWS에서 제공하는 문서를 보시면 더 자세한 내용이 있습니다. https://aws.amazon.com/ko/lambda/details/)여러 가지 특징중에 특히 강조할 만한 것은 서버없는 서비스(serverless services)가 가능하다는 것 입니다. 좀 더 구체적으로 말하면 내가 관리해야할 서버가 없이도 서비스를 제공할 수 있다 입니다. 서버 상태를 관리하지 않아도 되면 많은 비용과 스트레스를 줄일 수 있습니다. AWS Lambda를 사용해서 서버 관리에 필요한 당연히 예상되는 비용(시간, 돈, 사람등)을 획기적으로 줄일 수 있다면 거기에 포인트를 두고 서비스를 설계 개발 하는것이 필요합니다.

그럼 AWS Lambda는 어디에 쓰는 물건 인가요?

AWS의 서비스들과 관계가 적은 복잡한 기능을 수행해야만 하는 특별한 나만의 맞춤 서버가 필요하다면 AWS Lambda 보다는 EC2를 활용하는 것을 권장합니다. AWS Lambda에서 제공 하는 Lambda Trigger를 이용하여 AWS 서비스와 연계된 이벤트를 처리할 때 사용하기에 유용합니다. 그 외에 API 기능을 API서버 없이 구현하기에도 유용합니다. 물론 API 서버로서 활용하고 싶다면 AWS Lambda 뿐만 아니라 API Gateway와 연계하여 설계하는 것이 더 효율적입니다. (이 내용은 다음 포스팅에서 다룹니다.)

AWS 서비스 내의 이벤트에서 트리거를 만들어서 처리할 수 있는 서비스들은 아래와 같습니다.(스크롤로 안보이는 S3, SNS 서비스도 포함되어 있습니다.)

구글링해서 보통 많이 볼 수 있는 사용 예는 http api 서버 기능 제공, S3를 활용한 이미지 자동 처리, SNS를 활용한 notification에 대한 자동 처리, CloudWatch 특정 이벤트 발생시 원하는 액션 처리등이 있습니다. 이 글에서는 비교적 구현하기 간단하고 많이 사용하는 http api 서비스를 배포하는 것을 목적으로 아래의 4가지 내용을 다루겠습니다.

1. Python으로 function 작성하기 및 패키징
2. S3를 활용한 function 배포
3. AWS Lambda 설정
4. Testing

1. Python으로 function을 작성하고 패키징 하기

Lambda function 코드를 업로드 하는 방법중 S3을 이용한 방법이기 때문에 AWS Lambda 서비스를 설정하기 전에 코드를 작성하여 S3 버킷에 올려 놓겠습니다.

시행착오를 줄이고자 먼저 두 가지 유의 사항을 알려드립니다.

  • Lambda function 코드를 작성할때 추가로 사용하는 python 모듈이 있을경우 해당 모듈을 모두 함께 패키징 해서 zip파일로 올려야 합니다.
  • 높은 확률로 Linux 에서 패키징을 해야 정상 작동 합니다.

각각의 Lambda function은  논리적으로 독립된 공간에서 실행 된다고 가정하는 것이 맞을 듯 합니다. 그래서 다른 function을 작성할때 이전에 이미 필요한 모듈을 같이 올렸다고 하더라도 import 에러가 발생하는 것을 볼 수 있습니다. 또한 AWS Lambda는 Linux 기반에서 실행되니 Windows 파일 시스템에서 패키징 한것은 제대로 돌아 가지 않을 확률이 매우 높습니다.

이번 예제에서는 MariaDB 혹은 MySQL을 사용하기 때문에 pymysql 모듈을 함께 패키징 해야 합니다. EC2 우분투 에서 패키징하고 awscli를 이용하여 S3으로 바로 업로드 하는 방법을 사용하겠습니다.

코드는 Windows 용 IDE 와 같은 편하신 환경에서 작성하시고 ec2 에 올려서 패키징 하겠습니다. 코드가 간단해서 vim 에디터 사용 가능하시면 직접 vim으로 작성하셔도 좋습니다. 코드는 aws에서 제공하는 example을 사용하겠습니다.
(http://docs.aws.amazon.com/lambda/latest/dg/vpc-rds-deployment-pkg.html)

예제에 나온대로 2개의 파일을 작성합니다. 먼저 메인 fuction인 getProducts.py 파일 입니다.

# getProducts.py
import sys
import logging
import rds_config
import pymysql

# rds settings
rds_host = "rds-instance-endpoint"
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name

logger = logging.getLogger()
logger.setLevel(logging.INFO)

try:
    conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)
except:
    logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
    sys.exit()

logger.info("SUCCESS: Connection to RDS mysql instance succeeded")


def handler(event, context):

    item_count = 0

    with conn.cursor() as cur:
        cur.execute("create table IF NOT EXISTS employee ( EmpID  int NOT NULL, Name varchar(255) NOT NULL, "
                    "PRIMARY KEY (EmpID))")
        cur.execute('insert into employee (EmpID, Name) values(1, "Joe")')
        cur.execute('insert into employee (EmpID, Name) values(2, "Bob")')
        cur.execute('insert into employee (EmpID, Name) values(3, "Mary")')
        conn.commit()

        cur.execute("select * from employee")
        for row in cur:
            item_count += 1
            logger.info(row)
            print(row)

    return "Added %d items from RDS MySQL table" % (item_count)

def handler 의 arguments 를보시면 단박에 감 잡으실 것 같은데 그것 맞습니다!  다른 부분은 python 언어의 일반적인 내용인데 여기서 handler, event, context에 대한 개념은 꼭 이혀두시길 권장 합니다.

handler

Lambda funtion이 호출될때 실행하는 handler를 위와 같은 형식으로 정의 해놓고  c나 java의 Main 함수 처럼 사용합니다. handler라는 이름은 당연히 수정하셔도 됩니다. main으로 실행할 함수를 정의하시고 추후 aws Lambda 콘솔에서 handler로 지정합니다. handler (event, context)의 포맷만 기억하시면 됩니다.

event

Lambda function을 실행할때 넘겨주는 파라메터들을 이 event로 받아서 처리 할 수 있습니다. http로 lambda를 실행할때 get, post, put, delete 등의 메서드를 통해서 전달 할 수 있습니다. JAVA servlet 에서 doGet, doPost 등에 있는 requst 와 같은 역할을 합니다.

context

Lambda function이 실행완료 하고 context를 통해 return 할 수 있습니다. 성공 메시지, 실패 메시지등을 리턴 할 수 있습니다. JAVA Servlet으로 보면 doGet doPost등의 response와 같은 역할을 합니다.

해당 내용은 튜토리얼에 자세하게 나와 있으니 그냥 넘어가지 마시고 꼭 보시기를 권장합니다.
(http://docs.aws.amazon.com/ko_kr/lambda/latest/dg/python-programming-model-handler-types.html)

다음은 rds 계정정보가 있는 rds_config.py 파일 입니다.

rds_config.
db_username = "db_user_name"
db_password= "db_password"
db_name = "algopie"

저는 임시로 ubuntu 계정 디렉터리 하위로 repo/lambda/getProudcts 라는 디렉터리를 생성하고 그 하위에 위 2개의 파일을 위치 시켰습니다. 이제 패키징 합니다.

python module installation

앞서 설명 했듯이 패키징시 필요한 외부 모듈들이 모두 함께 포함되어야 실제 function 실행시 import 에러가 나지 않습니다. 그래서 외부 모듈들을 같은 디렉토리에 인스톨 하는 과정이 필요합니다. 본인이 작성한 모듈을 다른곳에 배포하기 위해 setup.py를 작성하는 작업도 필요합니다.

aws 튜토리얼에 다 나와 있습니다.
(http://docs.aws.amazon.com/ko_kr/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html)

ec2-shell> cd /home/repo/lambda/getProducts
ec2-shell> vi setup.py

아래는 setup.py 내용입니다. py_module 부분과 setup.name 부분이 중요합니다. 외부 모듈을 사용하므로 아래 예시처럼 pymysql을 명시해주세요.

from distutils.core import setup

py_modules = [
 'pymysql',
]

setup(
    name='getProducts',
    version='0.1',
    packages=[''],
    url='',
    license='',
    author='YourName',
    author_email='',
    description=''
)

이제  pip install 로 외부 모듈을 같은 위치에 인스톨 합니다. 명령어 패턴은 aws 튜토리얼에 나온대로 pip install module-name -t /path/to/project-dir 입니다. 이미 change directory로 소스가 위치한 root 디렉터리에 와 있으므로 아래와 같이 typing  합니다.

 ec2-shell> pip install pymysql -t ./ 

성공적으로 모듈이 설치되면 아래와 같은 메시지가 나옵니다.

zip 으로 압축

하위디렉터리까지 몽땅 압축합니다.

ec2-shell> zip -r getProducts.zip *

2. S3를 활용한 function 배포

s3 버킷으로 업로드

awscli를 설치하신 상태라면 아래 커맨드라인으로 업로드 하시면 됩니다. 혹시 awscli가 무엇인지 모르시거나 아직 설치 하지 못하신 분들께서는 이전 포스트에 상세히 작성해 놓았으니 보시고 awscli를 설치해주신 다음에 아래 순서를 진행해 주세요. s3를 관리하는 cli 명령어 옵션에 대한 설명도 링크로 걸어둡니다.

링크1: AWS ec2 우분투(ubuntu)에 awscli 설치 하기

링크2: AWS CLI를 사용하여 ec2에서 s3로 업로드/다운로드 하기 (우분투 Ubuntu)

ec2-shell> aws s3 mb s3://algopie-functions
make_bucket: algopie-functions

ec2-shell> aws s3 cp ./getProducts.zip s3://algopie-functions/
upload: ./getProducts.zip to s3://algopie-functions/getProducts.zip

이제 가장 긴 고비를 넘기셨으니 얼마 안남았네요

3. AWS Lambda 설정

AWS 콘솔에서 AWS Lambda를 선택하면 제일 처음 대시보드가 나옵니다. Create Function 버튼을 누르고 새로운 funtion을 생성합니다. (저는 이미 2개의 사용중인 funtion이 있어서 아래와 같이 나오네요)

다음으로 넘어가면 각종 예제들이 포함되어 있는 Blueprint 항목이 나옵니다. 하지만 여기서는 그냥 그대로 따라하기 보다는 RDS와 연동하여 테이블 데이터를 쿼리하여 Json 포맷으로 뿌려주는 HTTP API를 만들기로 했으니 왼쪽 메뉴에서 “Configure Function” 버튼을 눌러줍니다. 아래와 같이 지원하는 언어는 5가지 입니다. 이 중에서 저는 Python으로 코드를 작성하겠습니다. (Python은 저도 몇번 접해 보기만 한 언어입니다. 이 참에 제대로 익혀 보자는 생각으로 골랐습니다. )

일단 이번 예제에서는 짧게 넘어가겠지만 AWS Lambda로 API 서비스를 구현하실 분들께서는 생각을 좀 해보셔야 하는 것이 있습니다. 바로 위 화면중 “Name”에 넣어야 할 Function Name 입니다. HTTP API 설계를 생각하시는 분들은 이미 머리속에 RESTful 이라는 단어가 있을 것 입니다. AWS Lambda 로 직접 API 서비스를 하실 계획을 가지신 분들은 별로 없을 것 같습니다. AWS에서도 API Gateway와 연동할 것을 권장하고 있습니다. 저도 API Gateway를 활용하여 RESTful한 멋진 API 서비스를 만들어 보시는 것을 추천합니다. 물론 이 AWS Lambda function을 direct로 HTTP API 서비스로 배포할 생각이 없으셔도 AWS Lambda Funtion naming 관련하여 시간을 내서 검색도 해보시고 본인에게 가장 설득력 있는 Naming 규칙을 사용하실 것을 권장합니다.

Name* : getProducts

네 그렇습니다. 전혀 RESTful 한 함수 이름이 아니야! 라고 할 수 있습니다. RESTful 한 naming 은 추후 API Gateway를 다룰 때 사용합니다!

Runtime*: Python 2.7

그리고 다음 아래로 내려 갑니다. 다음은 코드를 어디서 업로드할지 선택해주는 화면 입니다. 아래 화면과 같이 Upload a file from Amazon S3을 선택하시고 아래 s3 link URL에 아까 만들어준 s3 URL을 적어줍니다. 저와 동일하게 하셨다면 link url은  https://s3.amazonaws.com/algopie-functions/getProducts.zip 입니다.

환경변수를 셋팅하는 기능도 제공합니다. key-value 페어형태로 해당 functon 전역에서 사용할 수 있는 환경 변수를 셋팅할 수 있습니다. 이 예제에서는 넘어갑니다.

아래는 중요한 셋팅 내용들이 있으니 이왕 해보시는 김에 확실히 익혀두시기를 권장합니다. 위에 한번 중요하게 handler에 대한 부분을 작성했습니다. 드디어 여기에 나오는군요.

 

Handler*: 위 python 코드에서 handler(event, context) 를 정의 하였는데 Handler에 위에 정의해 놓은 함수명을 적어줍니다. 예시의 getProducts.py의 handler 이므로 getProducts.handler 입니다. 일종의 네임스페이스 개념이라고 생각하시면 될듯 합니다.

Advanced setting: 메모리나 타임아웃등에 대하여 셋팅할 수 있고 저는 기본으로 두고 진행했습니다. 튜토리얼을 보면 설명이 나옵니다. 간단하게 설명하면 디테일하게 셋팅하여 퍼포먼스를 높일 때 사용합니다.

Roll*: AWS의 IAM롤에서 lambd 전용 롤을 만들고 적용하겠습니다. 위 예시와 같이 new roll을 선택하시고 roll name을 적으시면 새로운 롤을 만드는 창이 오픈됩니다.

lambda basic execution 을 선택하고 policy name도 제공해주는 것을 사용하였습니다. IAM 관련하여서는 추후에 깊게 다룰 예정입니다. 이전 포스팅에서 awscli 의 access key id와 secret key를 발급 할때 다룬 내용을 참고하셔도 됩니다.

링크: IAM  유저생성

다시 Lambda 설정으로 돌아옵니다. 드디어 끝이 보이네요.
VPC는 virtual private cloud 로 쉽게 설명하면 가상 개인 네트워크 정도로 말 할 수 있습니다. vpc 셋팅을 통해서 aws 내부 접근과 외부접근에 대한 제어를 할 수 있습니다. 자세한 설명은 aws docs링크를 보시는 것을 권장합니다. http://docs.aws.amazon.com/ko_kr/AmazonVPC/latest/UserGuide/VPC_Introduction.html

Secret Group*: 저의 경우 Lambda 전용으로 하느를 만들었고 inbound, outbound 모두 모든 포트를 anywhere 로 오픈했습니다. Next 버튼을 누르면 review 화면이 나오고 마지막으로 creating 버튼을 누르면 약간의 시간을 대기하고 모든 과정이 완료됩니다. “Save and Test” 버튼을 누르시고 다음 과정으로 넘어 갑니다.

자 드디어 대망의 테스팅 입니다. 과연 잘 작동할까요? 두근두근!

4. Testing

Test 버튼을 누르시면 잠시후 테스트 결과가 나옵니다.

위에 우리가 작성한 대로 employee 라는 테이블을 생성하고 3개의 row를 insert 하여 위와 같은 결과가 리턴 되었습니다.  Lambda function 셋팅 자체보다는 선행해야할 셋팅들이 많아서 예상보다 긴 길이 되었습니다. 긴글 따라 오시느라 수고 많으셨습니다.

AWS CLI를 사용하여 ec2에서 s3로 업로드/다운로드 하기 (우분투 Ubuntu)

야심차게 AWS를 사용해보고자 free tier를 신청하신 분들이 많으실 줄 생각합니다. 여러가지 매력적이고 강력한 서비스들이 있습니다. 그 중에서 가장 기본이 되는 것을 꼽아 보자면 역시 EC2, RDS와 함께 S3을 꼽아 볼 수 있습니다.

리눅스 서버 환경에 익숙한 저 로서는 S3을 처음 이용할때 EC2에 직접 마운트 하는 방법을 찾았었고 역시나 이미 먼저 AWS를 사용한 선배들이 간단하게 마운트 해서 S3을 이용할 수 있는 방법들을 만들어 놓았습니다. 저 역시 이러한 솔루션중에 평가가 좋은 것들을 테스트 해봤는데 테스트 해보고 내린 결론은 S3은 마운트해서 쓰라고 만든게 아니구나 였습니다. 마운트해서 사용해도 되긴 되지만 읽기, 쓰기 모두 비정상적으로 느리게 체감 되었습니다. 파일 사이즈가 100Mb만 넘어가도 너무 느려서 실제 서비스에서는 사용할 수 없다고 결론 내렸던 기억이 있습니다.

이 포스트 에서는 심플하고 강력한 커맨드라인 툴인 AWS CLI를 사용하여 간편하게 S3 버킷에 파일을 업로드 하거나 다운로드 하는 방법을 다루겠습니다.

일단 awscli 가  ec2 머신에 설치되어 있어야 합니다. cli  설치방법은 매우 상세하게 설명하여 포스트 했습니다.

[링크:AWSCLI 설치 방법은 이곳을 참조 해 주세요. ]

ec2 에서 s3 관련 명령어 옵션이 무엇이 있는지 먼저 살펴봅시다.
ec2-shell> aws s3 help
 

리눅스를 접해보신 분들에게 익숙한 man 페이지를 제공해주는군요! S3 명령어 옵션을 보시면 이렇게 7개가 나옵니다. 각각 무엇인지 살펴봅시다.

이 포스트까지 검색해서 찾아오신 분들이라면 cp, mv, rm, ls 이 네 가지는 제가 설명하지 않아도 아실것 같은 느낌적인 느낌이 드는 군요. 7가지 모두 하나 하나 살펴보겠습니다.

업로드/다운로드: cp, mv

cp: copy입니다.  ec2 에서 s3 cp 하면 업로드 s3 에서 ec2로 cp 하면 다운로드입니다.
aws s3 cp /local/object s3://bucket/to/object/path
aws s3 cp s3://bucket/from/object/path /local/to/path

aws s3 cp README.txt s3://algopie-test
aws s3 cp s3://algopie-test/README.txt ./

mv: move 입니다. cp와 마찬가지로 업로드, 다운로드 둘다 되며 다만 명령이 실행 완료되면 오리지널 오브젝트는 지워집니다. 명령어 패턴은 위 cp 와 완전하게 동일합니다.

삭제: rm

rm: remove 입니다. s3에 있는 오브젝트를 삭제하는 명령어 옵션입니다.

aws s3 rm s3://bucket/to/path
ec2-shell> aws s3 rm s3://algopie-test/README.txt

목록 보기: ls

ls: list directory contents 입니다. dos로 치면 dir 과 비슷합니다. ls 로 해당 버킷에 들어 있는 파일 목록을 볼 수 있는 명령어 옵션입니다.

aws s3 ls s3://bucket/to/path
ec2-shell> aws s3 ls s3://algopie-test

Bucket 생성 / 삭제: mb, rb

mb: make bucket 입니다. s3에 버킷을 생성하는 명령어 옵션입니다.

aws s3 mb s3://bucket
ec2-shell> aws s3 mb s3://algopie-test
rb: remove bucket 입니다. 위에 설명한 rm은 버킷안에 있는 오브젝트를 삭제하는 것 이고 rb는 버킷 자체를 삭제하는 것 입니다.

aws s3 rb s3://bucket

ec2-shell> aws s3 rb s3://algopie-tmp

동기화: sync

sync: synchronize 입니다. 말그대로 동기화 하는 명령어 옵션입니다. local to s3, s3 to local, s3 to s3 이렇게 3가지를 지원합니다.

aws s3 sync /local/from/path s3://bucket/to/path
aws s3 sync s3://bucket/from/path /local/to/path
aws s3 sync s3://bucket/from/path s3://bucket/to/path

ec2-shell> aws s3 sync /home/www/algopie-public s3://algopie-public 
ec2-shell> aws s3 sync s3://algopie-tmp /home/www/tmp
ec2-shell> aws s3 sync s3://algopie-public s3://algopie-tmp

장황하게 정리하였지만 사실 help 명령어 옵션으로 모두 자세하게 확인이 가능합니다. 각각 명령 옵션에 대한 헬프도 따로 따로 볼 수 있습니다.

가령 아래와 같은 명령어 옵션을 실행 시키면 sync 옵션에 대한 설명과 자세한 사용법 모두 나오니 help를 활용하는 습관을 들여 놓으면 굳이 검색을 하지 않아도 빠르게 찾아 볼 수 있습니다.

ec2-shell> aws s3 sync help

AWS ec2 우분투(ubuntu)에 awscli 설치 하기

AWS의 경우 문서가 훌륭하게 준비가 되어 있어서 사실 AWS에서 제공해 주는 메뉴얼 및 튜토리얼을 보는 것이 가장 확실한 정보를 얻을 수 있는 수단입니다.
(AWS 한국어 문서 페이지: https://aws.amazon.com/ko/documentation/)
아래 내용은 기본적으로 AWS에서 제공하는 문서를 참고하여 정리한 내용입니다.

대상 EC2의 OS는 Ubuntu 이지만 CentOS나 AmazonLinux도 사실 apt 대신 yum을 사용하는 것 외에 별 다를 것은 없을 것 같습니다.

AWS cli 는 무엇에 쓰는 물건인가?(What Is the AWS Command Line Interface?)

The AWS Command Line Interface is a unified tool to manage your AWS services.
Refer: http://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cli-chap-welcome.html

AWS에서는 AWS 서비스를 관리할수 있는 통합도구라고 표현하고 있습니다.
AWS cli(Command Line Interface)라 하면 사용자가 AWS와의 대화(제어, 관리)를 Command Line으로 할 수 있게 구현해 놓은 일종의 툴 이라고 볼 수 있습니다.
사실 보통 사용자들은 CLI보다는 화면상에서 버튼을 클릭하거나 드래그&드롭 할 수 있는 GUI(Graphic User Interface)에 익숙해져 있어서 처음 사용할때는 어려워 보이지만 익숙해지면 나름 GUI처럼 편하게 사용할 수 있습니다.

AWScli 설치

Refer: http://docs.aws.amazon.com/ko_kr/cli/latest/userguide/installing.html
AWS에서 제공하는 문서에는 pip(The PyPA recommended tool for installing Python packages)를 이용한 설치방법이 나와 있습니다. 이 글에서는 pip를 이용한 설치방법과 apt install를 이용한 방법 두가지 모두 다루겠습니다. 어느 방법을 하는것이 저 적합한지 잘 모르겠다 하시는 분들은 2. apt install 방법을 선택하시는것 을 추천 합니다.

1. pip를 이용한 cli 설치

Refer: http://docs.aws.amazon.com/ko_kr/cli/latest/userguide/installing.html

설치

ec2-shell> pip install --upgrade --user awscli

옵션 설명

–upgrade 옵션은 이미 설치된 관련 패키지가 있으면 업그래이드 가능한 경우 업그래이드를 하게 해주는 옵션입니다.
–user 옵션은 pip 명령을 실행한 유저의 서브디렉터리에 설치를 하라는 옵션입니다.

aws 명령어로 확인

ec2-shell> aws
usage: aws [options]   [ ...] [parameters]
To see help text, you can run:

  aws help
  aws  help
  aws   help
aws: error: the following arguments are required: command

유의사항

pip를 이용하여 위와 같이 튜토리얼대로 설치하면 설치한 유저만 awscli를 사용할 수 있습니다. 사용환경에 설치된 디렉터리를 path로 잡아주면 다른 사용자들도 사용할 수 있습니다.

2. apt를 이용한 설치

awscli가 설치 되지 않은 상태에서 아래와 같이 명렁어를 입력하면 apt install 을 권유하는 가이드를 볼 수 있습니다.

ec2-shell> aws
The program 'aws' is currently not installed. You can install it by typing:
apt install awscli

awscli 설치

ec2-shell> sudo apt install awscli

aws 명령어로 확인

ec2-shell> aws
usage: aws [options]   [ ...] [parameters]
To see help text, you can run:

  aws help
  aws  help
  aws   help
aws: error: the following arguments are required: command

이렇게 설치하면 모든 계정이 awscli 사용이 가능합니다.

AWS cli 설정

위 설치 과정을 완료후에 바로 사용할 수 있으면 좋겠지만 중요한 과정인 계정 access  key 셋팅을 포함한 기타 설정 과정을 완료해야 cli를 사용 할 수 있습니다. Access Key를 만들기 위해서는 먼저 IAM 에서 유저를 생성해야 합니다.

1. IAM 유저 생성

먼저 aws 콘솔에서 IAM 서비스로 이동합니다. 왼쪽 메뉴에 Users 가 있는데 이 것을 클릭하고 기존에 User가 없으면 생성하는 과정이 필요합니다. 새 User가 속할 그룹도 만들어야 합니다. 복잡해 보이는데 이 과정은 줄일 수가 없어서 감내해야 합니다.

User Name을 적어주세요. 그리고 지금 생성하는 유저는 AWS콘솔용 유저가 아니고 CLI에서 사용할 User 이기 때문에아래 캡쳐화면과 같이 Programmatic access 를 체크해줍니다.

다음 단계로 갔는데 기존에 사용하던 그룹이 없으면 이것 또한 만들어야 합니다. 이 유저그룹은 해당 유저가 어떠한 권한을 가지게 될지에 대해서 범위를 정해주는 역할을 하게 됩니다.

아래 캡쳐화면과 같이 사용하실 그룹 이름을 적어줍니다. 그리고 하단 테이블에서 이 유저가 가지게 될 policy type이 어떤 것인지 선택해야 합니다. 다중 선택도 가능합니다. 혹은 그룹 한개당 한개의 policy만 선택해서 여러개를 만들어 놓고 나중에 유저의 그룹을 다중으로 선택해도 됩니다. 일단 여기에서는 CLI를 테스트 할때 S3을 이용할 계획이기 때문에 S3에 대한  Full Access할 수 있는 policy type을 선택하겠습니다.

생성한 그룹중에서 원하는 그룹을 선택해줍니다. 이 예제에서는 CLI가 되겠습니다.

2. Access Key 생성

새로 유저를 생성하게 되면 그 유저를 선택해서 Access Key를 생성할 수 있습니다. 긴 과정을 거쳐서 이제 거의 다 왔습니다.  Access Key를 생성하면 아래와 같이 생성된 키를 볼수 있는 창이 하나 나옵니다. 캡쳐 화면에서 보신것과 같이 생성하신 Key는 다운로드 하셔서 보관하시는 것을 추천합니다. 이 화면에서 close 하면 다시는 Secret Key를 aws 콘솔에서는 찾을 수 가 없습니다. Secret key가 **** 표시 되어 있는데 “Show”를 클릭하면 볼 수 있습니다.

키 분실에 대해서 너무 걱정안하셔도 되긴 합니다. 얼마든지 새로 생성할 수 있습니다. 이렇게 Key ID와 Secret Key를 생성한것을 aws cli에 셋팅해주어야 합니다.

3. AWS configure

configure 옵션을 사용하여 셋팅합니다.
ec2-shell> aws configure
위와 같이 명렁어를 실행시키면 아래와 같은 입력 라인(한줄씩 나옵니다.)이 나옵니다.

AWS Access Key ID [None]: #여기엔 위에서 생성한 Key ID를 붙여넣고 엔터
AWS Secret Access Key [None]:  # Secret Key를 붙여놓고 엔터
Default region name [None]:  ap-northeast-2 # 디폴트로 cli를 사용할 resoin을 씁니다.  이 예시는  서울 리전 입니다.
Default output format [None]:  # 여기는 그냥 엔터로 넘어갔니다.

참고로 각 resion의 endpoint및 resion이름을 알수 있는 페이지를 AWS에서 제공하고 있습니다. 본인의 resion을 모르시면 여기서 찾아보시면 됩니다. http://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/using-regions-availability-zones.html

자 이제 셋팅을 마쳤으니 테스트를 해보겠습니다.

ec2-shell> aws s3 ls
2017-02-10 00:48:24 algopie-api
2017-02-17 01:04:48 algopie-public

이렇게 S3 버킷이 이미 존재한다면 ls로 리스트가 나옵니다. cli의 S3 에서 가장 많이 사용하게 될 것은 아마 cp, mv, rm 정도가 아닐까 생각됩니다.

간단한 확인으로 S3를 어떻게 제어하는지 옵션을 어떻게 써야 하는지 보려면 아래와 같이 help 옵션을 사용하시면 아주 익숙한 man page가 나옵니다.

ec2-shell> aws s3 help

s3 외에도 다양한 서비스들을 command line으로 관리할수 있는 강력한 툴이 바로 aws cli 입니다.