Developer's Development

3.4.12 [클라우드] AWS 인프라: 데이터 저장 본문

AI 활용 애플리케이션 개발/클라우드

3.4.12 [클라우드] AWS 인프라: 데이터 저장

mylee 2025. 10. 28. 19:10
Amazon RDS (Relational Database Service)

 

Amazon RDS는 AWS에서 제공하는 관리형 관계형 데이터베이스 서비스이다.

MySQL, PostgreSQL, Oracle, SQL Server, MariaDB, Aurora 등 다양한 엔진을 지원한다.

AWS에서 자동으로 설치, 백업, 모니터링, 스냅샷, 스케일링 등을 관리해주기 때문에, 사용자는 데이터베이스 자체 운영 부담 없이 사용할 수 있다.

- 일반적으로 EC2에 직접 DB를 설치하는 방식보다 보안과 유지 관리, 확장성이 뛰어나다.

 

  • 구조

- DB 인스턴스: RDS에서 실제로 실행되는 데이터베이스 서버 (EC2처럼 인스턴스로 관리)

- 스토리지: RDS는 자동 백업/복구를 지원하며, EBS 기반 스토리지로 구성

- 엔드포인트(Endpoint): Django나 다른 애플리케이션이 DB에 접속하기 위한 주소 및 포트 정보 

 

 

실습

 

EC2)

- 인스턴스 시작

  - 이름 및 태그: django_docker

  - 애플리케이션 및 OS 이미지: Ubuntu Server 22.04 LTS

  - 인스턴스 유형: t2.micro

  - 키 페어(로그인): 키페어 생성

  - 네트워크 설정

  : 새 기본 VPC 생성 후 편집 버튼 클릭, 항목 옆 새로고침으로 VPC 채우기

    보안 그룹 규칙(4개): ssh, HTTP, HTTPS, 사용자 지정 TCP만 포트 범위 8080 / 소스 유형 모두 위치 무관

    스토리지 구성: 30 GiB

  → 인스턴스 시작

 

- 네트워크 및 보안 > 탄력적 IP > 탄력적 IP 주소 할당 (기본값) 

- EC2 > 탄력적 IP 주소 > 탄력적 IP 주소 연결: 생성한 인스턴스 선택 후 연결 

 

  • vscode

django_docker/.env 추가

settings.py의 SECRET_KEY를 .env의 DJANGO_ SECRET_KEY로 추가 

 

django_docker/settings.py 수정

# load_dotenv 없으면 cmd에서 설치: pip install python-dotenv

from dotenv import load_dotenv
import os

SECRET_KEY = os.getenv('DJANGO_SECRET_KEY')
...
ALLOWED_HOSTS = ["loalhost", "3.36.183.190"]

 

cmd

pip freeze > requirements.txt

 

requirements.txt 수정

Django==5.2.7
django-filter==25.2
djangorestframework==3.16.1
drf-nested-routers==0.95.0
drf-yasg==1.21.11
fastapi==0.119.1
gunicorn==23.0.0
mysqlclient==2.2.7
pandas==2.3.2
pillow==12.0.0
python-dotenv==1.1.1
sqlparse==0.5.3
uritemplate==4.2.0
uvicorn==0.38.0
wheel==0.45.1

 

django_docker/.gitignore 추가

__pycache__/
*.pyc
*.pyo
*.pyd
*.sqlite3

venv/
.env/
*.env

.vscode/
.idea/

 

git에 repository 생성, commit

git bash

# django_docker.pem 있는 폴더 경로로 이동
ssh -i django_docker.pem ubuntu@3.36.183.190
$ sudo apt update
$ sudo apt install -y docker.io docker-compose git
$ sudo usermod -aG docker ubuntu
$ newgrp docker
$ git clone https://github.com/mylee99125/django_docker.git

# django_docker.pem 있는 폴더 경로에서 새로 git bash open (위에꺼 그대로 두기)
# 작업 폴더에 있던 .env 파일 보내야 함 (clone받은 파일에 없어서), 파일 보낼 땐 pem 키 필요
scp -i django_docker.pem django_docker/.env ubuntu@3.36.183.190:/home/ubuntu/django_docker

# 다시 원래 bash로 이동
$ cd django_docker
# 받은 .env 확인
$ ls -a		
$ docker-compose build

# requirements.txt 수정 후 (local)push, (ubuntu)pull 다시
# git fetch
$ git pull
$ docker-compose build
$ docker images
$ docker-compose up

 

EC2 > 인스턴스 > 종료, 삭제 

