Skip to content

Nền tảng phân cấp tài nguyên: Kiến trúc phân cấp GCP

Vì sao điều này quan trọng trong production

Phân cấp tài nguyên của GCP không phải là tính năng tùy chọn — nó là nền tảng của mọi quyết định về bảo mật, thanh toán, mạng, và tuân thủ trên Google Cloud. Mọi quyết định kiến trúc hệ thống đều phụ thuộc vào việc bạn hiểu rõ phân cấp này.

Hậu quả khi thiết kế sai:

  • Blast radius không kiểm soát: Nếu IAM policy được đặt ở cấp organization thay vì folder, một lỗi có thể ảnh hưởng tới toàn bộ công ty
  • Phân bổ chi phí sai: Không thể theo dõi chi phí chính xác khi phân cấp tài nguyên không đúng
  • Cấu hình sai policy mạng: Thiết kế Shared VPC phụ thuộc hoàn toàn vào cấu trúc phân cấp
  • Vi phạm tuân thủ: Phân cấp sai = không thể ép buộc organization policies hiệu quả
  • Gánh nặng vận hành: Phải duy trì nhiều policy chồng lấn nếu phân cấp bị phá vỡ

Ở quy mô enterprise (1000+ projects), thiết kế phân cấp sai có thể dẫn đến downtime toàn công ty, rò rỉ dữ liệu, hoặc vi phạm tuân thủ pháp lý.

Kiến trúc phân cấp: Bốn tầng

Phân cấp tài nguyên của GCP là một cấu trúc cây có gốc với chính xác 4 tầng:

Organization (root)
    ├── Folder (optional)
    │   ├── Folder (nested)
    │   │   └── Project
    │   └── Project
    └── Project

Tầng 1: Organization Resource

Organization resource là nút gốc của toàn bộ phân cấp GCP — tương đương khái niệm "tập đoàn" hoặc "công ty" trong GCP.

Điều kiện tiên quyết:

  • Phải có tài khoản Google Workspace hoặc Cloud Identity
  • Mỗi domain chỉ có thể liên kết với duy nhất một organization
  • Khi bất kỳ user nào trong domain tạo GCP project lần đầu, organization resource sẽ được provision tự động

Các đặc điểm chính của Organization:

  1. Gắn với vòng đời: Tất cả projects và folders thuộc organization này — nếu một nhân viên rời công ty, projects vẫn tồn tại và được bảo vệ
  2. Quản trị tập trung: Organization admins có quyền xem/quản lý tất cả resources trong toàn công ty
  3. Gắn với danh tính: Organization liên kết với Google Workspace customer ID (từ Directory API)
  4. Điểm kế thừa chính sách: Mọi IAM allow/deny policies, organization policies, audit logs đều bắt đầu từ organization

Một điểm quan trọng: Organization resource không được tạo bằng lệnh gcloud — nó được provision tự động. Bạn chỉ có thể đặt IAM policies và organization policies trên nó sau khi nó đã được tạo.

Hệ quả trong production:

  • Nếu bạn không có organization, bạn không thể sử dụng folders — bị hạn chế về governance
  • Nếu bạn cần mô hình multi-organization (trường hợp hiếm), phải xử lý bằng workaround (không được hỗ trợ chính thức)

Tầng 2: Folder Resources

Folders là cơ chế nhóm tùy chọn giữa organization và projects. Nó tương tự organizational units trong Active Directory.

Tại sao folders quan trọng:

Hãy hình dung cấu trúc công ty như sau:

Công ty (Organization)
├── Engineering (Folder)
│   ├── Backend team (Folder)
│   │   └── backend-prod, backend-staging projects
│   └── Frontend team (Folder)
│       └── frontend-prod, frontend-staging projects
├── Data (Folder)
│   ├── Data Engineering (Folder)
│   └── Analytics (Folder)
└── Finance (Folder)
    ├── Billing team
    └── FP&A team

Mỗi cấp folder là một điểm gắn policy. Bạn có thể:

  • Gán role Editor cho một team lead ở cấp folder → họ quản lý toàn bộ projects trong folder
  • Ép buộc organization policies (ví dụ: vô hiệu hóa external IP) ở cấp folder → tự động áp dụng cho toàn bộ child resources
  • Tách luồng billing theo từng phòng ban

