2. Google Cloud资源层级与IAM基础

在Google Cloud上做基础设施即代码(IaC),第一件必须搞清楚的事不是Terraform怎么写,而是资源放在哪里、权限从哪里继承。Google Cloud的资源模型是一棵严格的树:组织(Organization)→ 文件夹(Folder)→ 项目(Project)→ 资源(Resource)。这棵树决定了两个关键行为:资源归属的唯一路径,以及IAM策略沿树自上而下的继承方式。理解这两点,后续的环境隔离(dev/staging/prod)、团队权限边界、IaC的目录结构才有稳定的治理模型可依托。

一、四层资源层级:谁包含谁

最顶层是组织节点,它对应一个Google Workspace或Cloud Identity账号,是整棵树的根,也是所有资源计费和策略的最终归属点。组织下面可以创建文件夹,文件夹可以嵌套文件夹,用来表达业务单元、部门或环境分组。文件夹下面是项目,项目是启用API、创建资源、结算费用的基本单元——几乎所有GCP资源都必须属于某个项目。项目内部才是具体的资源,例如Compute Engine实例、Cloud Storage存储桶、BigQuery数据集。

关键约束:一个资源只能有一个父级,因此它在树中的位置是唯一的。项目只能属于一个文件夹(或直接挂在组织下),文件夹只能有一个父文件夹或组织。这种“单亲树”结构让权限和策略的继承路径完全确定,不会出现多路径冲突。

组织 Organization example.com · 根节点 文件夹: 研发部 Folder: R&D 文件夹: 生产环境 Folder: Production 文件夹: 沙箱 Folder: Sandbox 项目: dev-app Project ID: dev-app-001 项目: prod-app Project ID: prod-app-001 项目: sandbox-lab Project ID: sandbox-001 Compute 实例 vm-dev-web-01 Cloud Storage prod-app-assets BigQuery 数据集 sandbox_events IAM 策略继承方向(自上而下,子节点继承父节点所有绑定) 组织级绑定 如: roles/viewer 文件夹级绑定 如: roles/editor 项目级绑定 如: roles/owner 资源级绑定 如: 条件策略 子节点无法“拒绝”父节点授予的权限,只能通过更细粒度的绑定叠加或使用组织策略约束

二、IAM策略继承:权限只增不减

IAM策略是一组“谁对什么拥有什么角色”的绑定(binding)。绑定可以挂在组织、文件夹、项目或单个资源上。继承规则非常直接:子节点自动继承所有祖先节点的绑定。例如在组织节点给用户 alice@example.com 授予 roles/viewer,那么她对组织下所有文件夹、项目、资源都拥有查看权限,无需在每个项目重复绑定。

这里有一个容易踩坑的点:IAM没有“拒绝”语义。你无法在项目层写一条“拒绝alice查看”来覆盖组织层的授予。子节点只能通过追加绑定来扩大权限,不能缩小。如果确实需要限制,必须使用组织策略(Organization Policy),例如限制某些API只能在特定项目启用,或禁止在文件夹外创建资源。组织策略是约束,IAM是授权,两者配合才能形成完整的治理边界。

另一个关键概念是有效策略(Effective Policy):某个资源上最终生效的权限,等于从组织到该资源路径上所有绑定的并集。排查权限问题时,不能只看项目层的IAM页面,必须沿树向上检查每一层的绑定。

三、为IaC和环境隔离奠定治理模型

把上述层级映射到IaC实践,可以得到清晰的目录与状态管理策略。推荐的做法是:用文件夹表达环境边界,用项目表达应用或工作负载边界。例如:

组织: example.com
├── 文件夹: common          # 共享资源:网络、日志、密钥
│   └── 项目: shared-network
├── 文件夹: dev
│   ├── 项目: dev-app
│   └── 项目: dev-data
├── 文件夹: staging
│   └── 项目: staging-app
└── 文件夹: prod
    ├── 项目: prod-app
    └── 项目: prod-data

这样划分后,IAM绑定可以按层级施加:在 dev 文件夹给开发团队授予 roles/editor,他们自动获得该文件夹下所有dev项目的编辑权限,但完全接触不到 prod 文件夹。生产环境则只在 prod 文件夹给SRE团队授予更严格的自定义角色。IaC的Terraform代码也按文件夹组织,每个环境一个独立的state文件,避免误操作跨环境传播。

实践建议:在Terraform中,使用 google_folder_iam_member 和 google_project_iam_member 资源来管理绑定,而不是在项目内部用 google_project_iam_binding 覆盖式绑定。前者是增量添加,后者会替换该角色下的所有成员,容易在多人协作时互相覆盖。

四、一个可执行的权限检查示例

假设你要验证“开发人员是否能访问生产存储桶”。按继承模型,检查路径如下:

  1. 确认目标资源:prod-app-assets 存储桶,位于项目 prod-app-001,父文件夹 prod,父组织 example.com。
  2. 沿路径向上收集所有IAM绑定:存储桶级 → 项目级 → prod 文件夹级 → 组织级。
  3. 检查开发人员是否出现在任何一层的绑定中,且角色包含 storage.objects.get 权限。
  4. 如果组织层给全体成员授予了 roles/viewer,而该角色包含存储对象查看权限,那么即使项目层没有显式绑定,开发人员依然能读取——这就是继承带来的“隐式权限”。

对应的gcloud命令可以快速拉取某资源上的有效策略:

gcloud projects get-iam-policy prod-app-001 \
  --format=json | jq '.bindings[] | select(.members[] | contains("developer"))'

gcloud resource-manager folders get-iam-policy FOLDER_ID \
  --format=json

通过逐层检查,你能明确权限来源,而不是盲目地在项目层反复加绑定。这种“沿树溯源”的排查方法,是后续做环境隔离和最小权限治理的基础技能。

五、治理模型的核心原则

总结本节要点,可以归纳为四条原则:

  • 层级即边界:文件夹是环境隔离的第一道墙,项目是资源归属的最小单元,不要把所有东西塞进一个项目。
  • 继承即累积:权限只增不减,子节点无法拒绝父节点授予的权限,限制必须靠组织策略。
  • 绑定在高层,例外在低层:通用权限尽量在文件夹或组织层授予,项目层只处理例外和精细化调整。
  • IaC按树组织:Terraform目录结构、state文件、变量作用域都应与资源层级对齐,让代码结构反映治理结构。

掌握这棵树和它的继承规则后,你就能在设计IaC时提前规划好“资源放哪、权限给谁、边界在哪”,而不是等资源创建完再补权限、补隔离。这是Google Cloud环境治理的起点,也是后续所有章节的模型基础。