검색
4분 읽기

청구서를 직접 뜯어 AWS 비용을 줄인 기록: 약 18% 추정과 실청구 검증

Cost Explorer 없이 시작해, 추정 절감과 실제 청구를 따로 확인하기까지
#AWS#비용 절감#Terraform#인프라 운영

청구 금액은 있는데, 내역을 볼 도구가 없었다

퍼플페퍼에서 풀스택 개발자로 일한 지 7개월 차다. 인프라 담당자가 퇴사한 뒤 AWS 계정 운영도 맡게 됐다.

월 AWS 청구액은 수천 달러 규모였다. 그런데 계정의 결제 구조 때문에 Cost Explorer를 쓸 수 없었다. 청구액은 알아도 어떤 서비스의 어떤 사용유형에서 비용이 나가는지 직접 풀어 봐야 했다.

결제 대행사의 청구 API로 내역을 받아 서비스·사용유형 단위로 분해하는 도구를 만들었다. 먼저 할 일은 비싼 서버를 고르는 것이 아니라, 무엇에 돈을 내고 있는지 읽을 수 있게 만드는 것이었다. 청구서에서 찾은 비용을 실제 사용 근거와 연결해야 줄일 대상을 정할 수 있었다.

«돌고 있다»와 «쓰고 있다»를 나눠 보기

유휴 크롤링 서버를 조사할 때 기준으로 삼은 질문이다. 서버가 켜져 있다는 사실만으로 지금도 필요하다고 할 수는 없었다. 반대로 사용률이 낮아 보인다는 이유만으로 삭제할 수도 없었다.

그래서 코드 호출 경로, DB 테이블 읽기 카운터, 접속 로그를 함께 봤다. 코드에서는 해당 서버로 이어지는 호출 경로를 확인했다. DB에서는 seq_scan과 idx_scan을 시간 간격을 두고 두 번 측정했다. 누적된 숫자 자체보다 관측 사이에 읽기가 늘었는지가 판단에 필요했다. 여기에 접속 로그를 대조해 실제 접근 흔적을 확인했다.

이 방법을 «카운터가 안 늘면 지워도 된다»는 규칙으로 쓰고 싶지는 않다. 관측 구간에 읽기가 없었다는 사실과 앞으로도 필요 없다는 판단은 다르다. 나는 코드와 DB, 접속 기록으로 안 쓰인다는 근거를 모으고 오너와 합의한 뒤 정리했다. 삭제 결정을 지표 하나에 맡기지 않는 것이 이 과정의 핵심이었다.

청구 항목을 보는 질문도 달라졌다. Lightsail 소형 가상서버는 꺼져 있어도 과금되고 있었다. 이렇게 남은 서버 3대와 연결되지 않은 고정 IP를 정리한 항목은 월 $333이었다. 실행 상태와 청구 상태도 따로 확인해야 했다.

지우거나 줄이기 전에 되돌릴 길부터

안 쓰인다는 근거를 확보한 뒤에도 곧바로 한꺼번에 지우지는 않았다. 유휴 크롤링 서버는 하루 한 대씩 스냅샷을 남긴 후 삭제했다. 이 항목의 추정 절감액은 월 약 $477이었다. 사용 여부를 판단하는 일과 판단이 틀렸을 때 돌아갈 준비는 별개였다.

Fargate는 없애는 대신 할당량을 줄였다. 먼저 14일간 사용률을 실측했다. CPU 평균은 2% 이하였고, 메모리 최대 사용률은 대부분 25% 이하였다. 이 수치가 곧바로 모든 환경을 줄여도 된다는 뜻은 아니었다.

dev부터 줄여 5일간 관찰했다. 그때 메모리 최대 사용률은 28%였고, 이후 stg에 적용했다. 이 항목은 월 약 $166 절감을 추정했다. 먼저 덜 위험한 환경에 적용하고 관측한 뒤 다음 환경으로 넘어가는 순서를 지켰다.