탄력적 IP 주소 릴리스 

VPC 삭제 

 

  • AWS

Aurora and RDS > 데이터베이스 생성

- 엔진옵션: MySQL

- 템플릿: 프리 티어

- 마스터 암호 설정

- 연결 > 퍼블릭 액세스: 예

→ 데이터베이스 생성

 

보안 그룹 > 인바운드 규칙 편집

규칙 추가: 3306, Anywhere-IPv4

 

(Windows) 환경변수 설정 → C:\Program Files\MySQL\MySQL Server 8.0\bin

(Windows) cmd

mysql --version

# mysql -h <엔드포인트> -P <포트번호> -u <사용자명> -p
mysql -h database-1.crw6u22w4deh.ap-northeast-2.rds.amazonaws.com -P 3306 -u admin -p
# 비밀번호 입력

# test
mysql> select now();
mysql> create database testdb character set utf8mb4 collate utf8mb4_unicode_ci;
mysql> use testdb;

 

django_docker > settings.py DATABASES 수정

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'testdb',
        'USER': 'admin',
        'PASSWORD': '비밀번호',
        'HOST': '호스트명',
        'PORT': '3306',
        'OPTIONS': {
            'charset': 'utf8mb4'
        }
    }
}

 

cmd

django-admin startapp blog	# settings.py에 INSTALLED_APPS에도 추가

 

django_docker/blog/models.py 수정

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

 

cmd

python manage.py makemigrations
python manage.py migrate
# 우와 잘 된당

python manage.py shell
>>> from blog.models import Post
>>> Post.objects.create(title='RDS에 데이터베이스를', content='올려보았습니다. 이게 정말 될까요?')
<Post: Post object (1)>

 

(Windows) cmd

mysql> select * from blog_post;
# 결과 확인!
mysql> ^Z
Bye

 

인스턴스 삭제

 

 

Amazon S3

 

👉🏻 객체 스토리지 (Object Storage)

Amazon S3는 객체 스토리지 방식의 저장 서비스이다. 객체는 파일 데이터와 메타데이터, 고유 식별자를 포함한 단위로 저장한다.

계층 구조 없이 평면적으로 저장되며, Key를 기반으로 객체에 접근한다.

 

👉🏻 구성 요소 및 구조

- 버킷 (Bucket): S3에서 객체를 저장하는 최상위 컨테이너이다. 하나의 AWS 계정은 여러 버킷을 만들 수 있다.

- 객체 (Object): 실제 저장되는 데이터 파일로, 메타데이터와 고유 키(Key)를 가진다.

- 키 (Key): 버킷 내 객체를 식별하는 고유한 경로 문자열이다. 

 

👉🏻 정적 웹 호스팅

- S3는 버킷을 정적 웹사이트로 호스팅할 수 있는 기능을 제공한다.

- HTML, CSS, JS 파일을 업로드하고 호스팅 URL을 통해 웹사이트처럼 접근할 수 있다.

- 주로 랜딩 페이지, 프론트엔드 정적 웹 서비스 등에 사용된다.

 

 

Django-외부 저장소 연동

 

  • 정적 파일 처리 구조

Django는 사용자 요청을 처리하는 것 외에도, 웹 서비스에 필요한 정적 자원(css, js, 이미지)과 사용자 업로드 파일을 관리해야 한다.

👉🏻 Django의 자원

- 정적 파일(Static Files): 개발자가 미리 준비한 자원으로, 일반적으로 서버(EC2) 내부에 저장되어 직접 제공된다.

- 미디어 파일(Media Files): 사용자가 업로드한 파일로, 저장소를 분리하여 외부 스토리지(S3 등)에 저장하는 방식이 일반적이다.

 

  • django-storages 동작

Django에서 다양한 외부 저장소(S3, Azure Blob 등)를 연동할 수 있도록 도와주는 라이브러리이다.

내부적으로 boto3 (AWS SDK for Pythob)를 사용하여 Amazon S3와 통신한다.

- settings.py에서 DEFAULT_FILE_STORAGE를 지정하면, 미디어 파일 저장 위치를 로컬이 아닌 S3로 전환할 수 있다.

 

  • AWS 인증키 관리 (.env 활용 + boto3 기반 연동)

AWS 자격 증명은 일반적으로 두 가지 방식으로 관리된다.

- 직접 설정: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY를 코드나 설정에 직접 입력

- 환경변수 또는 .env 파일: 민감한 정보를 외부화하여 관리

