AWS 이용해 이미지 S3 스토리지에 업로드하기
django에서 업로드할 이미지를 aws 서버에 올리기 전 aws에 대한 간단한 개념을 살펴보았다. 시간을 들여 점점 깊이있게 공부할 예정이다 :-)
클라우드 서비스란?
- 어디에나 존재하는 인터넷이라는 의미로 사용자의 문서나, 이미지, 영상등 다양한 데이터를 서버에 저장한뒤 PC나 스마트폰등으로 접속하여 해당 데이터를 이용하거나 편집하게 도와주는 서비스이다.
- 과거에는 유저들이 사용하는 데이터를 USB등에 담아 보관해 사용했었다면 현재는 클라우드를 통해 다른 플랫폼에서도 저장해놓은 동일한 데이터를 사용할 수 있게 되었다.
클라우드 서비스 유형에는 무엇이 있는가?
-
IaaS(인프라 서비스) = 데이터 저장공간 + 서버
서버와 스토리지, 네트워크 장비등의 it 인프라 장비를 빌려주는 서비스로 이용자가 직접 데이터센터를 구축할 필요없이 클라우드 환경에서 필요한 인프라를 빌려와 운영체제를 설치하고 애플리케이션을 설치한 다음 원하는 서비스를 운영한다.예를 들자면 넷플릭스는 aws의 iaas 서비스를 이용하여 운영하는 서비스이다. ex) amazon web service, microsoft azure, google compute engine
-
PaaS(플랫폼 서비스) = 데이터 저장공간 + 서버 + 플랫폼
소프트웨어 서비스를 개발할 때 필요한 플랫폼을 제공하는 서비스로 사용자는 필요한 서비스를 선택해 애플리케이션을 개발한다. 개발자가 소프트웨어를 개발할때 필요한 API를 제공하여 개발자가 좀 더 편하게 앱을 개발 할 수 있게 돕는다. ex) google app engine
-
Saas(소프트웨어 서비스) = 데이터 저장공간 + 서버 + 소프트웨어
지메일이나 드롭박스 ,네이버 클라우드처럼 소프트웨어를 웹에서 쓸 수 있는 서비스로 지메일을 예를 들어본다면 이메일을 보내고 받는 과정에서 따로 소프트웨어를 설치하지 않고 웹사이트에 들어가 주소를 입력하고 보내면 끝난다. 이처럼 모든 서비스가 클라우드에서 이루어져 pc에 따로 설치하지 않아도 웹에서 소프트웨어를 빌려 쓸 수 있다. ex) google app, dropbox
클라우드 컴퓨팅이란?
사용자의 직접적인 활발한 관리 없이 데이터 스토리지와 시스템 리소스를 필요시 바로 제공하는 것을 말한다. 데이터 정보를 자신의 컴퓨터가 아닌 클라우드에 연결된 다른 컴퓨터(휴대폰, TV, 노트북 등등)로 처리하는 기술을 말한다.
AWS(Amazon Web Service)란
AWS는 아마존에서 개발한 클라우드 컴퓨팅 플랫폼으로 클라우드 컴퓨팅을 통해 웹사이트를 관리하는데 필요한 많은 기능을 제공해준다. 웹사이트를 운영하는데 필요한 서버나 DB, 스토리지등을 제공하는 등 개발자가 사용 가능한 기능을 제공하는 플랫폼을 제공하며 PaaS이다.
IAM(Identity and Access Management)이란
AWS 리소스에 대한 안전한 접근제어를 제공하는 서비스로 IAM을 사용하여 리소스를 사용하도록 인증 및 권한 부여된 대상을 제어한다.
S3(Simple Storage Service)란
인터넷 스토리지 서비스로 웹에서 언제 어디서나 원하는 양의 데이터를 저장하고 검색할 수 있다.
객체(Object)
s3에 데이터(이미지, 동영상, 파일)가 저장되는 기본 단위는 객체로 파일과 메타데이터로 이루어져 있다.
객체의 구성요소
key
: 파일명
value
: 파일에 대한 데이터
메타데이터
: 데이터의 데이터라는 뜻이며 언제 파일이 업로드 되었는지, owner, 수정등에 대한 데이터이다
cors
: 리전을 무시하고 한 버킷의 파일을 다른 버킷에서 접근할 수 있도록 한다
버킷(Bucket)
s3에서 생성할 수 있는 최상위 디렉토리의 개념으로 버킷의 이름은 유일해야 하며 계정별로 100개까지 생성이 가능하고 버킷에 저장할 수 있는 객체의 수는 무제한이다. 버킷별로 접근제어 설정이 가능하다.
Key
: 버킷 내에서 객체를 찾기 위해 사용되는 고유 식별자이다. 보통 디렉터리+파일명으로 이름이 지어진다. 업로드 할 이미지의 네임이 동일할 수 있음을 고려하여 date를 추가해 네임을 지을 수 도 있다.
Region
: 버킷 생성시 버킷의 위치를 지정할 수 있다. 버킷의 위치를 어디에 지정하느냐에 따라서 지연 시간의 최적화나 비용의 최소화등이 결정된다.
AWS에서 제공하는 S3 스토리지 서비스를 사용하여 이미지를 서버에 업로드 시켜보자
-
IAM 사용자 추가하기
-
AWS S3 Bucket 생성하기
IAM 등을 설정하는 방법은 다양하니까 자신의 상황에 맞게 설정에 대한 내용을 찾아보고 설정해주면 될 것 같다. 나는 연습용으로 서버에 이미지를 올리는 것을 목적으로 구축하였기 때문에 퍼블릭으로 설정하되 익명의 사용자에 대한 권한을 readonly로 주어 제한시켜 사용하였다
- IAM과 S3를 설정하는 방법을 간단하게 설명하겠다
1. 가장먼저 필요한 것은 회원가입이다. 해외에서 결제가 가능한 카드를 준비해서 회원가입시 적어주면된다. 회원가입은 어렵지 않으니 회원가입을 따라서 천천히 한다.
2. 검색창에 iam을 입력후 사용자 추가를 눌러준 후 아래와 같이 입력해준다. 이때 3,4번 단계는 설정 필요없이 넘어가 주면 된다. 주의할점은 5단계에서 csv파일은 꼭! 저장해야 한다. 나중에 장고에서 설정할때 필요한 아이들이므로 저장해준다. 해당 페이지에서만 제공해주므로 이것만 주의해서 설정해주자
3. 버킷을 만들어준다. 검색창에 s3를 검색후 버킷만들기를 눌러준후 아래와 같이 입력해준다. 이때 주의할점은 버킷은 앞에서 말했듯이 아이디처럼 고유한 이름이어야 한다. 나는 연습용으로 만드는 것이기 때문에 모든 퍼블릭 액세스 차단 버튼을 해제해 설정하였다.
4. 이후 익명의 사용자에 대한 권한을 제어하기 위해 만들어진 버킷에서 권한을 선택해 버킷 정책을 편집해준다. 이때 아래의 내용을 넣어주면 되는데 여기서 주의할점은 Resource부분에 버킷의 네임을 내가 설정한 네임으로 넣어주어야 한다. 스펠링이 틀리면 오류가 발생하니 바로 위에 있는 네임을 복사해서 사용해주자
아래에 보이는 이미지에 있는 내용을 버킷정책에 넣어주면 된다. 해당 내용이 있는 링크는 여기를 누르면 된다
5. 이제 사전 설정은 끝이 났다. 이제 장고에서 이미지를 업로드 했을때 서버에 저장될 수 있도록 설정해주면 된다.
장고 설정
4단계정도로 나누어 설정을 해주었다.
- visual studio에서 가상환경을 구축한 후 project와 app을 만들어준다.
- 나의 저장공간인 S3에 이미지 파일을 저장하기 위한 사전 설정을 해준다 (settings.py, .env등)
- 이미지는 장고 DB에서도 저장되어야 하기 때문에 이미지를 저장할 model을 만들어준다.
- index 템플릿을 만들어 이곳에서 form으로 image를 post요청으로 보내고 view에서 s3의 스토리지에 저장하는 로직을 작성한다.
1. 가장 먼저 config라는 프로젝트와 s3라는 앱을 만든 후 pip install django-environ
, pip install boto3
, touch .gitignore
을 설치한다
- django-environ : settings.py에서 .env파일에 있는 것을 environ을 통해 읽어온다. .env에는 s3 access를 위한 secret key를 넣어준다(사전에 저장해 놓은 csv내용들) 그리고 이를 gitignore 파일에 추가한다. 그리고 이들을 불러와 쓸때 environ을 통해 사용하면 된다
- boto3 : s3를 사용하기 위한 모듈이다
2. config에 .env파일을 만들어 다운받았던 csv내용을 내용에 맞게 적어주면 된다. .env파일은 gitignore에 추가해주는 것을 잊지말자 !
AWS_ACCESS_KEY_ID="Csv 참고"
AWS_SECRET_ACCESS_KEY="Csv 참고"
AWS_STORAGE_BUCKET_NAME="설정한 버킷 이름"
3. settings.py에서 .env에 있는 내용을 environ을 통해 읽어온다
# settings.py
import environ
env = environ.Env()
environ.Env.read_env()
AWS_ACCESS_KEY_ID=env('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY=env('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME=env('AWS_STORAGE_BUCKET_NAME')
AWS_S3_REGION_NAME='ap-northeast-2' # 버킷 생성할때 지정한 region을 작성한다
AWS_S3_FILE_OVERWRITE=False # 기본적인 오버라이트 설정 false
4. 이미지를 저장할 model을 만들어준다. media폴더를 사용할때는 ImageField를 사용하였지만 S3에 저장할땐 url을 저장해서 나중에 화면에 이미지를 불러올때 src에 저장한 url을 통해 불러온다
class Post(models.Model):
title = models.CharField(max_length=64) # 이미지의 타이틀, 필수는 아니다
url = models.TextField() # 이미지 url, 길수도 있으므로 TextField로 설정
def __str__(self):
return self.title
5. 이미지를 업로드하고 불러올 수 있는 index 템플릿을 작성한다
{% for post in posts %} # view에서 등록한 post를 전부 보여준다
<img class="img" src="{{post.url}}" alt="{{post.title}}">
{% endfor %}
<form action="{% url 'index' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="img">
<input type="text" name="title" placeholder="file name/">
<button type="submit">post</button>
</form>
6. form에서 url이 index인 곳으로 post요청을 보내므로 이에 맞게 url을 지정해준다(config에서 url을 설정하던 app에서 url을 작성하던 이건 자유다. 참고로 나는 config에서 app을 include받아 사용했다)
7. 이제 view를 작성해보자
import boto3
from boto3.session import Session
from config.settings import AWS_ACCESS_KEY_ID, AWS_S3_REGION_NAME, AWS_SECRET_ACCESS_KEY, AWS_STORAGE_BUCKET_NAME
def index(request):
if request.method == 'POST':
# 들어온 요청에서 이미지를 꺼낸다
file = request.FILES.get('img') - 1
session = Session( - 2
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name=AWS_S3_REGION_NAME
)
s3 = session.resource('s3') - 3
now = datetime.now().strftime('%Y%H%M%S') - 4
img_object = s3.Bucket(AWS_STORAGE_BUCKET_NAME).put_object( - 5
Key = now+file.name,
Body = file
)
s3_url = "https://django-s3-practices.s3.ap-northeast-2.amazonaws.com/" - 6
Post.objects.create( - 7
title = request.POST['title'],
url = s3_url+now+file.name
)
return redirect('index')
posts = Post.objects.all()
return render(request, 'index.html',{'posts':posts})
-
form에서 등록한 이미지의 데이터를 file 변수에 넣는다
-
session을 생성해준다. 이때 3가지는 settings.py에서 import하여 사용한다
-
만들어진 세션을 통해 나의 s3에 접근한다.
-
만들어지는 이미지의 파일명 중복을 피하기 위해 생성되는 시간을 url에 함께 넣어준다
-
put_object 메서드로 s3 버킷에 파일을 key와 body로 담는다. 이때 key에는 파일 이름과 생성시간이 들어간다. body에는 생성된 file이 들어간다
-
나의 버킷주소를 s3_url에 넣어준다
-
생성되는 post를 등록할때 url에 버킷의 url과 버킷에 들어간 key값을 넣어준다. 해당 url은 실제 템플릿에 있는 img src에 들어갈 url로 버킷에 있는 key에 접근하여 해당되는 파일에 접근하는 방식이 된다.
이제 모델과 s3 스토리지에 업로드하는 이미지가 잘 등록되는지 확인해보자 :-)
👏 다음번엔 이를 이용해 프로필 이미지 등록과 여러 제품 이미지 등록에 대한 부분을 다룰 예정이다