당신의 Cloud Storage Bucket에 6개월 동안 아무도 손대지 않은 2TB 데이터가 있습니다 (당신은 16배나 과다하게 지불하고 있습니다) 💾
Source: Dev.to
비용 비교
| Class | Cost/GB / month | Min Duration | Best For | Retrieval Fee |
|---|---|---|---|---|
| Standard | $0.020 | 없음 | 핫 데이터, 빈번한 접근 | 무료 |
| Nearline | $0.010 | 30 일 | 덜 자주 접근 | — |
| Coldline | $0.004 | 90 일 | 드물게 접근 (분기별) | — |
| Archive | $0.0012 | 365 일 | 드물게 접근 (연간) | — |
Note: 모든 스토리지 클래스는 동일한 11 개의 9(99.999999999 %) 내구성과 밀리초 수준 접근 지연을 제공합니다. Archive 스토리지는 테이프와 다르며 – 데이터는 즉시 접근 가능하고, 단지 더 높은 검색 비용만 지불하면 됩니다.
라이프사이클 정책이 중요한 이유
- 모든 객체는 Standard 스토리지 클래스에서 시작하며, 개입하지 않으면 영원히 그곳에 머뭅니다.
- GCP 자동으로 데이터를 더 저렴한 티어로 이동시키지 않습니다.
- 정책이 없으면, 6개월 동안 손대지 않은 2 TB 데이터셋은 월 $40이 들지만, 실제로는 $2.40 정도만 비용이 들 수 있습니다.
라이프사이클 정책은 객체가 오래될수록 자동으로 더 저렴한 클래스로 전환합니다—수동 작업, 스크립트, 또는 cron 작업이 필요 없습니다. Terraform을 사용하면 몇 분 안에 배포할 수 있습니다.
일반적인 티어‑다운 패턴
Standard → Nearline → Coldline → Archive → Delete
Terraform 예시: 간단한 티어‑다운
resource "google_storage_bucket" "data" {
name = "${var.project_id}-app-data"
location = "US"
storage_class = "STANDARD" # start in Standard
# 30 days → Nearline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
condition {
age = 30
matches_storage_class = ["STANDARD"]
}
}
# 90 days → Coldline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "COLDLINE"
}
condition {
age = 90
matches_storage_class = ["NEARLINE"]
}
}
# 365 days → Archive
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "ARCHIVE"
}
condition {
age = 365
matches_storage_class = ["COLDLINE"]
}
}
# 730 days (2 years) → Delete
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 730
}
}
labels = local.common_labels
}
⚠️ 주의: 라이프사이클 규칙에 의해 수행되는 전환은 조기 삭제 비용이 발생하지 않습니다. 객체를 수동으로 다른 클래스로 다시 쓰면 검색 비용과 조기 삭제 비용이 모두 발생하므로, 규칙에 맡겨 처리하십시오.
Terraform 예제: 접두사 기반 다계층
resource "google_storage_bucket" "multi_tier" {
name = "${var.project_id}-multi-tier-data"
location = "US"
# ---------- Logs ----------
# 7 days → Nearline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
condition {
age = 7
matches_prefix = ["logs/"]
matches_storage_class = ["STANDARD"]
}
}
# 30 days → Coldline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "COLDLINE"
}
condition {
age = 30
matches_prefix = ["logs/"]
matches_storage_class = ["NEARLINE"]
}
}
# 90 days → Delete
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 90
matches_prefix = ["logs/"]
}
}
# ---------- Backups ----------
# 30 days → Coldline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "COLDLINE"
}
condition {
age = 30
matches_prefix = ["backups/"]
matches_storage_class = ["STANDARD"]
}
}
# 90 days → Archive
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "ARCHIVE"
}
condition {
age = 90
matches_prefix = ["backups/"]
matches_storage_class = ["COLDLINE"]
}
}
# 730 days → Delete (keep backups for 2 years)
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 730
matches_prefix = ["backups/"]
}
}
# ---------- User uploads ----------
# 90 days → Nearline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
condition {
age = 90
matches_prefix = ["uploads/"]
matches_storage_class = ["STANDARD"]
}
}
labels = local.common_labels
}
하나의 버킷, 세 가지 데이터 패턴:
- 로그는 적극적으로 단계가 낮아지며 90 일 후 삭제됩니다.
- 백업은 한 달 동안은 고온(Hot) 상태를 유지하고, 그 다음에는 냉각(Cold) 상태, 마지막으로 최대 2 년까지 보관되는 아카이브(Archive) 상태가 됩니다.
- 사용자 업로드는 3개월 동안 Standard 상태를 유지한 뒤 Nearline으로 이동합니다.
Terraform 예제: 버전 관리 버킷
resource "google_storage_bucket" "versioned" {
name = "${var.project_id}-versioned-data"
location = "US"
versioning {
enabled = true
}
# Keep only the 3 most recent versions
lifecycle_rule {
action {
type = "Delete"
}
condition {
num_newer_versions = 3
with_state = "ARCHIVED"
}
}
# Delete non‑current versions older than 90 days
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 90
with_state = "ARCHIVED"
}
}
# Abort incomplete multipart uploads after 7 days
lifecycle_rule {
action {
type = "AbortIncompleteMultipartUpload"
}
condition {
age = 7
}
}
labels = local.common_labels
}
Why? 버전 관리는 데이터를 보호하지만 정리 작업이 없으면 저장 비용이 두 배 또는 세 배로 증가할 수 있습니다. 위 규칙들은 버킷을 자동으로 깔끔하게 유지해 줍니다.
요약
- 모든 클래스가 동일한 내구성과 지연 시간을 공유합니다—필요한 액세스 패턴에 대해서만 비용을 지불합니다.
- 수명 주기 규칙은 데이터를 더 저렴한 계층으로 이동하고 최종적으로 삭제하는 가장 간단하고 안전한 방법입니다.
- Terraform으로 몇 분 안에 배포하고, GCP가 나머지를 처리하도록 하세요.
비용 효율적인 GCP 클라우드 스토리지와 Terraform
⚠️ 숨겨진 비용 요인
Incomplete multipart uploads는 콘솔에 표시되지 않지만 여전히 스토리지를 차지합니다. 애플리케이션이 대용량 파일을 업로드하고 중간에 실패하는 경우, 이러한 조각들이 조용히 쌓이게 됩니다.
AbortIncompleteMultipartUpload 규칙은 무료 보험입니다.
Autoclass – 자동 티어링
데이터가 얼마나 자주 액세스되는지 모를 경우, GCP의 Autoclass 기능은 실제 액세스 패턴에 따라 스토리지 클래스를 자동으로 이동시킵니다.
resource "google_storage_bucket" "auto_tiered" {
name = "${var.project_id}-auto-tiered"
location = "US"
autoclass {
enabled = true
terminal_storage_class = "ARCHIVE" # Lowest tier it can reach
}
labels = local.common_labels
}
Autoclass는 자주 액세스되는 데이터를 Standard 클래스로 위로 이동시키고(라이프사이클 규칙으로는 할 수 없습니다), 사용되지 않은 데이터를 자동으로 티어를 아래로 이동시킵니다. 관리 비용이 약간 발생하지만, 예측할 수 없는 액세스 패턴에서는 비용보다 절감 효과가 더 큽니다.
Autoclass와 수동 라이프사이클 규칙을 언제 사용할까
| 시나리오 | 권장 방법 |
|---|---|
| 접근 패턴이 알려진 경우(로그, 백업) | 수동 라이프사이클 규칙 |
| 접근 패턴이 알 수 없거나 혼합된 경우 | Autoclass |
| 몇 개월 후에 다시 접근될 가능성이 있는 데이터 | Autoclass |
| 규정 준수 요구사항(특정 클래스에 있어야 함) | 수동 라이프사이클 규칙 |
| 비용을 최대한 통제하고 싶을 때 | 수동 라이프사이클 규칙 |
모든 팀 버킷에 동일한 라이프사이클 규칙 적용
variable "buckets" {
type = map(object({
location = string
lifecycle_type = string # "logs", "backups", "general", "autoclass"
}))
default = {
"team-alpha-logs" = {
location = "US"
lifecycle_type = "logs"
}
"team-beta-backups" = {
location = "US"
lifecycle_type = "backups"
}
"ml-training-data" = {
location = "US"
lifecycle_type = "autoclass"
}
}
}
locals {
lifecycle_configs = {
logs = {
nearline_age = 7
coldline_age = 30
delete_age = 90
}
backups = {
nearline_age = 30
coldline_age = 90
delete_age = 730
}
general = {
nearline_age = 30
coldline_age = 90
delete_age = 365
}
}
}
관리형 버킷 (Autoclass 비활성)
resource "google_storage_bucket" "managed" {
for_each = {
for k, v in var.buckets : k => v
if v.lifecycle_type != "autoclass"
}
name = "${var.project_id}-${each.key}"
location = each.value.location
storage_class = "STANDARD"
# → Move to NEARLINE
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
condition {
age = local.lifecycle_configs[each.value.lifecycle_type].nearline_age
matches_storage_class = ["STANDARD"]
}
}
# → Move to COLDLINE
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "COLDLINE"
}
condition {
age = local.lifecycle_configs[each.value.lifecycle_type].coldline_age
matches_storage_class = ["NEARLINE"]
}
}
# → Delete
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = local.lifecycle_configs[each.value.lifecycle_type].delete_age
}
}
# → Abort incomplete multipart uploads
lifecycle_rule {
action {
type = "AbortIncompleteMultipartUpload"
}
condition {
age = 7
}
}
labels = local.common_labels
}
새 버킷이 필요하신가요? buckets 맵에 항목을 하나 추가하고 terraform apply를 실행하세요. 라이프사이클 규칙이 즉시 적용됩니다. ✅
빠른 성과 작업
| 작업 | 노력 | 절감 |
|---|---|---|
| 기존 로그 버킷에 수명 주기 규칙 추가 | 5 분 | 로그 스토리지 73‑94 % 절감 |
AbortIncompleteMultipartUpload 활성화 | 2 분 | 눈에 보이지 않는 비용 누수 차단 |
| 버전 관리 정리 규칙 추가 | 5 분 | 버전이 있는 버킷 50‑70 % 절감 |
| 재사용 가능한 수명 주기 모듈 생성 | 15 분 | 조직 전체에 일관된 규칙 적용 |
| 알 수 없는 패턴에 대해 Autoclass 활성화 | 2 분 | 자동 최적화 티어 적용 |
로그 버킷부터 시작하세요 – 보통 가장 큰 원인입니다 (일주일이 지나면 아무도 읽지 않는 방대한 데이터량). 🎯
Pricing Snapshot (US region)
| 클래스 | 가격 / GB |
|---|---|
| Standard | $0.020 (핫 데이터, 빈번한 접근) |
| Nearline | $0.010 (≤ 1×/월, 최소 30일) |
| Coldline | $0.004 (≤ 1×/분기, 최소 90일) |
| Archive | $0.0012 (≤ 1×/년, 최소 365일) |
모든 클래스는 동일한 내구성과 지연 시간을 제공하며, 차이는 가격뿐입니다.
왜 라이프사이클이 중요한가
- 라이프사이클이 없음 → 모든 객체가 영원히 Standard에 머무름 → 오래된 데이터에 대해 16배까지 높은 비용 발생.
- 몇 분짜리 Terraform → 수년간의 낭비를 없앨 수 있습니다. 🪣
다음 단계
- 식별 가장 큰 버킷을. 콘솔에서 “last accessed”(마지막 액세스) 기준으로 정렬합니다.
- 적용 적절한 lifecycle(수명 주기) 또는 Autoclass 구성을.
- 모니터링 다음 달 동안 비용 절감 효과를.
핵심 요점: 버킷에 lifecycle 규칙이 없으면 과도하게 비용을 지불하고 있습니다. 몇 분만 Terraform을 사용하면 오래된 데이터에서 80 % 이상의 절감을 달성할 수 있습니다.
이 내용이 도움이 되었나요? Terraform을 활용한 GCP 비용 최적화 팁을 더 보려면 팔로우하세요! 💬