→ .env 파일에 자격정보를 저장하고, python-dotenv 또는 os.environ을 통해 로드하는 방식이 권장된다.

 

인증키를 안전하게 관리하면 S3 버킷과의 통신 시 자동 인증이 이루어지며, 파일 업로드/다운로드가 가능해진다.

 

 

실습

 

  • AWS

Amazon S3 > 버킷 > 버킷 만들기

- 버킷 이름: mylee-django-docker

 

IAM > 사용자 > student

보안 자격 증명 > 액세스 > 액세스 키 만들기

- 사용 사례: AWS 컴퓨팅 서비스에서 실행되는 애플리케이션, 확인 체크 

- 설명 태그 설정(선택 사항): django S3 Access 

- 액세스 키 검색 > .csv 파일 다운로드 

 

  • vscode

cmd

pip install boto3 django-storages

 

django_docker/.env 수정

DJANGO_SECRET_KEY = 'django-insecure-***'
AWS_ACCESS_KEY_ID = # csv 파일 첫 항목 
AWS_SECRET_ACCESS_KEY = # csv 파일 두번째 항목 
AWS_STORAGE_BUCKET_NAME = mylee-django-docker
AWS_S3_REGION_NAME = ap-northeast-2

 

django_docker/django_docker/settings.py 수정

# 맨 아래에 추가
# 스토리지 설정
STORAGES = {
    "default": {
        "BACKEND": "storages.backends.s3boto3.S3Boto3Storage",
    },
    "staticfiles": {
        "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
    },
}

# AWS 설정
AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.getenv('AWS_STORAGE_BUCKET_NAME')
AWS_S3_REGION_NAME = os.getenv('AWS_S3_REGION_NAME')
AWS_S3_SIGNATURE_VERSION = 's3v4'

 

django_docker/blog/templates 폴더 추가

django_docker/blog/forms.py 파일 추가

from django import forms
from .models import UploadedImage

class UploadImageForm(forms.ModelForm):
    class Meta:
        model = UploadedImage
        fields = ['title', 'image']

 

django_docker/blog/models.py 내용 추가

class UploadedImage(models.Model):
    title = models.CharField(max_length=100)
    image = models.ImageField(upload_to='media/')
    uploaded_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

 

django_docker/blog/views.py 수정

from django.shortcuts import render, redirect
from .forms import UploadImageForm
from .models import UploadedImage

def image_upload_view(request):
    if request.method == 'POST':
        form = UploadImageForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('upload_success')
    else:
        form = UploadImageForm()
        return render(request, 'image_upload.html', {'form': form})

def upload_success_view(request):
    images = UploadedImage.object.all()
    return render(request, 'upload_success.html', {'images': images})

 

django_docker/django_docker/urls.py 수정

# urlpatterns에 추가
path('blog/', include('blog.urls'))

 

django_docker/blog/urls.py 수정

from django.urls import path
from . import views

urlpatterns = [
    path('', views.images_upload_view, name='image_upload'),
    path('success/', views.images_upload_view, name='upload_success')
]

 

django_docker/blog/templates/image_upload.html, upload_success.html 추가

<!-- image_upload.html -->
<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">사진 업로드</button>
</form>

<!-- upload_success.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>Uploaded Images</h1>
    {% for img in images %}
        <p>{{ img.title }}</p>
        <img src="{{ img.get_presigned_url }}" width="300"/>
    {% endfor %}
</body>
</html>

 

AWS

IAM > 사용자 > student > 권한 > 권한 추가: 인라인 정책 생성

- 시각적 → JSON

- 정책 편집기 수정

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
			    "s3:PutObject",
			    "s3:GettObject"
		    ],
			"Resource": "arn:aws:s3:::mylee-django-docker/*"
		}
	]
}

 

- 정책 이름: s3_putObject 

 

vscode

blog/migrations/init 만 남기고 폴더 내 나머지 파일 삭제

프로젝트 내 pycache 폴더 모두 삭제 

 

django_docker/django_docker/settings.py DATABASES 수정

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'testdb',
        'USER': 'django',
        'PASSWORD': 'django',
        'HOST': 'localhost',
        'PORT': '3306',
        'OPTIONS': {
            'charset': 'utf8mb4'
        }
    }
}

 

MySQL Workbench

create database testdb character set utf8mb4 collate utf8mb4_unicode_ci;
grant all privileges on testdb.* to 'django'@'%';

 

vscode

cmd

cd django_docker
python manage.py makemigrations
python manage.py migrate
python manage.py runserver

 

테스트 완료 후 버킷 삭제