Best practice cho cấu trúc folder trong production:

  1. Phản ánh cấu trúc tổ chức, nhưng không quá sâu

    • Khuyến nghị: Tối đa 2-3 mức nesting folder
    • Quá sâu = phức tạp kế thừa policy, khó troubleshoot
    • Quá nông = không đủ độ chi tiết cho governance
  2. Folder vs Project để cô lập

    • Folders = ranh giới team/phòng ban
    • Projects = ranh giới workload/môi trường
    • Không nên đặt tất cả prod resources vào cùng một folder rồi dùng labels để phân chia — hãy tách bằng project
  3. Phân bổ ngân sách: Mỗi folder nên tương ứng với một cost center

    • Tránh trộn chi phí giữa các team trong cùng một folder

Giới hạn của Folder:

  • Một project chỉ có thể có duy nhất một parent folder hoặc organization
  • Folder không thể đổi tên ở cấp resource ID (chỉ đổi display name)
  • Việc di chuyển projects giữa folders có ảnh hưởng lớn tới VPC peering (xem chi tiết ở 09.shared-vpc-model.md)

Tầng 3: Project Resource

Project là đơn vị vận hành cơ bảntrust boundary của GCP.

Các định danh của project:

json
{
  "projectId": "my-webapp-prod",          // 6-30 ký tự, toàn cục duy nhất, không đổi
  "name": "My Web App - Production",      // tên hiển thị, có thể đổi, không duy nhất
  "projectNumber": "123456789012",        // tự động gán, không đổi, duy nhất
  "lifecycleState": "ACTIVE",             // ACTIVE, DELETE_IN_PROGRESS, DELETE_REQUESTED
  "parent": {
    "type": "folder",
    "id": "folders/987654321"
  }
}

Project ID vs Project Number vs Project Name:

  • Project ID: Định danh duy nhất được dùng trong API calls, resource names, billing reports. Không thể thay đổi sau khi tạo.
  • Project Number: Được gán tự động, dùng trong các hệ thống nội bộ của Google. Ít khi cần nhưng quan trọng với tên service account: PROJECT_NUMBER@cloudservices.gserviceaccount.com
  • Project Name: Tên hiển thị, dễ đọc với con người, không dùng trong APIs. Có thể thay đổi bất cứ lúc nào.

Lỗi thường gặp: Developers thường nhầm project ID với project number khi tự động hóa. Ví dụ:

bash
# ❌ SAI
gcloud config set project 123456789012  # project number

# ✅ ĐÚNG
gcloud config set project my-webapp-prod  # project ID

Lần đầu set project, lỗi này thường hiện ra rất rõ — nhưng trong các script CI/CD, nó có thể gây lỗi âm thầm.

Khuyến nghị quy ước đặt tên:

  • Dùng kebab-case (chữ thường + dấu gạch nối): team-service-environment
  • Ví dụ: backend-api-prod, data-pipeline-staging, ml-training-dev
  • Không nên chứa thông tin nhạy cảm (customer IDs, API keys) — project ID xuất hiện trong logs, billing reports, URLs

Project như một trust boundary:

Trong GCP, resources trong cùng project mặc định có mức tin cậy cao hơn so với resources liên project. Ví dụ:

  • Service accounts trong project A có thể truy cập resources trong project A mà không cần additional IAM policy nếu quyền đã được cấp ở cấp project
  • Service accounts trong project A phải có IAM binding liên project rõ ràng để truy cập resources trong project B

Mẫu trong production:

  • Mỗi môi trường một project: team-service-prod, team-service-staging, team-service-dev
  • Cách này cho phép: quota khác nhau theo môi trường, theo dõi billing riêng, blast radius rõ ràng

Tầng 4: Service Resources

Service resources (Compute Engine instances, Cloud Storage buckets, Cloud SQL databases, v.v.) nằm bên trong projects.

Từ góc nhìn phân cấp GCP, service resources được coi là leaf nodes — chúng kế thừa policy từ project, nhưng không có child riêng.

Điều quan trọng: Resource-level IAM policies (ví dụ: cấp viewer role trên một Compute Engine instance cụ thể) có thể được đặt, nhưng phải là tập con của quyền cấp project. Bạn không thể cấp quyền ở resource level nếu user không có quyền truy cập cơ bản vào project.

