Phân cấp billing: Gán chi phí & quản lý ngân sách
Nền tảng billing
Organization
├── Projects (tạo resources)
└── Billing Accounts (theo dõi chi phí)
Nhiều project → 1 billing account
1 project → Chỉ liên kết được với 1 billing accountQuan hệ chính:
- Project: Nơi chạy resource (compute, storage, v.v.)
- Billing Account: Nhận hóa đơn, thanh toán cho toàn bộ project đã liên kết
Cấu trúc Billing Account
bash
# Liệt kê billing accounts
gcloud billing accounts list
# Liên kết project với billing account
gcloud billing projects link PROJECT_ID \
--billing-account=BILLING_ACCOUNT_ID
# Xem project đang liên kết với billing account nào
gcloud billing projects describe PROJECT_IDMô hình gán chi phí
Mô hình 1: Chi phí theo Project
Đơn giản nhất: mỗi project = một cost center riêng
project-prod: $10,000/tháng
project-staging: $2,000/tháng
project-dev: $500/thángGiới hạn: Không thể tách chi phí bên trong project (ví dụ: service nào tốn nhiều nhất?)
Mô hình 2: Chi phí theo Label
Chi tiết hơn: dùng labels cho phân bổ chi phí
python
# Truy vấn chi phí theo label
from google.cloud import bigquery
query = """
SELECT
labels.key,
labels.value,
SUM(cost) as total_cost
FROM `project.billing.gcp_billing_export_v1_XXXXXX`
WHERE DATE(usage_start_time) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY labels.key, labels.value
HAVING SUM(cost) > 100 -- Chỉ hiển thị chi phí > $100
ORDER BY total_cost DESC
"""
results = bigquery.Client().query(query).result()
for row in results:
print(f"{row.key}={row.value}: ${row.total_cost:.2f}")Mô hình 3: Chargeback
Tính phí tài nguyên cho từng team:
python
def calculate_chargeback():
"""Chargeback hàng tháng theo cost-center"""
# Lấy chi phí theo label cost-center
costs_by_center = query_costs_by_label("cost-center")
charges = {}
for cost_center, cost in costs_by_center.items():
team = get_team_for_cost_center(cost_center)
# Tính overhead phòng ban (ví dụ: 5%)
overhead = cost * 0.05
total_charge = cost + overhead
charges[team] = {
"direct_cost": cost,
"overhead": overhead,
"total": total_charge
}
# Gửi invoice
for team, charges_detail in charges.items():
send_email(
to=f"finance-{team}@company.com",
subject=f"GCP Chargeback - {team}",
body=f"""
Chi phí trực tiếp: ${charges_detail['direct_cost']:.2f}
Overhead (5%): ${charges_detail['overhead']:.2f}
Tổng: ${charges_detail['total']:.2f}
"""
)Cảnh báo ngân sách
Cảnh báo khi vượt ngân sách
bash
# Tạo budget alert
gcloud billing budgets create \
--billing-account=BILLING_ACCOUNT_ID \
--display-name="Monthly budget limit" \
--budget-amount=5000 \
--threshold-rule=percent=50,spend_basis=current_spend \
--threshold-rule=percent=90,spend_basis=current_spend \
--threshold-rule=percent=100,spend_basis=current_spendCảnh báo ngân sách tùy chỉnh qua Pub/Sub
python
from google.cloud import pubsub_v1, monitoring_v3
def create_budget_alert():
"""Cảnh báo qua Pub/Sub khi vượt ngân sách"""
# Tạo budget
service = billingbudgets.BudgetServiceClient()
budget = billingbudgets.Budget(
display_name="Q1 2024 Budget",
budget_amount=billingbudgets.BudgetAmount(
specified_amount={"currency_code": "USD", "units": 10000}
),
threshold_rules=[
billingbudgets.ThresholdRule(percent_spend_basis=90),
billingbudgets.ThresholdRule(percent_spend_basis=100)
],
notifications_rule=billingbudgets.NotificationsRule(
pubsub_topic=f"projects/PROJECT_ID/topics/budget-alerts",
schema_version="1.0"
)
)
service.create_budget(
parent=f"billingAccounts/{BILLING_ACCOUNT_ID}",
budget=budget
)Tối ưu chi phí
Xác định resource đắt nhất
sql
-- Tìm 10 resource đắt nhất
SELECT
resource.name,
resource.labels.value as resource_label,
SUM(cost) as total_cost,
COUNT(*) as line_items
FROM `project.billing.gcp_billing_export_v1_XXXXXX`
WHERE DATE(usage_start_time) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY resource.name, resource.labels.value
ORDER BY total_cost DESC
LIMIT 10;
-- Tìm resource không dùng
SELECT
resource.name,
COUNT(*) as usage_count
FROM `project.billing.gcp_billing_export_v1_XXXXXX`
WHERE DATE(usage_start_time) >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
GROUP BY resource.name
HAVING COUNT(*) < 10 -- Mức sử dụng rất thấp
ORDER BY usage_count ASC;Chiết khấu theo reservation
bash
# Nhận chiết khấu cho capacity reserved (giảm 25-55% so với on-demand)
# Compute Engine reservations
gcloud compute reservations create prod-vms \
--project=PROJECT_ID \
--zone=us-central1-a \
--vm-family=N1 \
--local-ssd=0 \
--accelerator-type=nvidia-tesla-k80 \
--accelerator-count=2 \
--vm-count=10
# BigQuery slots (cam kết hàng năm)
gcloud compute reservations create bigquery-annual \
--annual-commitmentBilling đa project
Billing account hợp nhất
Organization
├── Prod Project
│ ├── VM: $5,000
│ └── Database: $3,000
├── Staging Project
│ └── VM: $500
└── Billing Account
├── Tháng 1: $8,500
├── Tháng 2: $9,200
└── Hóa đơn hợp nhấtLợi ích:
- Một hóa đơn duy nhất
- Chia sẻ chiết khấu (chiết khấu theo volume trên nhiều project)
- Thanh toán tập trung
- Dễ đối soát hơn
Quản lý billing bằng Terraform
hcl
# Terraform: tự động hóa budget alert + chargeback
resource "google_billing_budget" "monthly_budget" {
billing_account = var.billing_account_id
display_name = "Monthly team budget"
budget_amount {
specified_amount {
currency_code = "USD"
units = "50000"
}
}
threshold_rules {
percent_spend_basis = 50
}
threshold_rules {
percent_spend_basis = 90
}
threshold_rules {
percent_spend_basis = 100
}
notifications_rule {
pubsub_topic = google_pubsub_topic.budget_alerts.id
schema_version = "1.0"
monitoring_notification_channels = [
google_monitoring_notification_channel.email.id
]
}
}
# Cloud Function: kích hoạt bởi budget alert
resource "google_cloudfunctions_function" "chargeback" {
name = "monthly-chargeback"
runtime = "python39"
entry_point = "process_budget_alert"
source_archive_bucket = google_storage_bucket.functions.name
source_archive_object = google_storage_bucket_object.chargeback_zip.name
event_trigger {
event_type = "google.pubsub.topic.publish"
resource = google_pubsub_topic.budget_alerts.id
}
}Các anti-pattern
| Anti-pattern | Vấn đề | Giải pháp |
|---|---|---|
| Mỗi project một billing account | Không thấy tổng chi tiêu org | Dùng billing account hợp nhất |
| Không có label theo dõi chi phí | Không phân bổ được chi phí | Bắt buộc labels |
| Không có budget alert | Không thấy overspend | Đặt alert ở ngưỡng quan trọng |
| Không chargeback | Team lãng phí tài nguyên | Triển khai phân bổ chi phí |
| Hóa đơn thủ công | Sai sót, chậm trễ | Tự động chargeback |
| Không tối ưu chi phí | Lãng phí tiền cho resource không dùng | Kiểm toán chi phí định kỳ |