우당탕탕
AWS S3 정적 웹사이트 호스팅에 CloudFront 연결하면서 겪은 삽질과 해결법 본문
AWS S3 정적 웹사이트 호스팅에 CloudFront 연결하면서 겪은 삽질과 해결법
사실 이걸 설정하면서 생각보다 많은 삽질을 했어요. AWS S3에 정적 웹사이트를 올리고, 거기에 CloudFront를 연결하려는데 자꾸 403 에러가 나고, 캐시 문제도 복잡해서 시간이 꽤 걸렸거든요.
이 글에서는 AWS S3 정적 웹사이트 호스팅을 세팅하는 기본 과정부터, CloudFront 배포로 연결하는 방법, 그리고 제가 막혔던 구체적인 문제들과 그 해결법을 단계별로 소개할게요. 각 단계에서 꼭 설정해야 할 권한, 정책, 그리고 명령어도 빠짐없이 담았어요.
AWS S3 정적 웹사이트 호스팅 CloudFront 연결 관련 정보
AWS S3 정적 웹사이트 기본 세팅과 버전 정보
저는 AWS CLI 버전 2.14, 콘솔 기준으로 작업했어요. S3 버킷은 서울 리전(ap-northeast-2)을 썼고, 버킷 이름은 my-static-site-bucket입니다.
이제 정적 웹사이트 호스팅을 위한 버킷 정책 설정과 인덱스 문서 및 오류 문서 등록 방법부터 시작할게요.
S3에 정적 웹사이트 호스팅 설정 이렇게 하면 됩니다
S3 버킷을 만든 뒤 정적 웹사이트 호스팅을 활성화하고, 공개 엑세스 권한을 올바르게 줘야 해요. 직접 콘솔과 CLI 방법을 소개할게요.
# AWS CLI로 버킷 생성 예시
aws s3api create-bucket --bucket my-static-site-bucket --region ap-northeast-2 --create-bucket-configuration LocationConstraint=ap-northeast-2
# 정적 웹사이트 호스팅 설정
aws s3 website s3://my-static-site-bucket/ --index-document index.html --error-document error.html
# 버킷 정책 예시 (홈페이지 파일들을 공개 읽기 가능하게)
aws s3api put-bucket-policy --bucket my-static-site-bucket --policy '{
\"Version\": \"2012-10-17\",
\"Statement\": [
{
\"Sid\": \"PublicReadGetObject\",
\"Effect\": \"Allow\",
\"Principal\": \"*\",
\"Action\": \"s3:GetObject\",
\"Resource\": \"arn:aws:s3:::my-static-site-bucket/*\"
}
]
}'
# 정적 파일 업로드
aws s3 cp ./website/ s3://my-static-site-bucket/ --recursive
이렇게 하면 S3 자체의 웹사이트 엔드포인트(http://my-static-site-bucket.s3-website.ap-northeast-2.amazonaws.com)로 접속해 정적 사이트가 보여야 합니다.
CloudFront 연결할 때 여기서 많이 틀립니다
그런데 여기서 막힌 게, '403 Forbidden' 에러였어요. CloudFront를 쓴다고 해서 그냥 S3 웹사이트 URL을 원본으로 넣으면 안 되거든요. 여기에 S3 웹사이트 엔드포인트 vs S3 REST API 엔드포인트 차이가 큰 영향을 주더라고요.
CloudFront 배포를 만들 때 원본 도메인을 REST API Endpoint 형태(my-static-site-bucket.s3.ap-northeast-2.amazonaws.com)로 설정하고, 오리진 액세스 아이덴티티(OAI)를 통해 버킷 접근 권한을 주는 게 핵심이에요.
# CloudFront 오리진 액세스 아이덴티티 생성\naws cloudfront create-cloud-front-origin-access-identity --cloud-front-origin-access-identity-config CallerReference=$(date +%s),Comment=OAI-for-my-static-site\n\n# 생성 후 OAI ID, CanonicalUser 값을 복사\n\n# S3 버킷 정책에 OAI 권한 추가 (예시)\n{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"GrantCloudFrontAccess\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"CanonicalUser\": \"OAI-CanonicalUser-값\"\n },\n \"Action\": \"s3:GetObject\",\n \"Resource\": \"arn:aws:s3:::my-static-site-bucket/*\"\n }\n ]\n}\n
OAI를 쓰면 버킷은 공개되지 않고 CloudFront만 버킷 콘텐츠를 읽게 만드니까 보안도 훨씬 좋아집니다.
CloudFront 배포 생성 시 주의해야 할 설정들
배포 만들 때 다음 부분도 신경써야 합니다.
- 원본 도메인은 S3 REST API 도메인 입력
- 오리진 경로는 기본값 (보통 비워둠)
- 오리진 액세스 아이덴티티(OAI)를 생성하고 연결
- Viewer Protocol Policy를 HTTP→HTTPS 리다이렉트 또는 HTTPS 전용으로 설정
- 기본 캐시 동작에서 쿼리 스트링은 필요하면 허용
아래는 AWS CLI로 CloudFront 배포 만들기 간단 예시입니다.
{\n \"CallerReference\": \"$(date +%s)\",\n \"Origins\": {\n \"Quantity\": 1,\n \"Items\": [\n {\n \"Id\": \"S3-my-static-site-bucket\",\n \"DomainName\": \"my-static-site-bucket.s3.ap-northeast-2.amazonaws.com\",\n \"S3OriginConfig\": {\n \"OriginAccessIdentity\": \"origin-access-identity/cloudfront/EXAMPLEOAI1234\"\n }\n }\n ]\n },\n \"DefaultCacheBehavior\": {\n \"TargetOriginId\": \"S3-my-static-site-bucket\",\n \"ViewerProtocolPolicy\": \"redirect-to-https\",\n \"TrustedSigners\": {\n \"Enabled\": false,\n \"Quantity\": 0\n },\n \"ForwardedValues\": {\n \"QueryString\": false,\n \"Cookies\": { \"Forward\": \"none\" }\n },\n \"MinTTL\": 0\n },\n \"Enabled\": true\n}\n
삽질후기
처음엔 S3 웹사이트 엔드포인트를 origin domain으로 써서 403 에러 떴어요. 원본 도메인에 S3 REST API 주소를 넣지 않으면 접근 권한 문제가 발생하는 게 컸죠.
또한, OAI를 생성했지만 버킷 정책에 오리진 액세스 아이덴티티의 CanonicalUser 값을 제대로 등록하지 않아 계속 권한 부족 메시지가 났어요. 이걸 찾느라 정책 JSON을 계속 수정했었습니다.
AccessDenied: Access Denied\nRequestId: XXXXXXXX\nHostId: YYYYYYYYYY\n\n# 버킷 정책에 OAI CanonicalUser 값 누락 시 발생\n
결국 OAI를 생성 후 콘솔에서 CanonicalUser ID를 복사해서 정책에 추가했더니 정상 작동했죠.
심화: 캐시 무효화와 HTTPS 설정 팁
CloudFront는 캐시가 강력해서, S3에 파일 업데이트해도 바로 안 보일 때가 많아요. 이럴 땐 캐시 무효화를 수동으로 해줘야 해요.
CLI로 무효화 요청하는 예시입니다.
aws cloudfront create-invalidation --distribution-id EXAMPLDISTRIBUTIONID --paths \"/*\"\n
그리고 HTTPS를 쓰려면 ACM에서 SSL 인증서를 발급받아 CloudFront 배포에 연결하는 게 좋아요. 이걸 안 하면 HTTPS 접속이 차단되거나 경고가 뜰 수 있습니다.
QNA
Q. S3 웹사이트 엔드포인트와 REST API 엔드포인트 차이가 뭔가요?
A. S3 웹사이트 엔드포인트는 정적 웹사이트를 위한 URL이라 80/443 포트와 HTTP 기본 동작에 최적화돼 있어요. 하지만 CloudFront는 이 주소를 원본으로 쓰면 권한 문제(403)가 발생합니다. REST API 엔드포인트는 버킷 객체에 직접 접근 가능한 주소로, OAI 권한 설정 후 사용해야 해요.
Q. CloudFront 캐시 때문에 업데이트가 안 보여요, 어떻게 하나요?
A. CloudFront 관리 콘솔이나 CLI로 캐시 무효화를 수행해야 합니다. 무효화는 비용이 발생하니 꼭 필요한 파일만 경로 지정해서 지우는 게 좋아요.
AWS S3 정적 웹사이트 호스팅 CloudFront 연결 관련 정보
'Tech > AWS' 카테고리의 다른 글
| AWS EC2 프리티어 서버 처음 만들면서 겪은 삽질과 단계별 설정법 (0) | 2026.05.23 |
|---|---|
| AWS 비용 예상치 못하게 나왔을 때 원인 찾는 법, 제가 직접 겪은 사례로 풀어봤어요 (1) | 2026.05.23 |
| AWS Lambda 비용 없이 사용하는 방법, 직접 세팅하며 겪은 삽질과 해결 (0) | 2026.05.17 |
| AWS RDS와 EC2 MySQL, 직접 써보니 어떤 경우에 좋은지 알겠더라고요 (0) | 2026.05.11 |
| AWS re:Invent 2025 총정리: Nova 2, Bedrock, Aurora DSQL로 보는 클라우드·AI 미래 (0) | 2025.12.14 |
