🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

S3와 CloudFront로 정적 웹사이트 배포하기 - 슬라이드 1/7
A

AI Generated

2025. 12. 28. · 2 Views

S3와 CloudFront로 정적 웹사이트 배포하기

AWS S3와 CloudFront를 활용하여 정적 웹사이트를 전 세계에 빠르게 배포하는 방법을 알아봅니다. 버킷 생성부터 CDN 설정, HTTPS 적용까지 실무에서 바로 사용할 수 있는 내용을 담았습니다.


목차

  1. S3_Simple_Storage_Service_개념
  2. S3_버킷_생성_및_정적_웹_호스팅_설정
  3. CloudFront_CDN의_동작_원리
  4. CloudFront_배포_생성_및_S3_연결
  5. 캐싱_정책과_TTL_설정
  6. 커스텀_도메인_및_HTTPS_적용

1. S3 Simple Storage Service 개념

어느 날 김개발 씨는 회사에서 만든 랜딩 페이지를 인터넷에 공개해야 하는 임무를 받았습니다. HTML, CSS, JavaScript 파일 몇 개뿐인데 서버를 따로 구축해야 할까요?

선배 박시니어 씨가 웃으며 말했습니다. "S3면 충분해요."

**S3(Simple Storage Service)**는 AWS에서 제공하는 객체 스토리지 서비스입니다. 마치 인터넷에 있는 거대한 USB 드라이브와 같습니다.

파일을 업로드하고, 필요할 때 언제든 다운로드하거나 웹에서 직접 접근할 수 있습니다. 정적 웹사이트 호스팅 기능을 켜면 별도의 웹 서버 없이도 웹사이트를 운영할 수 있습니다.

다음 코드를 살펴봅시다.

// AWS SDK를 사용한 S3 파일 업로드 예제
const AWS = require('aws-sdk');

const s3 = new AWS.S3({
  region: 'ap-northeast-2'  // 서울 리전
});

// HTML 파일을 S3 버킷에 업로드
const uploadParams = {
  Bucket: 'my-website-bucket',
  Key: 'index.html',
  Body: '<html><body><h1>Hello World</h1></body></html>',
  ContentType: 'text/html'
};

s3.upload(uploadParams).promise()
  .then(data => console.log('업로드 완료:', data.Location));

김개발 씨는 입사 6개월 차 주니어 개발자입니다. 이번 주 미션은 회사의 새 랜딩 페이지를 인터넷에 공개하는 것이었습니다.

index.html 파일 하나와 CSS, 이미지 몇 개가 전부인 간단한 페이지였습니다. "이거 서버를 새로 세팅해야 하나요?" 김개발 씨가 걱정스럽게 물었습니다.

박시니어 씨가 고개를 저으며 대답했습니다. "정적 파일만 서빙하면 되니까 S3로 충분해요.

서버 관리할 필요도 없고요." 그렇다면 S3란 정확히 무엇일까요? 쉽게 비유하자면, S3는 인터넷에 연결된 무한한 크기의 창고입니다.

여러분이 짐을 맡기면 창고지기가 알아서 보관해주고, 필요할 때 언제든 꺼내볼 수 있습니다. 심지어 창고 문을 열어두면 다른 사람들도 여러분의 짐을 구경할 수 있습니다.

웹사이트 파일을 올려두고 문을 열어두면, 바로 그것이 웹 호스팅이 되는 것입니다. S3가 없던 시절에는 어땠을까요?

개발자들은 정적 파일 몇 개를 서빙하기 위해서도 EC2 인스턴스를 띄우고, Nginx나 Apache를 설치하고, 보안 설정을 하고, 서버 상태를 모니터링해야 했습니다. 단순한 HTML 페이지 하나를 공개하는 데 며칠이 걸리기도 했습니다.

서버가 죽으면 새벽에 호출을 받는 일도 비일비재했습니다. 바로 이런 번거로움을 해결하기 위해 S3의 정적 웹 호스팅 기능이 등장했습니다.

S3를 사용하면 파일을 업로드하는 것만으로 웹사이트가 완성됩니다. AWS가 인프라를 알아서 관리해주므로 서버 다운 걱정도 없습니다.

트래픽이 갑자기 늘어나도 자동으로 확장됩니다. 무엇보다 사용한 만큼만 비용을 내면 됩니다.

