단일 Cloudfront를 사용하여 여러 오리진 (S3, ELB, EC2 등)에서 컨텐츠를 배포할 수 있다.
Cloudfront에서의 default 오리진은 S3이며 이외의 오리진(ELB,EC2..)은 사용자 지정 오리진으로 분류되고 이러한 사용자 지정 오리진은 동적 컨텐츠 전송이 필요할 때 사용된다.
가령, 정적 콘텐츠는 S3에서 제공하고 동적 콘텐츠를 제공하는 웹 사이트는 로드밸런서를 통해 제공하는 것이다.
(아래와 같이 *.png 에 대한 컨텐츠 요청은 S3 버킷으로, 그 외의 요청은 ELB를 거쳐 서비스를 구동중인 EC2 서버로 요청하게 된다.)
ACM, Route53, ALB, EC2, S3이 모두 생성되어 있다는 가정하에 콘솔에서 S3와 ELB를 Cloudfront에 연동하는 방법을 살펴보도록 하자. 개략적인 순서와 설정은 아래와 같다.
(1) Origin 설정 : S3 버킷에 대한 오리진 하나와 ELB에 대한 오리진 하나를 생성 (2개의 origin)
(1-2) S3에 대한 OAI 설정 : Cloudfront를 통한 요청만 허용하도록 OAI 설정 (S3 Origin 설정)
(2) Behavior 설정 : 각 오리진에 대한 경로 패턴을 지정하는 동작을 생성 (2개의 behavior)
[테스트에 사용할 S3 Origin]
[테스트에 사용할 ELB Origin]
S3 버킷에 대한 Origin 한 개, EC2를 타겟으로 하고 있는 ALB에 대한 Origin 한 개를 생성해준다.
먼저, 커스텀 오리진(ELB)에 대한 배포를 생성해주자.
Origin domain으로 사용할 대상, 여기서는 목록에 표시되는 내 alb를 선택한다.우선, 나는 HTTP 요청을 HTTPS로 redirect 할 것이므로 아래 항목만 변경해주고 나머지 옵션은 기본값 그대로 생성한다.
필요에 따라 아래에서 추가로 edit을 통해 설정해줄 것이다.
옼키. origin, behavior 모두 잘 생성되었다.
자 이제 S3 origin을 추가해주자.
Origin domain으로 내 s3 bucket을 선택해주면 그 아래 Name 항목은 자동으로 기입된다.
S3 버킷의 보안을 위해 외부 접근은 차단하고 Cloudfront를 통해서 콘텐츠를 Private하게 구성하고 싶다면 S3에서 퍼블릭 액세스 차단 후에 Cloudfront의 Distribution에서 OAI(Origin Access Identity) 기능을 설정하는 것이 좋다.
이 기능은 S3 버킷 및 콘텐츠에 대한 액세스를 CloudFront와 CloudFront가 실행하는 작업으로 제한한다.
즉, S3로의 직접적인 요청은 차단되고 Cloudfront를 통한 요청만 허용한다.
따라서, 여기서는 OAI를 설정해줄 것이다.
OAI 설정을 위해서는 Cloudfront에서 OAI를 생성하고 S3에서 OAI에 대한 버킷 정책을 생성해주는 작업이 필요하다.
(1) Cloudfront 설정
이어서 'Yes use OAI' 옵션을 선택해준 후, 'Create new OAI'를 선택하면 새로이 생성된 OAI가 선택된다.
OAI를 S3 버킷에도 적용시켜주기 위해 bucket policy 가 필요한데 여기서는 Yes, update the bucket policy를 선택하여 자동으로 적용되도록 한다.
이외의 나머지 설정은 기본값으로 생성한다.
S3 및 ELB에 대한 origin이 모두 잘 생성되었다.
(2) S3 설정
위 Bucket Policy 설정에서 Yes, update the bucket policy를 선택하면 S3 확인 시 아래와 같은 정책이 자동으로 추가된 것을 볼 수 있을 것이다.
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EAF5XXXXXXXXX"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::AWSDOC-EXAMPLE-BUCKET/*"
}
하지만 Bucket Policy 설정에서 No, I will update the bucket policy를 선택했다면 S3 정책에서 아래 내용을 수정하여 추가해주면 된다.
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity [CloudFront에서 만들었던 OAI ID]"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::[현재 접속한 s3 bucket명]/*"
}
]
}
이 때, 내 S3 버킷은 퍼블릭 액세스가 차단된 Private 상태이다.
앞서 CF 생성 시 S3에 대한 오리진 및 behavior를 설정해주었기 때문에 S3에 대한 behavior만 추가해주면 된다.
참고로, Cloudfront는 Behavior 경로를 사용하여 요청을 올바른 오리진으로 전송한다.
즉, Viewer의 요청에 대한 처리를 어떻게 할 것인지에 대한 설정이므로, Behavior가 없으면 정상적으로 동작하지 않는다.
Create behavior를 선택한다.
입력이 완료되면 Create behavior를 클릭하여 생성해준다.
아래와 같이 두 개의 behavior가 생성되었다.
client 요청에 대해 CF는 precedence가 0인 path pattern을 먼저 고려한 후, 부합하는 경우 s3에서 처리하고 해당 path pattern에 부합하지 않으면 alb에서 처리하도록 한다.
CF 도메인/s3.png로 접근시 화면
CF 도메인으로 접근 시 화면 개발자 도구를 살펴보면 x-cache에 'Hit from cloudfront'로 표시되는 것을 알 수 있는데 이는 Cloudfront를 통해 요청이 전달된 것임을 나타낸다.만일 해당 부분이 'Miss from cloudfront'로 표시된다면 CF를 통해서 데이터를 가져온게 아닌,
오리진에서 직접 데이터를 가져왔다고 보면 된다.
앞서 S3 버킷으로의 직접 요청은 제한하고 CF를 통해서만 요청할 수 있도록 OAI를 설정해주었기 때문에
S3 버킷의 객체 URL로 직접 접속하면 아래와 같이 AccessDenied 에러가 발생한다.
Cloudfront에 대해 추가로 알아야 할 것들이 정말 많지만 천천히 정리해보도록 하겠다.