비용 표에는 절감액이 남지만, 실행에서 먼저 필요했던 것은 스냅샷과 적용 순서였다.

함정: Terraform의 null이 제거 요청은 아니었다

서버리스 캐시는 실데이터가 1KB 미만인데 최소 용량 1GB를 예약해 과금되고 있었다. 이 예약을 해제하는 항목은 월 $196이었다.

문제는 설정을 바꾸는 단계에 있었다. Terraform에서 최소값을 null로 바꿨지만, provider가 제거 요청을 보내지 않았다. 내가 설정 파일에서 값을 비웠다는 사실과 원격 서비스의 예약이 해제됐다는 사실은 같지 않았다.

결국 API로 Minimum=0을 보냈고, 이후 Terraform plan에서 변경이 없음을 확인했다. 이 사례에서 확인한 것은 당시 provider가 null을 처리한 방식이다. 모든 Terraform 리소스에서 같은 문제가 생긴다고 일반화할 근거는 없다. 다만 선언을 고쳤다는 것만으로 실제 과금 조건까지 바뀌었다고 결론 내리면 안 된다는 점은 남았다.

함정: 총액만 보면 절감이 덜 된 것처럼 보였다

실행이 끝난 뒤에는 청구서로 돌아왔다. 8월 작업분을 검증하려고 7월과 9월을 비교했더니 관련 서비스의 월 비용은 $917 줄었다. 그런데 같은 기간 전체 청구액 감소는 그보다 작았다.

총액만 봤다면 추정이 크게 틀렸거나 작업 효과가 작았다고 생각할 수 있었다. 다시 서비스별로 나눠 보니 다른 항목의 사용량 증가가 절감분을 상쇄하고 있었다. 줄인 항목과 늘어난 항목을 같은 합계에 두면 무엇이 달라졌는지 놓치기 쉬웠다.

추정과 실청구는 같은 숫자가 아니다

단가에 줄인 양을 곱해 계산한 전체 작업의 추정 월 절감액은 약 $1,500이다. 월 청구액의 약 18%에 해당한다. 여기에는 앞서 적은 항목 외에 실패만 하던 감시 작업 정리 등 소액 항목도 포함된다.

반면 실제 청구서로 확인한 것은 8월 작업분의 관련 서비스 월 $917 감소다. 10월 작업분은 아직 청구로 확인하기 전이다. 전체 작업의 추정액과 검증한 작업분의 실청구 변화는 범위가 다르다. 약 18%를 실제 총청구 감소율이라고 쓰면 이 차이를 감추게 된다.

그래서 추정 절감과 실청구 검증은 원장을 따로 둔다. 변경 당시 계산한 절감액은 예상 효과이고, 이후 청구서에서 확인한 값은 실제 관측이다. 다른 서비스에서 늘어난 비용까지 분리해야 내가 바꾼 부분의 결과를 설명할 수 있다.

남은 기준

이번에 배운 것은 비용 절감에 앞서 사용 여부를 설명할 수 있어야 한다는 점이다. 켜져 있는지, 호출되는지, 돈이 나가는지는 각각 확인할 질문이었다. 근거를 모은 다음에는 되돌릴 준비를 하고, 변경 후에는 청구서를 다시 읽어야 했다.

서버를 지운 일보다 이 순서가 더 오래 남을 것 같다. 코드와 사용 기록으로 판단하고, 스냅샷과 단계적 적용으로 실행하고, 추정과 실제 청구를 나눠 결과를 적는 것. 다음 비용 작업에서도 같은 기준으로 판단하려 한다.

링크가 복사되었습니다

자주 묻는 질문

아니다. 전체 작업의 추정 월 절감액은 약 $1,500으로 청구액의 약 18%다. 8월 작업분은 7월과 9월 청구를 비교해 관련 서비스 월 $917 감소를 확인했다.
결제 대행사의 청구 API로 청구서를 서비스와 사용유형 단위로 직접 분해하는 도구를 만들었다.

댓글