위의 코드를 살펴보겠습니다. 먼저 AWS SDK를 불러와서 S3 클라이언트를 생성합니다.

region은 데이터가 저장될 물리적 위치를 의미하며, 서울은 ap-northeast-2입니다. 그 다음 upload 메서드로 파일을 버킷에 업로드합니다.

Bucket은 파일을 담을 폴더 이름이고, Key는 파일 이름입니다. 실제 현업에서는 어떻게 활용할까요?

마케팅 팀에서 급하게 이벤트 페이지를 올려달라고 요청할 때, S3를 사용하면 10분 안에 배포가 가능합니다. React나 Vue로 만든 SPA(Single Page Application)도 빌드 결과물을 S3에 올리기만 하면 됩니다.

많은 스타트업에서 이 방식으로 웹사이트를 운영하고 있습니다. 하지만 주의할 점도 있습니다.

S3 버킷 이름은 전 세계적으로 유일해야 합니다. my-website 같은 평범한 이름은 이미 누군가 사용하고 있을 가능성이 높습니다.

또한 버킷을 퍼블릭으로 열면 누구나 접근할 수 있으므로, 민감한 파일은 절대 올리면 안 됩니다. 김개발 씨는 박시니어 씨의 설명을 듣고 눈이 반짝였습니다.

"서버 관리 없이 웹사이트를 운영할 수 있다니, 정말 편리하네요!" 이제 S3가 무엇인지 이해했으니, 다음 단계로 실제 버킷을 만들어보겠습니다.

실전 팁

💡 - 버킷 이름은 회사명이나 프로젝트명을 조합하여 유일하게 만드세요

  • 비용 절감을 위해 불필요한 파일은 주기적으로 정리하세요
  • S3 버전 관리를 켜두면 실수로 파일을 삭제해도 복구할 수 있습니다

2. S3 버킷 생성 및 정적 웹 호스팅 설정

김개발 씨가 AWS 콘솔에 로그인했습니다. S3가 좋다는 건 알겠는데, 막상 설정하려니 옵션이 너무 많습니다.

"버킷 정책? ACL?

이게 다 뭐죠?" 박시니어 씨가 옆에 앉아 하나씩 짚어주기 시작했습니다.

S3 버킷은 파일을 담는 최상위 컨테이너입니다. 마치 컴퓨터의 드라이브와 비슷합니다.

버킷을 만들고, 정적 웹 호스팅을 활성화하고, 적절한 권한을 설정하면 웹사이트가 완성됩니다. 버킷 정책을 통해 누가 어떤 파일에 접근할 수 있는지 세밀하게 제어할 수 있습니다.

다음 코드를 살펴봅시다.

// AWS CLI로 S3 정적 웹 호스팅 설정하기
// 1. 버킷 생성
aws s3 mb s3://my-static-website-2024 --region ap-northeast-2

// 2. 정적 웹 호스팅 활성화
aws s3 website s3://my-static-website-2024 \
  --index-document index.html \
  --error-document error.html

