AWS

[AWS] S3 + CloudFront + Route53으로 정적 파일 HTTPS 배포하기

sian han 2025. 4. 21. 18:39
사용자 ─ HTTPS 접속 ─▶ CloudFront (캐싱 및 요청 처리)
                          │
                       Route 53 (도메인 연결)
                          │
                       S3 (정적 파일 호스팅)

 

위 구조와 같이 개인 포트폴리오 사이트를 구축한 과정을 작성한다. 

 

포트폴리오는 정적파일로 구성되어 있어 S3에 업로드하여 호스팅 한다. 

CloudFront 를 앞에 붙여서 매번 S3 로 직접 접속하지 않고 CloudFront 가 캐싱하고 있는 컨텐츠를 제공하도록 설정했다.

(S3에 대한 요청이 줄어들어 트래픽 비용을 절감할 수 있다)


목차

1. S3에 정적 파일 업로드

2. Route53에 도메인 등록 

3. CloudFront 배포 설정

4. 커스텀 도메인 연결

5. HTTP 요청을 HTTPS 로 리다이렉트 (CloudFront Function 사용)


1. S3에 정적 파일업로드

  • S3에 버킷을 생성한 후 정적파일을 업로드 한다. 
  • 이때 초기 정책 설정은 아래와 같이 한다. 
  • 버킷 > 버킷 클릭 > 권한 > 버킷 정책 편집
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadForStaticWebsite",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::{name}/*"
    }
  ]
}
  • 버킷 > 속성 > Amazon 리소스 이름(ARN) 을 통해 브라우저에 접속하면 배포된 정적파일을 확인할 수 있다. 

 

2. CloudFront 배포 설정

  • CloudFront > 배포 > 배포 설정
Your account must be verified before you can add new CloudFront resources. 
To verify your account, please contact AWS Support (https://console.aws.amazon.com/support/home#/) 
and include this error message

 

  • 배포설정 버튼을 눌렀는데 위와 같은 에러 메세지가 뜸
  • 에러 메시지는 AWS 계정이 아직 완전히 활성화(verified) 되지 않았기 때문에 CloudFront 리소스를 생성할 수 없다는 의미이다.

 

✅ 해결방법

  • AWS 결제 수단 확인 > AWS Support에 문의
  • 나의 경우 등록해둔 카드의 유효기간이 만료되어 결제가 정상적으로 처리되지 않았다.
  • 결제가 가능한 새로운 카드를 등록하고 밀린 결제를 처리한 후 AWS Support에 문의했다. 

문의는 AWS Support Center 에서 가능하다. 

  • AWS Support Center > 사례생성

 

 

  • 계정 및 결제 선택
  • 서비스 : Account
  • 범주 : Change Account Details
  • 심각도 : 일반질문
  • 설명에 아래처럼 작성

 

Hello, I am trying to create a CloudFront distribution for static website hosting via S3. 
However, I received the following error: 
"Your account must be verified before you can add new CloudFront resources."

Please help verify my account so I can use CloudFront.

Thank you.

 

 

1시간 30분 만에 계정이 verify 되었다.

 

계정이 활성화 된 후에는 아래 절차로 CloudFront 배포를 생성한다. 

 

  • Origin domain : S3 버킷 선택
  • 원본 엑세스 : 공개
  • 원본 및 원본 그룹 : S3 선택 
  • 뷰어 프로토콜 정책 : HTTP and HTTPS > 추후 변경됨. 우선 설정
  • 허용된 HTTP 방법 : GET, HEAD

 

 

3. Route 53에 도메인 등록

도메인 등록

  • 가비아에서 구매한 2,500원 도메인을 Route 53에 등록한다. 
  • Route53 > 도메인 등록
  • 도메인을 등록하면 자동으로 SOA 와 NS 레코드가 생성됨. (NS 레코드는 나중에 사용됨
  • ACM에서 인증서 요청

 

호스팅 영역 생성

  • Route53 > 호스팅 영역 생성
  • 도메인 이름에 가비아에서 구매한 도메인을 입력하고 퍼블릭 호스팅 영역으로 생성
  • 생성과 동시에 NS 레코드 4개와 SOA 레코드가 생성됨

 

NS (Name Server) : 도메인의 관리 책임자를 알려주는 안내표지판. 커스텀 도메인을 Route53에서 관리하려면, 도메인판매처(가비아) 에게 주소 관리는 Route53에 있어요~ 라고 알려주는 역할이다.

SOA(Start of Authority) 레코드: 도메인 정보의 원본은 여기야 ! 라고 말해주는 레코드. 한 도메인에 여러 네임서버가 있을 수 있기 때문에, 누가 최종 결정권을 가지는지 명시해주는 역할

 

 

4. 커스텀 도메인 연결

가비아에서 네임서버를 Route53으로 변경

도메인이 가비아에 있으니, NS를 Route53 으로 위임해줘야 함

 

  • 1. Route53 에서 NS 레코드 확인 
  • 2. 가비아 > 내 도메인 관리 > 해당 도메인 선택 > 네임서버 관리/변경 메뉴 > 1,2,3,4 차를 Route53에서 생성된 NS 레코드로 변경해줌

 

30분이내에 네임서버가 변경됨

적용 후에는 Route 53에서 설정한 A레코드, CNAME, CloudFront 등 DNS 설정이 적용된다.

 

이제 적용된 도메인으로 접속하면 ? 

아래와 같은 메세지가 뜬 화면이 나타난다.

 

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>{RequestId}</RequestId>
<HostId>{HostId}</HostId>
</Error>

 

 

Cloudfront 에서 S3에 대한 접근권한이 없어서 발생하는 문제인 것으로 추정됨. 

 

✅ 해결

  • 버킷 정책에서 "PublicReadGetObject" 를 추가해주어 해결함
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": ""
        },
        {
            "Sid": "AllowCloudFrontServicePrincipal",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": ""
                }
            }
        }
    ]
}

 

  • 이때부터는 변경 사항이 생기면 무조건 캐시 무효화를 해줌
  • CloudFront > ID 클릭 > 무효화 > 무효화 생성 > 객체경로 /* (전체 캐시를 무효화)

 

 

5. /index.html 파일을 제공하도록 동작 추가 & HTTP 요청을 HTTPS 로 리다이렉트

기본적으로 index.html 파일이 열리도록 설정하지 않으면 도메인명/index.html로 직접 접근해야 했지만, CloudFront Function을 활용해 루트 경로(/) 접근 시 자동으로 index.html을 불러오도록 설정했다.

 

함수 작성

  • CloudFront > 함수 > 함수 생성
  • 아래 함수 작성
function handler(event) {
    var request = event.request;
    if (request.uri === "/") {
        request.uri = "/index.html";
    }
    return request;
}

 

 

함수를 생성하면 초기 상태는 '개발'이며, 실제로 사용하려면 '게시(Publish)'하여 배포 가능한 상태로 변경해야 한다.

 

 

함수 적용

  • CloudFront > 배포 > 동작 > 편집
  • 뷰어 프로토콜 정책 : Redirect HTTP to HTTPS (사용자가 HTTP 로 요청하면 자동으로 HTTPS 로 리다이렉트 된다) 

 

  • 함수 유형 : CloudFront Functions
  • 함수 ARN/이름 : 생성한 함수명 선택

 

 

도메인에 HTTPS 인증서가 설정되어 있어야 리다이렉트가 제대로 작동함 (ACM 인증서가 CloudFront에 연결되어 있어야 함)

 

정상적으로 포트폴리오 사이트에 접근할 수 있다.