콘텐츠로 이동

Serverless Prune Plugin으로 AWS Lambda Code Storage Limit 해결

Serverless Framework로 배포하던 중 Code storage limit exceeded 에러가 발생했다.

AWS를 이용한 Serverless 아키텍처에서 서비스를 운영하면 AWS Lambda를 자주 쓰게 된다. 지금 운영 중인 서비스에서도 Lambda를 아래처럼 여러 용도로 사용하고 있다.

  1. 15분 이내의 간단한 배치 처리
  2. API Gateway + AWS Lambda 조합의 웹 서버 처리
  3. Step Functions, CloudFront, S3 업로드 이벤트 같은 다른 AWS 리소스 전후처리

그러던 중 Serverless Framework(sls)로 배포하던 과정에서 아래와 같은 에러가 발생했다.

Terminal window
Code storage limit exceeded. (Service: Lambda, Status Code: 400, ...)

Lambda 코드 스토리지는 계정 단위로 관리되고, 기본 한도는 75GB다.

코드 스토리지는 해당 계정의 Lambda 함수 코드, 함수 버전, 레이어 버전 같은 배포 아티팩트가 사용하는 공간이다. 이 모든 데이터의 총합이 75GB를 넘으면 안 된다.

즉 특정 함수 하나의 문제가 아니라, 해당 계정에서 사용할 수 있는 코드 스토리지의 용량을 초과한 상황이었다.

오래된 Lambda 버전이 계속 쌓이면서 계정 전체 Code Storage를 가득 채우고 있었다.

AWS Lambda는 함수 코드와 함수 버전, 그리고 레이어 버전을 포함한 배포 아티팩트를 계정 단위 코드 스토리지에 저장한다.

Serverless Framework로 배포를 반복하면, 특별한 정리 작업이 없을 때 과거 버전이 계속 남아 있을 수 있다. 이번에 문제였던 것도 바로 이 부분이었다.

특히 Lambda 콘솔의 버전 탭을 보면 알 수 있듯, Lambda 함수를 배포할 때마다 새로운 버전이 계속 쌓일 수 있다.

  • 5MB 크기의 함수 코드를 30번 배포했다면, 단순 계산으로도 150MB가 누적될 수 있다.

서비스 초반에 만든 어떤 Lambda 함수는 버전이 300개가 넘게 쌓여 있었다. 이렇게 오래된 버전들이 계속 남아 있으면서, 계정 전체 Code Storage 한도인 75GB를 모두 사용하게 됐다.

먼저 수동으로 공간을 확보하고, 이후에는 serverless-prune-plugin으로 자동 정리하도록 바꿨다.

가장 먼저 한 일은 일단 다시 배포가 가능할 정도로 공간을 확보하는 것이었다.

  • 사용하지 않는 Lambda 함수 삭제
  • 오래된 Lambda 버전 삭제

조사 결과 사용하지 않는 Lambda 함수는 없었기 때문에, 오래된 버전 삭제만 진행했다. 이 작업은 팀의 시니어 엔지니어가 AWS CLI로 수동 정리했다.

Terminal window
$ aws lambda delete-function \
--function-name ${LAMBDA_FUNCTION_NAME} \
--qualifier ${LAMBDA_FUNCTION_VERSION}

이 작업은 sls deploy가 다시 가능해질 만큼의 공간이 확보될 때까지 계속됐다. (sls deploy 할 때마다 Code storage limit exceeded 가 발생해 아무것도 할수 없었다.)

2) serverless-prune-plugin으로 자동으로 과거 버전 삭제

섹션 제목: “2) serverless-prune-plugin으로 자동으로 과거 버전 삭제”

수동 정리는 급한 불을 끄는 방법일 뿐이라, 이후에는 오래된 버전이 다시 쌓이지 않도록 serverless-prune-plugin을 적용했다.

이 플러그인은 설정에 따라 일정 개수의 Lambda 함수 버전과 레이어 버전만 남기고 오래된 배포 아티팩트를 정리할 수 있다.

즉 배포할 때마다 오래된 버전을 함께 정리하도록 만들어, 이후에는 같은 문제가 반복되지 않도록 한 것이다.

설정 방법 자체는 별도 문서로 정리해 두었다.

먼저 하나의 Serverless Framework YAML에만 플러그인을 적용해 테스트했고, 의도대로 오래된 버전이 정리되는 것을 확인했다. 이후 같은 계정에서 사용하는 다른 Serverless Framework 설정들에도 플러그인을 적용하고 다시 배포했다.

이 과정은 특정 환경 하나만이 아니라, 같은 AWS 계정 안에서 운영하던 Dev, Staging, Prod 환경의 모든 Lambda 함수들을 대상으로 진행했다. Lambda Code Storage는 계정당 75GB 한도를 공유하므로, 과거 버전 정리도 계정 전체 기준으로 봐야 했다.

그 결과 Dev, Staging, Prod를 모두 포함한 같은 AWS 계정 전체 Code Storage 사용량이 아래처럼 줄었다.

  • 75GB -> 22GB

1) Lambda Code Storage는 함수 하나가 아니라 계정 전체 기준이다

섹션 제목: “1) Lambda Code Storage는 함수 하나가 아니라 계정 전체 기준이다”
  • 특정 Lambda 함수 하나만 커졌다고 보기보다, 같은 계정 안에 쌓인 함수 버전과 레이어를 함께 봐야 한다.
  • Dev, Staging, Prod를 분리해 운영하더라도 같은 계정을 쓰고 있다면 Code Storage는 공유한다.

2) 수동 삭제는 임시 대응이고, 핵심은 자동화다

섹션 제목: “2) 수동 삭제는 임시 대응이고, 핵심은 자동화다”
  • 오래된 버전을 CLI로 직접 지우는 것은 급한 대응으로는 가능하다.
  • 하지만 지속적으로 배포하는 환경이라면 prune 플러그인 같은 자동 정리 방식이 없으면 같은 문제가 반복된다.
  • 계정 전체 Lambda Code Storage 사용량
  • 오래된 Lambda 함수 버전 수
  • 오래된 Layer 버전 수
  • 배포 자동화 도구에서 버전 정리 설정이 있는지