// 3. 버킷 정책 설정 (bucket-policy.json)
{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "PublicReadGetObject",
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::my-static-website-2024/*"
  }]
}

김개발 씨가 AWS 콘솔의 S3 서비스 페이지를 열었습니다. 주황색 "버킷 만들기" 버튼이 눈에 들어왔습니다.

클릭하자 수많은 옵션이 펼쳐졌습니다. 버킷 이름, 리전, 퍼블릭 액세스 차단, 버전 관리...

뭘 어떻게 설정해야 할까요? 박시니어 씨가 차근차근 설명을 시작했습니다.

"버킷 이름부터 정하죠. 전 세계에서 유일해야 하니까, 회사명과 날짜를 조합하면 좋아요." 버킷 이름은 S3에서 가장 중요한 식별자입니다.

한번 정하면 바꿀 수 없고, 삭제 후 다시 만들어야 합니다. 소문자, 숫자, 하이픈만 사용할 수 있고, 3자에서 63자 사이여야 합니다.

mycompany-website-2024 같은 형식을 추천합니다. 다음은 리전 선택입니다.

리전은 데이터가 물리적으로 저장되는 위치입니다. 한국 사용자가 주 타깃이라면 서울 리전(ap-northeast-2)을 선택하세요.

가까울수록 응답 속도가 빠릅니다. 여기서 많은 초보자가 헷갈리는 부분이 있습니다.

퍼블릭 액세스 차단 설정입니다. 기본적으로 AWS는 모든 퍼블릭 액세스를 차단합니다.

보안을 위한 좋은 기본값이지만, 정적 웹사이트를 호스팅하려면 일부를 열어야 합니다. "모든 퍼블릭 액세스 차단" 체크박스를 해제하고, 경고 메시지에 동의해야 합니다.

버킷을 만들었으면 이제 정적 웹 호스팅을 활성화할 차례입니다. 버킷 속성 탭에서 "정적 웹 사이트 호스팅"을 찾아 활성화합니다.

인덱스 문서는 index.html로, 오류 문서는 error.html로 설정하세요. 이렇게 하면 S3가 웹 서버처럼 동작합니다.

누군가 버킷 URL에 접속하면 index.html을 보여주고, 없는 페이지를 요청하면 error.html을 보여줍니다. 마지막으로 버킷 정책을 설정해야 합니다.

버킷 정책은 JSON 형식으로 작성합니다. 위 코드의 정책은 "모든 사람(Principal: *)이 이 버킷의 모든 객체(Resource: .../**)를 읽을 수 있다(Action: s3:GetObject)"는 의미입니다.

이 정책을 적용하면 드디어 웹사이트가 외부에 공개됩니다. 설정이 완료되면 S3가 버킷 웹사이트 엔드포인트를 제공합니다.

http://my-static-website-2024.s3-website.ap-northeast-2.amazonaws.com 같은 형식입니다. 이 URL로 접속하면 여러분의 웹사이트가 보입니다.

김개발 씨가 URL을 브라우저에 입력하자 "Hello World"가 화면에 나타났습니다. "와, 정말 되네요!" 하지만 박시니어 씨가 고개를 저었습니다.

"아직 끝이 아니에요. 이 URL은 너무 길고, HTTPS도 안 되잖아요.

CloudFront를 연결해야 해요."

실전 팁

💡 - 버킷 이름에 점(.)을 사용하면 SSL 인증서 문제가 생길 수 있으니 피하세요

  • 실수로 민감한 파일을 업로드하지 않도록 버킷 정책을 신중하게 설정하세요
  • AWS CLI를 사용하면 콘솔보다 빠르게 설정할 수 있습니다

3. CloudFront CDN의 동작 원리

김개발 씨가 랜딩 페이지를 미국에 있는 친구에게 보여줬습니다. 친구가 말했습니다.

"로딩이 좀 느린데?" 서울 리전에 있는 S3 버킷까지 태평양을 건너 요청이 오가니 당연한 일이었습니다. 이 문제를 어떻게 해결할 수 있을까요?

CloudFront는 AWS의 CDN(Content Delivery Network) 서비스입니다. 전 세계 수백 개의 엣지 로케이션에 콘텐츠를 캐싱하여 사용자와 가까운 곳에서 빠르게 전달합니다.

마치 전국에 편의점을 두고 상품을 미리 배치해두는 것과 같습니다. 고객이 멀리 있는 본사 창고까지 가지 않아도 가까운 편의점에서 바로 물건을 받을 수 있습니다.

다음 코드를 살펴봅시다.

// CloudFront 배포 생성 (AWS SDK)
const cloudfront = new AWS.CloudFront();

const distributionConfig = {
  CallerReference: Date.now().toString(),
  Origins: {
    Quantity: 1,
    Items: [{
      Id: 'S3-my-website',
      DomainName: 'my-website.s3.amazonaws.com',
      S3OriginConfig: {
        OriginAccessIdentity: ''
      }
    }]
  },
  DefaultCacheBehavior: {
    TargetOriginId: 'S3-my-website',
    ViewerProtocolPolicy: 'redirect-to-https',
    // 캐시 정책 설정
    CachePolicyId: '658327ea-f89d-4fab-a63d-7e88639e58f6'
  },
  Enabled: true
};

미국에 있는 친구가 서울 S3 버킷에 접속하면 무슨 일이 벌어질까요? 요청이 태평양 해저 케이블을 타고 서울까지 왔다가, 응답이 다시 미국으로 돌아갑니다.

왕복 거리만 수만 킬로미터입니다. 빛의 속도로 이동해도 지연이 발생할 수밖에 없습니다.

이것이 바로 레이턴시(지연 시간) 문제입니다. 박시니어 씨가 화이트보드에 그림을 그리며 설명했습니다.

"CDN이 이 문제를 해결해줘요. 전 세계 곳곳에 작은 창고를 두는 거예요." **CDN(Content Delivery Network)**은 콘텐츠 전송 네트워크입니다.

원본 서버의 콘텐츠를 전 세계 여러 지점에 복제해두고, 사용자가 요청하면 가장 가까운 지점에서 응답합니다. CloudFront는 AWS의 CDN 서비스입니다.

현재 전 세계 40개 이상 국가에 400개 이상의 엣지 로케이션을 운영하고 있습니다. 한국에도 서울에 여러 개의 엣지 로케이션이 있습니다.

작동 원리를 조금 더 자세히 살펴볼까요? 첫 번째 사용자가 미국에서 웹사이트에 접속합니다.

CloudFront는 먼저 미국 엣지 로케이션의 캐시를 확인합니다. 아직 캐시가 없으므로 원본 S3 버킷에서 파일을 가져옵니다.

이것을 **캐시 미스(Cache Miss)**라고 합니다. 파일을 가져온 CloudFront는 두 가지 일을 합니다.

사용자에게 파일을 전달하고, 동시에 미국 엣지 로케이션에 파일을 저장합니다. 두 번째 사용자가 같은 지역에서 접속하면?

이번에는 미국 엣지 로케이션에 캐시가 있습니다. 서울까지 갈 필요 없이 바로 응답합니다.

이것이 **캐시 히트(Cache Hit)**입니다. 응답 시간이 수백 밀리초에서 수십 밀리초로 줄어듭니다.

CloudFront를 사용하면 또 다른 이점도 있습니다. 첫째, HTTPS를 무료로 사용할 수 있습니다.

S3 정적 웹 호스팅은 HTTP만 지원하지만, CloudFront는 AWS 인증서를 통해 HTTPS를 제공합니다. 둘째, DDoS 방어 기능이 기본 포함되어 있습니다.

AWS Shield Standard가 자동으로 적용됩니다. 셋째, 커스텀 도메인을 연결할 수 있습니다.

위 코드에서 주목할 부분은 ViewerProtocolPolicy입니다. redirect-to-https로 설정하면 HTTP 요청을 자동으로 HTTPS로 리다이렉트합니다.

보안과 SEO 모두에 좋습니다. 김개발 씨가 이해했다는 듯 고개를 끄덕였습니다.

"그러니까 CloudFront가 전 세계에 있는 편의점 같은 거네요. 고객이 멀리 있는 본사 창고까지 안 가도 되고요." 박시니어 씨가 웃으며 대답했습니다.

"정확해요. 이제 직접 설정해볼까요?"

실전 팁

💡 - 캐시 히트율을 높이면 S3 요청 비용도 줄어듭니다

  • CloudFront는 동적 콘텐츠도 가속할 수 있습니다
  • 엣지 로케이션 위치는 AWS 공식 문서에서 확인할 수 있습니다

4. CloudFront 배포 생성 및 S3 연결

이론은 충분히 배웠습니다. 이제 실제로 CloudFront 배포를 만들어 S3 버킷과 연결할 시간입니다.

김개발 씨가 AWS 콘솔에서 CloudFront 서비스를 열었습니다. "배포 생성" 버튼이 보입니다.

어떤 옵션을 선택해야 할까요?

**CloudFront 배포(Distribution)**는 CDN 설정의 단위입니다. 하나의 배포에 원본(Origin), 캐시 동작(Cache Behavior), 도메인 설정 등이 포함됩니다.

S3 버킷을 원본으로 지정하고, **OAC(Origin Access Control)**를 설정하면 CloudFront를 통해서만 S3에 접근하도록 보안을 강화할 수 있습니다.

다음 코드를 살펴봅시다.

// CloudFront 배포 설정 (Terraform 예제)
resource "aws_cloudfront_distribution" "website" {
  origin {
    domain_name = aws_s3_bucket.website.bucket_regional_domain_name
    origin_id   = "S3-Website"

    // OAC로 S3 접근 제어
    origin_access_control_id = aws_cloudfront_origin_access_control.oac.id
  }

  enabled             = true
  default_root_object = "index.html"

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "S3-Website"

    viewer_protocol_policy = "redirect-to-https"
    compress               = true  // Gzip 압축 활성화
  }

  restrictions {
    geo_restriction { restriction_type = "none" }
  }
}

김개발 씨가 CloudFront 콘솔에서 "배포 생성"을 클릭했습니다. 첫 번째로 보이는 것은 원본(Origin) 설정입니다.

원본은 CloudFront가 콘텐츠를 가져올 곳입니다. 원본 도메인 입력란을 클릭하면 자동으로 S3 버킷 목록이 나타납니다.

방금 만든 버킷을 선택하세요. 중요한 것은 버킷의 리전 도메인 이름을 사용해야 한다는 점입니다.

정적 웹 호스팅 엔드포인트가 아닙니다. 다음으로 원본 액세스 설정이 나옵니다.

여기서 세 가지 옵션이 있습니다. 퍼블릭은 S3 버킷을 완전히 공개하는 것입니다.

앞서 설정한 버킷 정책 방식이죠. 하지만 보안 관점에서 권장하지 않습니다.

누구나 S3 URL로 직접 접근할 수 있기 때문입니다. **OAC(Origin Access Control)**는 현재 AWS가 권장하는 방식입니다.

CloudFront만 S3 버킷에 접근할 수 있도록 제한합니다. 사용자는 반드시 CloudFront URL을 통해야만 콘텐츠를 볼 수 있습니다.

레거시 OAI(Origin Access Identity)는 예전 방식입니다. 새 프로젝트에서는 OAC를 사용하세요.

OAC를 선택하면 AWS가 자동으로 필요한 버킷 정책을 생성해줍니다. "버킷 정책 업데이트"를 클릭하면 복사할 수 있는 정책이 나타납니다.

이걸 S3 버킷 정책에 붙여넣으면 됩니다. 기본 캐시 동작 섹션으로 내려갑니다.

뷰어 프로토콜 정책은 redirect-to-https를 선택하세요. HTTP로 들어오는 요청을 자동으로 HTTPS로 변환합니다.

허용된 HTTP 메서드는 정적 사이트니까 GET, HEAD면 충분합니다. POST나 PUT은 필요 없습니다.

압축은 반드시 활성화하세요. Gzip이나 Brotli로 파일을 압축해서 전송합니다.

HTML, CSS, JavaScript 파일 크기를 70% 이상 줄일 수 있습니다. 로딩 속도가 크게 향상됩니다.

기본 루트 객체에는 index.html을 입력합니다. 사용자가 도메인 루트(예: https://example.com/)에 접속했을 때 보여줄 파일입니다.

나머지 설정은 기본값으로 두어도 됩니다. "배포 생성"을 클릭하면 CloudFront가 전 세계 엣지 로케이션에 설정을 배포하기 시작합니다.

상태가 "배포 중"에서 "활성화됨"으로 바뀌기까지 보통 5-10분 정도 걸립니다. 배포가 완료되면 CloudFront가 도메인 이름을 제공합니다.

d1234abcd.cloudfront.net 같은 형식입니다. 이 URL로 접속하면 여러분의 웹사이트가 HTTPS로 서비스됩니다.

김개발 씨가 새 URL을 미국 친구에게 보냈습니다. "와, 이번엔 엄청 빠르다!" 친구의 답장에 김개발 씨가 뿌듯해했습니다.

실전 팁

💡 - OAC를 사용하면 S3 버킷을 비공개로 유지하면서도 웹사이트를 서비스할 수 있습니다

  • 배포 생성 후 설정 변경도 가능하지만, 반영에 시간이 걸립니다
  • 여러 S3 버킷을 하나의 CloudFront 배포에 연결할 수도 있습니다

5. 캐싱 정책과 TTL 설정

웹사이트가 잘 동작합니다. 그런데 김개발 씨가 CSS를 수정하고 S3에 업로드했는데, 사이트에 반영이 안 됩니다.

새로고침을 해도 옛날 스타일 그대로입니다. "캐시 때문이에요." 박시니어 씨가 말했습니다.

캐시는 양날의 검이었습니다.

**TTL(Time To Live)**은 캐시의 유효 기간입니다. CloudFront가 엣지 로케이션에 저장한 파일을 얼마나 오래 보관할지 결정합니다.

TTL이 길면 원본 요청이 줄어 비용이 절감되지만, 변경사항 반영이 느립니다. TTL이 짧으면 최신 콘텐츠를 빠르게 반영하지만, 원본 요청이 늘어납니다.

**캐시 무효화(Invalidation)**를 사용하면 TTL과 관계없이 즉시 캐시를 삭제할 수 있습니다.

다음 코드를 살펴봅시다.

// 캐시 정책 생성 및 무효화 예제
const cloudfront = new AWS.CloudFront();

// 커스텀 캐시 정책 생성
const cachePolicyConfig = {
  Name: 'StaticAssets-1Year',
  DefaultTTL: 86400,      // 1일 (기본)
  MaxTTL: 31536000,       // 1년 (최대)
  MinTTL: 0,              // 0초 (최소)
  ParametersInCacheKeyAndForwardedToOrigin: {
    CookiesConfig: { CookieBehavior: 'none' },
    HeadersConfig: { HeaderBehavior: 'none' },
    QueryStringsConfig: { QueryStringBehavior: 'none' }
  }
};

// 캐시 무효화 (배포 후 즉시 반영 필요할 때)
cloudfront.createInvalidation({
  DistributionId: 'E1234567890',
  InvalidationBatch: {
    CallerReference: Date.now().toString(),
    Paths: { Quantity: 1, Items: ['/*'] }  // 모든 파일 무효화
  }
}).promise();

김개발 씨는 당황했습니다. 분명히 CSS를 수정하고 S3에 올렸는데 왜 반영이 안 되는 걸까요?

"엣지 로케이션에 이전 버전이 캐시되어 있어서 그래요." 박시니어 씨가 설명했습니다. "CDN의 장점이자 단점이죠.

빠른 응답을 위해 파일을 저장해두는데, 그게 업데이트를 막기도 해요." **TTL(Time To Live)**은 캐시가 살아있는 시간입니다. CloudFront에서는 세 가지 TTL을 설정할 수 있습니다.

MinTTL은 최소 캐시 시간입니다. 원본이 아무리 짧은 캐시 시간을 지정해도 이 값 이하로는 내려가지 않습니다.

DefaultTTL은 원본이 캐시 헤더를 보내지 않을 때 적용되는 기본값입니다. MaxTTL은 최대 캐시 시간입니다.

원본이 아무리 긴 시간을 지정해도 이 값을 넘지 않습니다. 그렇다면 어떤 값이 적절할까요?

파일 유형에 따라 다르게 설정하는 것이 좋습니다. HTML 파일은 TTL을 짧게 설정하세요.

5분에서 1시간 정도면 적당합니다. HTML은 자주 바뀌고, 크기도 작아서 원본 요청 비용이 크지 않습니다.

CSS, JavaScript 파일은 조금 복잡합니다. 파일 내용이 바뀌면 파일 이름도 바꾸는 캐시 버스팅 전략을 사용한다면 TTL을 1년으로 설정해도 됩니다.

style.css 대신 style.abc123.css처럼 해시를 붙이는 방식입니다. Webpack이나 Vite 같은 빌드 도구가 자동으로 해줍니다.

이미지, 폰트 파일은 TTL을 길게 설정합니다. 한 번 올리면 거의 바뀌지 않으니까요.

1년으로 설정하면 캐시 히트율이 높아져 비용도 절감됩니다. 그런데 긴급하게 수정해야 할 때는 어떻게 할까요?

바로 **캐시 무효화(Invalidation)**를 사용합니다. 무효화 요청을 보내면 CloudFront가 전 세계 엣지 로케이션의 캐시를 삭제합니다.

다음 요청부터는 원본에서 새 파일을 가져옵니다. 위 코드에서 Paths: ['/*']는 모든 파일을 무효화하라는 의미입니다.

특정 파일만 무효화하려면 ['/style.css', '/app.js']처럼 경로를 지정하면 됩니다. 주의할 점이 있습니다.

무효화는 월 1,000건까지 무료이고, 그 이후는 건당 비용이 발생합니다. /* 같은 와일드카드도 1건으로 계산됩니다.

하지만 자주 사용하면 비용이 늘어나니, 가능하면 캐시 버스팅 전략을 사용하세요. 또 다른 팁이 있습니다.

S3에 파일을 업로드할 때 Cache-Control 헤더를 함께 설정할 수 있습니다. 예를 들어 Cache-Control: max-age=31536000을 설정하면 1년간 캐시하라는 의미입니다.

CloudFront는 이 헤더를 존중합니다. 김개발 씨가 무효화 요청을 보냈습니다.

잠시 후 새로고침하니 드디어 수정된 CSS가 반영되었습니다. "앞으로는 파일 이름에 해시를 붙여야겠어요." 김개발 씨가 다짐했습니다.

실전 팁

💡 - 빌드 도구의 파일 해싱 기능을 활용하면 캐시 관리가 편해집니다

  • 무효화보다 캐시 버스팅이 비용 면에서 효율적입니다
  • 개발 환경에서는 TTL을 0으로 설정하면 편리합니다

6. 커스텀 도메인 및 HTTPS 적용

d1234abcd.cloudfront.net이라는 URL은 아무도 기억하지 못합니다. 김개발 씨는 회사 도메인인 www.mycompany.com으로 접속하게 하고 싶었습니다.

그리고 브라우저 주소창에 자물쇠 아이콘도 보여야 합니다. 마지막 단계입니다.

커스텀 도메인을 CloudFront에 연결하려면 SSL/TLS 인증서가 필요합니다. AWS Certificate Manager(ACM)에서 무료로 인증서를 발급받을 수 있습니다.

단, CloudFront용 인증서는 반드시 버지니아 북부(us-east-1) 리전에서 발급받아야 합니다. 인증서를 연결하고 DNS 레코드를 설정하면 커스텀 도메인으로 HTTPS 서비스가 완성됩니다.

다음 코드를 살펴봅시다.

// Route 53 + ACM + CloudFront 설정 (Terraform)
// 1. ACM 인증서 (us-east-1 필수!)
resource "aws_acm_certificate" "cert" {
  provider          = aws.us_east_1  // 버지니아 리전
  domain_name       = "www.mycompany.com"
  validation_method = "DNS"

  subject_alternative_names = ["mycompany.com"]  // 루트 도메인도 포함
}

// 2. Route 53 DNS 레코드
resource "aws_route53_record" "www" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "www.mycompany.com"
  type    = "A"

  alias {
    name    = aws_cloudfront_distribution.website.domain_name
    zone_id = aws_cloudfront_distribution.website.hosted_zone_id
    evaluate_target_health = false
  }
}

// 3. CloudFront에 도메인과 인증서 연결
aliases = ["www.mycompany.com", "mycompany.com"]
viewer_certificate {
  acm_certificate_arn = aws_acm_certificate.cert.arn
  ssl_support_method  = "sni-only"
}

웹사이트의 마지막 퍼즐 조각입니다. 전문적인 서비스라면 고유한 도메인과 HTTPS는 필수입니다.

먼저 도메인이 필요합니다. Route 53에서 직접 구매하거나, 외부 도메인 등록 업체에서 구매할 수 있습니다.

이미 도메인이 있다면 그걸 사용하면 됩니다. 다음은 SSL/TLS 인증서입니다.

HTTPS를 위해서는 인증서가 있어야 합니다. AWS Certificate Manager(ACM)에서 무료로 발급받을 수 있습니다.

여기서 중요한 주의사항이 있습니다. CloudFront용 인증서는 반드시 버지니아 북부(us-east-1) 리전에서 발급받아야 합니다. 서울 리전에서 발급받은 인증서는 CloudFront에서 사용할 수 없습니다.

많은 초보자가 이 부분에서 막힙니다. 인증서를 발급받기 전에 꼭 리전을 확인하세요.

ACM 콘솔에서 "퍼블릭 인증서 요청"을 클릭합니다. 도메인 이름을 입력합니다.

www.mycompany.com과 mycompany.com 둘 다 등록하려면 **주체 대체 이름(SAN)**에 추가하세요. 검증 방법은 DNS 검증을 추천합니다.

ACM이 특정 DNS 레코드를 추가하라고 알려줍니다. Route 53을 사용한다면 "Route 53에서 레코드 생성" 버튼 하나로 자동 설정됩니다.

다른 DNS 서비스를 사용한다면 해당 서비스에서 직접 CNAME 레코드를 추가해야 합니다. 검증이 완료되면 인증서 상태가 "발급됨"으로 바뀝니다.

보통 몇 분에서 몇 시간이 걸립니다. 이제 CloudFront 배포 설정을 수정합니다.

대체 도메인 이름(CNAMEs) 필드에 www.mycompany.com을 입력합니다. 루트 도메인도 사용하려면 mycompany.com도 추가하세요.

사용자 정의 SSL 인증서에서 방금 발급받은 인증서를 선택합니다. 마지막으로 DNS 레코드를 설정합니다.

Route 53에서 A 레코드를 생성합니다. 레코드 유형은 "A - IPv4 주소"를 선택하고, 별칭을 활성화합니다.

별칭 대상에서 CloudFront 배포를 선택하면 됩니다. www 서브도메인과 루트 도메인 각각에 대해 레코드를 만드세요.

DNS 변경사항이 전파되는 데 시간이 걸릴 수 있습니다. 보통 몇 분이면 되지만, 최대 48시간까지 걸리기도 합니다.

모든 설정이 완료되면 브라우저에서 https://www.mycompany.com을 입력해보세요. 자물쇠 아이콘과 함께 여러분의 웹사이트가 나타날 것입니다.

김개발 씨가 마침내 URL을 팀 슬랙 채널에 공유했습니다. "드디어 완성했습니다!" 박시니어 씨가 엄지를 들어 보였습니다.

"축하해요. 이제 전 세계 어디서든 빠르고 안전하게 접속할 수 있어요." 정적 웹사이트를 S3와 CloudFront로 배포하는 전체 과정을 마쳤습니다.

이 아키텍처는 확장성이 뛰어나고, 비용 효율적이며, 관리 부담도 적습니다. 많은 기업에서 사용하는 검증된 방식입니다.

여러분도 직접 도전해보세요.

실전 팁

💡 - 인증서 발급은 us-east-1 리전에서 해야 한다는 점을 꼭 기억하세요

  • 루트 도메인(mycompany.com)과 www 서브도메인 모두 설정하는 것이 좋습니다
  • Route 53 외의 DNS 서비스를 사용해도 CloudFront 연결이 가능합니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#AWS#S3#CloudFront#CDN#StaticWebsite#HTTPS

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스

DynamoDB NoSQL로 확장 가능한 데이터 저장

AWS DynamoDB의 핵심 개념부터 실전 활용까지, 초급 개발자도 쉽게 이해할 수 있도록 설명합니다. 파티션 키 설계부터 GSI, Streams까지 단계별로 배워봅니다.

ElastiCache로 인메모리 캐싱 구현하기

AWS ElastiCache를 활용하여 애플리케이션의 성능을 획기적으로 개선하는 방법을 알아봅니다. Redis 클러스터 구성부터 실제 연동까지 실무에서 바로 적용할 수 있는 내용을 다룹니다.

VPC 엔드포인트로 AWS 서비스 프라이빗 연결

AWS 서비스에 프라이빗하게 접근하는 VPC 엔드포인트의 개념과 설정 방법을 알아봅니다. 게이트웨이 엔드포인트와 인터페이스 엔드포인트의 차이점, S3 연결 설정, 그리고 비용 절감 효과까지 실무 중심으로 설명합니다.

RDS 읽기 전용 복제본으로 읽기 성능 향상 완벽 가이드

AWS RDS의 읽기 전용 복제본(Read Replica)을 활용하여 데이터베이스 읽기 성능을 향상시키는 방법을 알아봅니다. 비동기식 복제 원리부터 실제 구현, 모니터링, 그리고 장애 대응까지 실무에서 바로 적용할 수 있는 내용을 다룹니다.

RDS 다중 AZ 구성으로 장애 대비하기

AWS RDS의 다중 AZ 구성을 통해 데이터베이스 고가용성을 확보하는 방법을 알아봅니다. 동기식 복제, 자동 장애 조치, 실습 방법까지 초급자도 이해할 수 있도록 쉽게 설명합니다.