본문 바로가기

카테고리 없음

랜딩페이지, S3로 이전

기존 랜딩페이지는 AWS EC2에서 Apache2를 통해 호스팅되고 있었다.

그러나 랜딩페이지의 동적컨텐츠가 모두 제거되어, 더 이상 호스팅을 위해 서버 자원을 사용하는 것은 낭비라 판단했다.

따라서 S3로 소스파일을 옮겨 정적 호스팅을 하고자 했다.

요구사항

  1. 이전 시, 접속이 안되는 일은 없어야 한다.
  2. Jenkins 배포자동화를 구성한다.
  3. 개발자를 위해 테스트 도메인을 하나 더 준비한다.

작업순서

  1. 테스트 도메인 S3 정적 호스팅
  2. S3 업로드 자동화
  3. 도메인을 Cloudfront에 등록
  4. Cloudflare DNS 등록

S3 정적 호스팅

고유한 이름으로 S3를 생성한다.

호스팅을 위해서 퍼블릭 액세스 차단을 해제한다.

속성에서 “정적 웹 사이트 호스팅”을 활성화 해준다. 인덱스 문서는 index.html 이다.

버킷 내 파일을 읽을 수 있는 권한을 주기위해 버킷 정책을 편집한다.

우선 모든 접근에 대해 허용해 준다.

{
  "Id": "Policy1668124825820",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1668124824658",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::landing.test.whatap.io/*",
      "Principal": "*"
    }
  ]
}

이제 S3의 정적파일들을 호스팅 할 준비가 끝났다. 엔드포인트는 속성에서 확인할 수 있다.

S3 업로드 자동화

구성된 Jenkins 환경에서 랜딩페이지 소스를 GitLab에서 받아올 수 있게 Repository URL과 Credentials를 입력한다. 필요한 경우 branch도 설정한다.

S3에 정적파일을 업데이트만 시키면되므로, aws s3 sync 명령어를 사용해 간단히 GitLab에서 받아온 소스를 S3에 업데이트할 수 있다.

소스를 GitLab으로 설정하면, Build Job을 실행하는 환경이 소스를 pull 받은 디렉토리에서 시작함을 명심한다. 따라서 ./ 이렇게 시작을 하면 소스부터 시작하는 것이다.

aws s3 sync ./landing-page/whatap/ s3://landing.test.whatap.io

젠킨스에서 Build Job이 실행되므로 Build가 끝난 후 꼭 workspace를 지워야 Jenkins disk가 꽉 차지 않는다.

실행해서 파일이 잘 올라가나 확인해보자.

Cloudfront에 등록

기본적으로 S3 정적 호스팅에 SSL/TLS 인증서를 붙일 수 없다. 따라서 https 접속은 불가능하다.

Cloudfront에 배포함으로써 인증서를 붙이고 https 통신이 가능하게 만들 수 있다.

콘솔에서 배포 생성을 한다.

원본 도메인으로 S3 버킷을 입력한다.

S3 버킷으로 직접 액세스 불가능, Cloudfront를 통해서만 액세스 가능하도록 구성한다.

인증서를 붙일 것이므로 모든 HTTP 요청은 HTTPS로 리다이렉트 하도록 설정한다.

추후 도메인 이름을 사용할 것을 넣어준다.

ACM에 등록한 인증서를 선택해주고, 지원되는 HTTP 버전도 늘려준다.

완료한 후 Cloudfront 도메인 주소로 접속한다. 아직은 손수 /ko/index.html 경로를 붙여줘야한다. 더 아름다운 방법이 있다.

Cloudfront 함수라는 기능이 있다. 동작에 붙어 작동하여 간단한 로직을 처리할 수 있다. 나는 /ko/index.html 을 입력해주지않아도 알아서 index.html 파일을 찾아가게 하고 싶었다.

function handler(event) {
    var request = event.request;
    var uri = request.uri;

    // Check whether the URI is missing a file name.
    if (uri.includes('.')) {
        
    }
    else if (uri.endsWith('/')) {
        request.uri += 'index.html';
    }

    else if (!uri.endsWith('/')){
        request.uri += '/index.html'
    }

    return request;
}

Cloudfront 함수를 만들고 다음과 같이 배포 동작에 붙일 수 있다.

Cloudflare DNS 등록

Cloudflare는 CDN 서비스로 보안과 캐싱을 해주는 서비스이다.

.whatap.io 라는 인증서를 가져와서 DNS 등록을 한다.

CNAME 형식으로 Cloudfront 주소로 리다이렉트 해준다.

이때 사용할 수 있는 CNAME은 Cloudfront에서 등록한 CNAME과 일치해야만 SSL hanshake 실패 오류가 안뜬다. (호스트 이름이 다르기 때문이다.)

Cloudflare의 Redirect Rules라는 기능을 활용해, 클라이언트의 Accept-language 헤더 값에 따라 다른 언어로 표현될 수 있게끔 구성할 것이다.

지금은 고정값을 사용하지만, 각 언어별로 페이지가 잘 적용된 경우 동일한 uri 이지만, 다른 언어로 동적 Redirect하는 것도 가능하다.

위와 같은 예시로 사용할 수 있다.

정리

클라이언트가 [landing-test.whatap.io] 로 접근을 한다면, Cloudflare로 프록싱된다. 설정된 규칙에 의해 [landing-test.whatap.io/en] 으로 리다이렉트된다.

그 후, [landing-test.whatap.io/en/index.html] 로 접근을 할 수 있어, 사용자는 정적파일을 볼 수 있게된다.