Cơ chế kế thừa policy

Khi một IAM policy được đặt ở một cấp trong phân cấp, tất cả child resources sẽ kế thừa policy đó — nhưng effective policy = hợp của:

  • Policies được đặt trực tiếp trên resource
  • Policies kế thừa từ parent (organization → folder → project → resource)

Mô hình kế thừa chi tiết

Organization (IAM policy: Organization Admin → admins@company.com)
    ↓ kế thừa
    Folder/Engineering (IAM policy: Folder Admin → eng-leads@company.com)
        ↓ kế thừa
        Project/backend-prod (IAM policy: Editor → backend-team@company.com)
            ↓ kế thừa
            Compute Engine instance (không có IAM explicit)

Effective policy trên Compute Engine instance:
- Organization Admin (kế thừa)
- Folder Admin (kế thừa)
- Editor (kế thừa)

Cảnh báo: Quan hệ role theo tầng

Các basic roles (Owner, Editor, Viewer) có tính chất:

  • Owner ⊃ Editor ⊃ Viewer (quan hệ tập con)

Nếu user đã có role Editor từ kế thừa ở cấp project, cấp thêm role Viewer ở cấp resource sẽ không có tác dụng — nó là dư thừa.

bash
# Tình huống: User có role Editor trên project, role Viewer được cấp trên bucket
# Kết quả: User vẫn có quyền Editor trên bucket (từ kế thừa ở project)
# Role Viewer từ bucket là dư thừa

Có thể override kế thừa không?

IAM không hỗ trợ "override" policies — chỉ có allow policies (hợp) hoặc deny policies (explicit deny).

Nếu bạn muốn ngăn truy cập, phải dùng:

  1. Deny policies (mới hơn, khuyến nghị) — explicit deny có ưu tiên cao hơn
  2. Xóa user khỏi group (nếu policy dùng group)
  3. Di chuyển resource sang folder có policy chặt hơn

Hệ quả trong production: Hãy thiết kế phân cấp sao cho mặc định kế thừa là an toàn. Ví dụ:

  • Không cấp role "Editor" rộng ở cấp organization — chỉ cấp các role cụ thể
  • Dùng groups và quản lý membership của group

Resource Manager API: Góc nhìn qua API

Khi bạn truy vấn phân cấp tài nguyên qua API, Google Resource Manager API cho phép:

bash
# Liệt kê tất cả projects trong organization
gcloud projects list --filter="parent.id:ORGANIZATION_ID"

# Lấy chi tiết folder
gcloud resource-manager folders describe folders/FOLDER_ID

# Tìm kiếm resources (cần Cloud Asset Inventory)
gcloud asset search-all-resources \
  --scope=organizations/ORGANIZATION_ID \
  --asset-types=compute.googleapis.com/Instance

Lưu ý về tính không nhất quán của API: Resource Manager API có mô hình eventual consistency. Khi bạn tạo project:

  1. Project được tạo
  2. IAM policies được áp dụng
  3. Gắn billing account diễn ra
  4. Có độ trễ lan truyền: 5-30 giây trước khi tất cả GCP services nhìn thấy project mới

Trong tự động hóa production, bạn phải thêm retry logic khi tạo project:

python
# ❌ Rủi ro
project = create_project(project_id)
set_iam_policy(project_id, policies)  # Có thể thất bại nếu propagation chưa hoàn tất

# ✅ An toàn hơn
project = create_project(project_id)
time.sleep(10)  # hoặc exponential backoff với retries
set_iam_policy(project_id, policies)

Hành vi cache & eventual consistency

GCP Resource Manager cache việc đánh giá policy ở nhiều cấp:

  1. Control plane: Cache của API server (vài trăm ms)
  2. Data plane: Cache theo từng service (khác nhau tùy service)
  3. Local caching: Client libraries có thể cache (cấu hình được)

Kịch bản production:

T=0: Admin thêm user vào group
T=5: IAM policy được đánh giá lại, user được thêm vào effective policy
T=10: GKE control plane thấy user có permission → pod được tạo
T=15: Kubelet thấy pod → container khởi động

