AWS S3 + CloudFront로 정적 파일 서빙 완전 가이드
안녕하세요! 오늘은 AWS S3와 CloudFront를 사용하여 정적 파일을 효율적으로 서빙하는 방법에 대해 알아보겠습니다.
왜 S3와 CloudFront를 사용할까요?
- 높은 가용성: AWS의 글로벌 인프라를 활용
- 빠른 전송 속도: CloudFront의 CDN 기능으로 전 세계 사용자에게 빠른 전송
- 비용 효율성: 사용한 만큼만 지불
- 보안: AWS의 보안 기능 활용
- 확장성: 트래픽 증가에 자동 대응
1. S3 버킷 설정
1.1 버킷 생성 및 설정
import boto3
def create_s3_bucket():
s3 = boto3.client('s3')
# 버킷 생성
bucket_name = 'your-static-files-bucket'
s3.create_bucket(
Bucket=bucket_name,
CreateBucketConfiguration={
'LocationConstraint': 'ap-northeast-2'
}
)
# 버킷 정책 설정
bucket_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": f"arn:aws:s3:::{bucket_name}/*"
}
]
}
s3.put_bucket_policy(
Bucket=bucket_name,
Policy=json.dumps(bucket_policy)
)
return bucket_name
1.2 CORS 설정
def set_cors_policy():
s3 = boto3.client('s3')
cors_configuration = {
'CORSRules': [{
'AllowedHeaders': ['*'],
'AllowedMethods': ['GET', 'HEAD'],
'AllowedOrigins': ['*'],
'ExposeHeaders': ['ETag'],
'MaxAgeSeconds': 3000
}]
}
s3.put_bucket_cors(
Bucket='your-static-files-bucket',
CORSConfiguration=cors_configuration
)
2. CloudFront 배포 설정
2.1 CloudFront 배포 생성
def create_cloudfront_distribution():
cloudfront = boto3.client('cloudfront')
distribution_config = {
'CallerReference': str(uuid.uuid4()),
'DefaultRootObject': 'index.html',
'Origins': {
'Quantity': 1,
'Items': [{
'Id': 'S3-Origin',
'DomainName': 'your-static-files-bucket.s3.ap-northeast-2.amazonaws.com',
'S3OriginConfig': {
'OriginAccessIdentity': ''
}
}]
},
'DefaultCacheBehavior': {
'TargetOriginId': 'S3-Origin',
'ForwardedValues': {
'QueryString': False,
'Cookies': {'Forward': 'none'}
},
'TrustedSigners': {
'Enabled': False,
'Quantity': 0
},
'ViewerProtocolPolicy': 'redirect-to-https',
'MinTTL': 3600
},
'Enabled': True
}
response = cloudfront.create_distribution(
DistributionConfig=distribution_config
)
return response['Distribution']['Id']
2.2 캐시 정책 설정
def set_cache_policy():
cloudfront = boto3.client('cloudfront')
cache_policy = {
'Name': 'StaticFilesCachePolicy',
'Comment': 'Cache policy for static files',
'DefaultTTL': 86400, # 24 hours
'MaxTTL': 604800, # 7 days
'MinTTL': 3600, # 1 hour
'ParametersInCacheKeyAndForwardedToOrigin': {
'EnableAcceptEncodingGzip': True,
'EnableAcceptEncodingBrotli': True,
'HeadersConfig': {
'HeaderBehavior': 'none'
},
'CookiesConfig': {
'CookieBehavior': 'none'
},
'QueryStringsConfig': {
'QueryStringBehavior': 'none'
}
}
}
response = cloudfront.create_cache_policy(
CachePolicyConfig=cache_policy
)
return response['CachePolicy']['Id']
3. Django 설정
3.1 Django Storage 설정
# settings.py
AWS_ACCESS_KEY_ID = 'your-access-key'
AWS_SECRET_ACCESS_KEY = 'your-secret-key'
AWS_STORAGE_BUCKET_NAME = 'your-static-files-bucket'
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
AWS_LOCATION = 'static'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{AWS_LOCATION}/'
3.2 정적 파일 업로드
from storages.backends.s3boto3 import S3Boto3Storage
class StaticStorage(S3Boto3Storage):
location = 'static'
default_acl = 'public-read'
class MediaStorage(S3Boto3Storage):
location = 'media'
default_acl = 'public-read'
file_overwrite = False
4. 파일 업로드 및 관리
4.1 파일 업로드
def upload_to_s3(file_path, s3_path):
s3 = boto3.client('s3')
try:
s3.upload_file(
file_path,
'your-static-files-bucket',
s3_path,
ExtraArgs={
'ACL': 'public-read',
'CacheControl': 'max-age=86400'
}
)
return True
except Exception as e:
print(f"Error uploading file: {str(e)}")
return False
4.2 파일 삭제
def delete_from_s3(s3_path):
s3 = boto3.client('s3')
try:
s3.delete_object(
Bucket='your-static-files-bucket',
Key=s3_path
)
return True
except Exception as e:
print(f"Error deleting file: {str(e)}")
return False
5. 성능 최적화
5.1 Gzip 압축 설정
def enable_gzip_compression():
s3 = boto3.client('s3')
compression_rules = {
'Rules': [
{
'ApplyServerSideEncryptionByDefault': {
'SSEAlgorithm': 'AES256'
},
'ID': 'EnableCompression',
'Priority': 1,
'Filter': {
'Prefix': ''
},
'Transitions': [],
'Status': 'Enabled'
}
]
}
s3.put_bucket_lifecycle_configuration(
Bucket='your-static-files-bucket',
LifecycleConfiguration=compression_rules
)
5.2 캐시 무효화
def invalidate_cloudfront_cache(paths):
cloudfront = boto3.client('cloudfront')
response = cloudfront.create_invalidation(
DistributionId='your-distribution-id',
InvalidationBatch={
'Paths': {
'Quantity': len(paths),
'Items': paths
},
'CallerReference': str(uuid.uuid4())
}
)
return response['Invalidation']['Id']
6. 보안 설정
6.1 버킷 정책
def update_bucket_policy():
s3 = boto3.client('s3')
bucket_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-static-files-bucket/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::account-id:distribution/your-distribution-id"
}
}
}
]
}
s3.put_bucket_policy(
Bucket='your-static-files-bucket',
Policy=json.dumps(bucket_policy)
)
6.2 Origin Access Identity 설정
def create_origin_access_identity():
cloudfront = boto3.client('cloudfront')
response = cloudfront.create_cloud_front_origin_access_identity(
CloudFrontOriginAccessIdentityConfig={
'CallerReference': str(uuid.uuid4()),
'Comment': 'Access identity for static files'
}
)
return response['CloudFrontOriginAccessIdentity']['Id']
7. 모니터링 및 로깅
7.1 CloudFront 로깅 설정
def enable_cloudfront_logging():
cloudfront = boto3.client('cloudfront')
logging_config = {
'Enabled': True,
'IncludeCookies': False,
'Bucket': 'your-logging-bucket.s3.amazonaws.com',
'Prefix': 'cloudfront-logs/'
}
cloudfront.update_distribution(
DistributionConfig={
'CallerReference': str(uuid.uuid4()),
'DefaultRootObject': 'index.html',
'Origins': {
'Quantity': 1,
'Items': [{
'Id': 'S3-Origin',
'DomainName': 'your-static-files-bucket.s3.amazonaws.com',
'S3OriginConfig': {
'OriginAccessIdentity': ''
}
}]
},
'DefaultCacheBehavior': {
'TargetOriginId': 'S3-Origin',
'ForwardedValues': {
'QueryString': False,
'Cookies': {'Forward': 'none'}
},
'ViewerProtocolPolicy': 'redirect-to-https',
'MinTTL': 3600
},
'Logging': logging_config,
'Enabled': True
},
Id='your-distribution-id'
)
결론
AWS S3와 CloudFront를 사용하여 정적 파일을 효율적으로 서빙하는 방법을 알아보았습니다. 이 설정을 통해 전 세계 사용자에게 빠르고 안정적인 파일 서비스를 제공할 수 있습니다. 추가적인 질문이나 궁금한 점이 있으시면 댓글로 남겨주세요!

댓글
댓글 쓰기