앞에서 이미 워드프레스 블로그를 구축하였는데, 굳이 S3와 CloudFront를 이용해야 하는 이유가 무엇일까요?

S3를 사용하는 이유는 블로그에 업로드하는 모든 컨텐츠를 분리 보관하여 추후 재해 복구 상황을 대비하기 위함과 동시에 정적 콘텐츠를 제공하는 것에 대한 리소스 부담을 덜어내기 위함입니다.

CloudFront를 사용하는 이유는 이러한 정적 콘텐츠를 CDN으로 서비스하여 보다 빠르게 콘텐츠를 전달하고 CFRC (CloudFront Reserved Capacity)를 이용하여 비용을 절감하기 위함입니다. 월 10TB 이상의 데이터 전송시에 할인을 받을 수 있는 별도 계약을 통해서 EC2나 S3로부터 인터넷으로의 데이터 전송 비용보다 훨씬 저렴하게 CloudFront를 통해서 데이터를 전송할 수 있습니다.

이처럼 충분한 이유가 있기 때문에 아래의 옵션에 가까운 설정을 진행하는 것은 추후 블로그의 수평 확장을 위해서 매우 유리하게 작용합니다.

S3를 이용한 정적 콘텐츠 분리

S3를 이용하는 방법은 여러 가지가 존재하지만, 가장 간단한 방법은 널리 사용되는 플러그인을 이용하는 것입니다. OpsNow 블로그에서는 WP Offload Media Lite 플러그인을 이용하여 업로드 콘텐츠를 S3에 복제합니다.

작업을 진행하기에 앞서, 워드프레스가 설치된 EC2에 IAM 롤을 할당해야 합니다. 다음과 같은 정책을 생성하고, IAM 롤을 만들어서 EC2에 해당 롤을 지정해줍니다.

 

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ObjectLevel",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::<bucket_name>/*"
},
{
"Sid": "BucketLevel",
"Effect": "Allow",
"Action": [
"s3:GetBucketPublicAccessBlock",
"s3:PutBucketPublicAccessBlock",
"s3:CreateBucket",
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::<bucket_name>"
}
] }
Code language: JSON / JSON with Comments (json)

아래는 플러그인 설정 화면입니다.

Offload media lite 설정 화면

사전에 준비된 S3 버킷 이름을 넣어주고 Block All Public Access를 Off로 설정합니다. 주의하실 점은, CloudFront를 이용한 CDN 설정을 진행할 경우에는 해당 옵션을 On으로 설정해주셔야 합니다.

단순히 S3를 이용한 콘텐츠 제공시에는 사용자가 버킷에 직접 접근하기 때문에 버킷을 퍼블릭하게 열어줘야 합니다. 하지만, CloudFront 서비스를 이용하여 콘텐츠를 제공하게 되면 해당 서비스만 접근하면 되므로 퍼블릭하게 열어줄 필요가 없습니다. 원하는 환경에 맞춰서 선택적으로 적용하시면 됩니다만, OpsNow에서는 CloudFront를 사용하므로 설정을 On으로 설정하였습니다.

기본적으로 워드프레스의 업로드 콘텐츠가 저장되는 wp-content/uploads/ 경로가 S3로 복사되도록 설정되어 있습니다. 상단의 URL 미리보기를 통해서 제공되는 콘텐츠의 URL이 어떻게 변경되는지 확인해볼 수 있습니다.

CloudFront를 이용한 CDN 설정

아래의 과정은 플러그인의 문서에서 자세히 확인할 수 있습니다. (바로가기)

먼저, AWS의 CloudFront 콘솔로 접속하여 새로운 Origin Access Identity를 생성합니다. 코멘트를 통해서 blog.opsnow.com에 대한 것임을 명시합니다.

그 다음에 Web Distribution을 생성합니다.

  • Origin Settings
    • Origin Domain Name : Bucket Endpoint
    • Restrict Bucket Access : Yes
    • Origin Access Identity : Use an Existing Identity
    • Your Identitis : blog.opsnow.com
    • Grant Read Permissions on Bucket : Yes, Update Bucket Policy
  • Distribution Settings
    • Alternate Domain Names (CNAMES) : cdn-blog.opsnow.com
    • SSL Certificate : Custom SSL Certificates (*.opsnow.com)

그 외의 모든 옵션은 기본 설정값으로 진행하였습니다. 이렇게 Distribution을 생성하고 나면 해당 Distribution에 대한 Domain Name이 생성됩니다.

  • xxxxxxxxxxxxx.cloudfront.net

이제, 도메인의 DNS에 CNAME 레코드를 생성하여 cdn-blog 서브 도메인을 위의 Domain Name으로 향하도록 설정을 해줍니다.

모든 설정이 정상적으로 완료되었다면, 사진을 업로드하고 해당 사진의 경로가 cdn-blog.opsnow.com으로 나타나는지 확인해보시기 바랍니다. 그렇다면 제대로 동작하고 있다는 뜻입니다.

수평 확장을 위한 고민

지금까지, 워드프레스 블로그를 구축하고 정적 콘텐츠에 대한 CDN 설정을 완료하였습니다. 콘텐츠 분리는 진행되었지만, 플러그인이나 테마와 같은 파일들은 결국 EC2에 존재하며, 로컬 DB를 사용하였기 때문에 수평적인 확장은 어려운 상황입니다. 그렇다면 어떤 방법들을 통해서 수평 확장을 가능하게 할 수 있을까요?

  • 로컬 DB의 Amazon RDS (Relational Database Service) 마이그레이션
  • 플러그인, 테마의 설치 경로를 탄력적인 네트워크 드라이브인 Amazon EFS (Elastic File System)로 이전
  • 워드프레스 구동을 위한 PHP의 커스텀 이미지 생성

가장 먼저, 데이터베이스를 로컬에서 Amazon RDS로 이전하여 특정 인스턴스에 의존하지 않는 데이터베이스 구축이 필요합니다. 또한, 플러그인과 테마 파일들이 특정 인스턴스에 의존하지 않도록 공통의 파일 시스템에 위치할 필요가 있는데, 여러 인스턴스에서 EFS를 통해 하나의 파일 시스템을 공유할 수 있습니다.

이렇게 되면, EC2에서는 PHP를 이용하여 워드프레스를 구동하는 부분만 남게 됩니다. 이것을 사용자 이미지로 만들고 로드밸런서의 대상 그룹에 Auto Scaling Group을 생성하거나, 도커라이즈된 이미지와 ECS (Elastic Container Service)를 통해서 워드프레스 블로그의 수평 확장을 이룰 수 있습니다.