Nếu ứng dụng kỳ vọng "policy được áp dụng ngay lập tức", nó sẽ thất vọng — bạn phải tính đến độ trễ propagation.

Cấu trúc quota

Quotas trong GCP không kế thừa — chúng được quản lý độc lập ở từng cấp:

  • Quota cấp organization: Giới hạn toàn cục (ví dụ: số project tối đa = 10,000)
  • Quota cấp folder: Tập con của quota organization
  • Quota cấp project: Giới hạn riêng của từng project (phổ biến nhất)

Hệ quả trong production:

  • Quota cấp organization = công cụ lập kế hoạch capacity
  • Quota cấp project = kiểm soát blast radius
  • Nếu project A chạm quota, project B không bị ảnh hưởng
bash
# Yêu cầu quota cao hơn ở cấp project
gcloud compute quotas describe METRIC --project=PROJECT_ID

# Điều chỉnh quota cấp organization (hỗ trợ hạn chế)
gcloud quotas info --project=ORGANIZATION_ID

Các mẫu phân cấp phổ biến

Mẫu 1: Mỗi môi trường một project (khuyến nghị)

Organization
└── Folder/My-App
    ├── my-app-prod (project)
    ├── my-app-staging (project)
    └── my-app-dev (project)

Ưu điểm:

  • Cô lập blast radius rõ ràng
  • Billing riêng theo môi trường
  • IAM policies riêng theo môi trường
  • Dễ hạn chế truy cập (dev không vào prod)

Nhược điểm:

  • Nhiều project = nhiều thứ phải quản lý
  • Chia sẻ tài nguyên liên project phức tạp

Mẫu 2: Mỗi team một folder (khuyến nghị cho org lớn)

Organization
├── Folder/Backend
│   ├── backend-prod
│   ├── backend-staging
│   └── backend-dev
├── Folder/Frontend
│   ├── frontend-prod
│   ├── frontend-staging
│   └── frontend-dev
└── Folder/Data
    ├── data-prod
    ├── data-staging
    └── data-dev

Ưu điểm:

  • Quản trị theo team
  • Theo dõi chi phí tập trung theo team
  • Quyền ở cấp folder

Nhược điểm:

  • Phức tạp nếu dịch vụ dùng chung giữa nhiều team

Mẫu 3: Hybrid (Shared Services + Team Projects)

Organization
├── Folder/Shared-Infrastructure
│   ├── networking (project)
│   ├── logging (project)
│   └── billing (project)
└── Folder/Teams
    ├── Folder/Backend-Team
    │   ├── backend-prod
    │   └── backend-dev
    └── Folder/Data-Team
        ├── data-prod
        └── data-dev

Ưu điểm:

  • Mạng tập trung (Shared VPC host)
  • Môi trường theo team
  • Có thể tổng hợp billing

Kiểm thử policy phân cấp

Trước khi triển khai thay đổi phân cấp production, phải test:

bash
# Kiểm tra inheritance của policy
gcloud resource-manager org-policies list --folder=FOLDER_ID

# Dry-run org policy (tính năng preview)
gcloud resource-manager org-policies set-policy --dry-run FILE.yaml

# Kiểm tra effective policy
gcloud projects get-iam-policy PROJECT_ID \
  --flatten="bindings[].members" \
  --format="table(bindings.role)"

Best practice:

  1. Test phân cấp mới ở folder non-production trước
  2. Xác thực IAM inheritance
  3. Kiểm tra quota compliance
  4. Theo dõi audit logs 24-48h trước khi mở rộng sang production

Di chuyển & tái cấu trúc

Thay đổi phân cấp trong production là một thao tác rủi ro cao:

  • Di chuyển project giữa folders = có thể gây gián đoạn dịch vụ (Shared VPC peering có thể hỏng)
  • Đổi organization policies = ép buộc hồi tố (resources hiện hữu có thể vi phạm)
  • Thêm folders hồi tố = có tác động phụ lên kế thừa IAM

Khuyến nghị: Phân cấp nên được thiết kế đúng ngay từ đầu. Nếu cần thay đổi:

  1. Lập kế hoạch migration cẩn thận
  2. Dùng dry-run policies
  3. Test kỹ ở staging
  4. Thực thi ngoài giờ làm việc

Tham khảo