AWS Lambda 를 이용하여 CloudFront Cache 무효화 처리하기
- -
AWS Lambda 를 이용하여 CloudFront Cache 만료 처리하기
AWS S3 와 CloudFront 를 사용하여 정적 웹을 호스팅 할 수 있습니다.
정적 컨텐츠를 저장하는 스토리지로 S3 를 사용하고, CDN 서비스로는 CloudFront 를 사용하여 정적 웹 호스팅을 구성합니다. 이러한 구성은 컨텐츠 보안 유지 및 컨텐츠 배포 상향시킵니다.
위 구성에서 S3에 저장된 동일한 이름의 정적 컨텐츠가 변경될 경우 CloudFront에 저장된 Cache 를 만료시켜야 변경된 최신 컨텐츠를 사용자에게 제공할 수 있습니다.
이 글에서는 Lambda 를 사용하여 S3에 저장된 컨텐츠가 변경될 경우 CloudFront의 Cache 를 만료시키는 방법에 대해 알아봅니다.
Lambda 함수에서 사용한 runtime 은 Node.js 18 이며 18버전 부터는 AWS SDK 3버전만 지원합니다.
Architecture
CloudFront 는 Origin 으로 설정된 S3의 컨텐츠를 Cache 처리하여 사용자에게 제공합니다.
제공되는 컨텐츠에 변경(S3 에 새로운 컨텐츠로 업로드)이 생기면 CloudFront 의 캐시를 만료 후 새롭게 업로드된 컨텐츠로 Cache 처리가 필요합니다.
이 예제에서는 S3 에 객체 생성 이벤트 트리거로 CloudFront Cache 를 만료시키는 Lambda 함수를 호출하여 자동으로 사용자에게 최신의 컨텐츠를 제공하도록 구성합니다.
개발환경에 Node.js 설치
구성하려는 Lambda runtime 버전과 동일하게 Local PC 에 Node.js 18 버전을 설치합니다.
NPM 설정
개발환경에 작업 폴더 생성 후 Node Package Manager 를 설정합니다.
Node.js 용 AWS CloudFrontClinet SDK 설치
아래 링크로 이동해서 개발 환경에 맞게 CloudFrontClient를 설치합니다.
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/cloudfront/
index.js 파일 생성 및 코드 작성
아래 url 에서 CloudFrontClient - CreateInvalidationCommand Operation 의 Example Syntax 를 참고하여 index.js 파일을 생성합니다.
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/cloudfront/
아래 코드로 index.js 파일을 생성합니다.
'use strict';
const { CloudFrontClient, CreateInvalidationCommand } = require("@aws-sdk/client-cloudfront"); // CommonJS import
const client = new CloudFrontClient();
exports.handler = async (event, context, callback) => {
//요청 Parameter
let timestamp = new Date().getTime();
let input = { // CreateInvalidationRequest
DistributionId: "E2FG7I3YDTRZW0", // cf-id
InvalidationBatch: { // InvalidationBatch
Paths: {
Quantity: 1,
Items: [ // PathList
encodeURI("/img/aws.png")
]
},
CallerReference: timestamp.toString() // required
},
};
//CloudFront Invalidation 요청 생성
let command = new CreateInvalidationCommand(input);
//CloudFrontClient 요청 수행 및 결과
let response = await client.send(command);
//응답 결과 출력
console.log(JSON.stringify(response));
callback(null, `cf-invalidation`);
};
index.js 파일을 포함하여 생성한 Package 를 zip 파일로 압축합니다.
Lambda 생성 및 테스트 이벤트
Lambda 함수를 생성합니다.
생성된 람다 함수에 zip 으로 압축한 package 를 upload 합니다.
생성된 Lambda 함수에 적용된 role에 CloudFront 에 대한 CreateInvalidation Action 을 추가합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:ap-northeast-2:<your-account-id>:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-northeast-2:<your-account-id>:log-group:/aws/lambda/cf-invalidation-lmb:*"
]
},
{
"Effect": "Allow",
"Action": [
"cloudfront:CreateInvalidation"
],
"Resource": [
"<your-cf-arn>"
]
}
]
}
Lambda 테스트 이벤트를 생성합니다.
테스트 이벤트를 실행하여 작성한 코드가 정상 동작 하는지 확인합니다.
CloudFront Cache 무효화 확인
변경전 이미지를 확인합니다.
S3 에 동일한 파일명으로 새로운 컨텐츠를 업로드 합니다.
Lambda 함수를 실행합니다.
CF 무효화 요청이 처리 되었는지 확인합니다.
CloudFront Cache 무효화처리가 완료되어 새롭게 업로드한 컨텐츠가 제공되는지 확인합니다.
Lambda 함수 호출을 통해 CloudFront Cache 무효화가 정상 처리됨을 확인하였습니다.
S3 파일 업로드시 자동으로 CloudFront Cache 무효화 처리하기
이번에는 CloudFront Cache 무효화 처리를 자동화 해보겠습니다.
S3 파일 업로드 이벤트가 발생하면 Lambda 함수가 호출되어 CloudFront Cache 무효화를 처리하게 됩니다.
Lambda 함수를 아래와 같이 수정하여 배포합니다.
'use strict';
const { CloudFrontClient, CreateInvalidationCommand } = require("@aws-sdk/client-cloudfront"); // CommonJS import
const client = new CloudFrontClient();
exports.handler = async (event, context, callback) => {
//요청 Parameter
let paths =[];
event["Records"].forEach(items => {
let key = items["s3"]["object"]["key"];
if (key.endsWith("index.html")){
paths.push("/" + key.slice(0, key.length - 10));
} else {
paths.push("/" + key)
}
});
let timestamp = new Date().getTime();
let input = { // CreateInvalidationRequest
DistributionId: "E2CWYO03NUQKOG", // cf-id
InvalidationBatch: { // InvalidationBatch
Paths: {
Quantity: paths.length,
Items: paths
},
CallerReference: timestamp.toString() // required
},
};
//CloudFront Invalidation 요청 생성
let command = new CreateInvalidationCommand(input);
//CloudFrontClient 요청 수행 및 결과
let response = await client.send(command);
//응답 결과 출력
console.log(JSON.stringify(response));
callback(null, `cf-invalidation`);
};
생성한 Lambda 함수에 S3 트리거를 추가해줍니다.
정적 컨텐츠가 업로드 될 S3 버킷을 선택하고 Event Types 은 'All object create events' 를 선택합니다.
트리거 구성을 완료합니다.
현재 이미지를 확인합니다.
S3 에 동일한 경로에 동일한 파일명으로 정적 컨텐츠를 업로드 합니다.
CF 무효화가 처리되었는지 확인합니다.
CloudFront Cache 가 무효화가 완료되었고 새롭게 업로드된 컨텐츠가 Cache 제공됩니다.
결론
S3 이벤트 트리거를 이용하면 사용자의 개입 없이 CloudFront 의 오리진으로 구성된 S3의 오브젝트가 변경(모든 객체 생성 이벤트)을 감지하여 Lambda 함수를 실행하여 업데이트된 파일에 대해서만 CloudFront Cache 를 무효화 처리하게 됩니다.
Lambda 할당량 및 파일 무효화 요금은 아래 링크에서 확인 가능합니다.
Lambda 할당량
https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/gettingstarted-limits.html
파일 무효화 요금 및 요청 최대값
'AWS' 카테고리의 다른 글
당신이 좋아할만한 콘텐츠
-
AWS EC2 Blue/Green Deployment (Feat. Jenkins, CodeBuild, CodeDeploy) - Part 1 2023.10.05
-
SSM(Session Manager) Plugin 을 사용하여 Local PC 에서 AWS Private 자원에 접근하기 2023.09.19
-
AWS MSK를 활용한 AWS RDS PostgreSQL CDC 2023.07.05
-
AWS에서 Terraform, ECS Fargate 및 CloudMap을 사용하여 마이크로 서비스 인프라를 구축하는 방법 | part 2 2023.06.05
소중한 공감 감사합니다