devops-exercises 实战指南:在 GCP 上创建唯一命名的项目(Console 与 Terraform 双方案)
devops-exercises 实战指南:在 GCP 上创建唯一命名的项目(Console 与 Terraform 双方案)
本篇技术指南围绕开源仓库 devops-exercises 中 GCP 板块的第一个练习——"Create a Project"展开,完整讲解如何通过 Google Cloud Console 与 Terraform(HashiCorp 官方 google provider)两种方式创建具有全局唯一名称的 GCP 项目,并深入剖析项目在 GCP 资源层级(Organization → Folder → Project → Resources)中的定位、命名约束与后续 IAM、计算资源挂载方式。读完本文,你将掌握一套可直接复制运行的 GCP 项目初始化流程,并能在该仓库配套的 Terraform 配置基础上继续扩展 VPC、实例等资源。
练习目标与本仓库中的定位
该练习位于 topics/gcp/exercises/create_project/exercise.md,目标只有一个:创建一个具有唯一名称的项目(Create a project with a unique name)。对应的完整解答位于 topics/gcp/exercises/create_project/solution.md。
它被收录在 topics/gcp/README.md 的 "Account Setup" 练习表中,是 GCP 学习路径的起点:在创建任何 Compute Engine 实例、VPC、存储桶之前,必须先拥有一个项目作为资源容器。后续的 Assign roles(IAM 角色分配) 与 Create an instance(创建实例) 练习,都默认你已完成了项目创建这一步。
为什么"唯一名称"如此关键:GCP 资源层级
在动手之前,先理解项目在 GCP 中的位置。根据 topics/gcp/README.md 的 "Resource Hierarchy" 问答,GCP 的资源层级自上而下为:
Organization(组织)
Folder(文件夹)
Project(项目)
Resources(资源)
- Organization:对应整个公司/企业实体;
- Folder:通常用于部门、团队或产品线分组;
- Project:可以是不同的项目,也可以是同一项目的不同环境(dev、staging、production);
- Resources:项目内实际使用的 GCP 服务(Compute、App Engine、Storage 等)。
仓库问答中明确了两条关键事实:
- 项目名称必须全局唯一(globally unique)——在同一个 GCP 组织甚至全局范围内,项目名称不可重复,这是"创建唯一命名项目"这一练习背后的硬性约束;
- 一个资源必须隶属于至少一个项目——GCP 中不存在脱离项目的裸资源,因此项目是资源管理的边界与计费、权限控制的基本单位。
了解这一点后,再来看"可选组织 / 可选文件夹"这两个创建选项:把项目挂到 Organization 下并使用 Folder 归类,正是为了让后续的 IAM 策略(父级策略会覆盖子级策略)与资源治理在层级上生效。
方式一:通过 Google Cloud Console 图形化创建
按照 solution.md 的步骤,在浏览器中完成创建:
- 点击顶部工具栏的 "New Project"(如果你已有项目,先点击当前项目名称,再点击 "New Project");也可以在顶部搜索栏直接输入 "Create Project" 进入创建页面;
- 输入一个全局唯一的项目名称——这是本练习的核心要求,若名称与现有项目冲突,GCP 会拒绝创建;
- (可选)选择一个 Organization,将项目纳入组织层级;
- (可选)将项目放入特定的 Folder,便于按部门/环境归类;
- 点击 "Create",等待项目创建完成(通常需数十秒)。
创建完成后,可在控制台项目选择器中看到该项目,并可将其设为当前工作项目。
方式二:通过 Terraform 声明式创建(本仓库推荐)
Console 适合一次性操作;若要让项目创建可复现、可纳入 Git 版本管理,仓库提供了完整的 Terraform 声明式方案。
2.1 项目资源定义:main.tf
核心配置位于 topics/gcp/exercises/create_project/main.tf:
resource "google_project" "gcp_project" {
name = "Some Project"
project_id = "some-unique-project-id"
folder_id = google_folder.some_folder.name
}
resource "google_folder" "some_folder" {
display_name = "Department 1"
parent = "organizations/some-organization"
}
逐项解读参数:
google_project.gcp_project——GCP 项目资源:name:项目的显示名称(对应 Console 中的"项目名称"),如 "Some Project";project_id:项目的唯一标识符(ID),本例为 "some-unique-project-id"。project_id 与 name 一样必须全局唯一,且一经创建不可修改,只能重建;它同时也是后续gcloud、gsutil、API 调用中引用项目的标识;folder_id:将项目挂载到某个文件夹下(对应 Console 第 4 步的可选项)。这里通过google_folder.some_folder.name引用下方声明的文件夹资源的名称属性,实现资源间依赖——Terraform 会先创建文件夹,再创建项目。
google_folder.some_folder——文件夹资源:display_name:文件夹显示名(如 "Department 1",可对应某个部门);parent:文件夹的上级,格式为organizations/<organization-id>。若当前账号属于组织some-organization,则需替换为真实的组织 ID。
2.2 版本约束:versions.tf
配套的 topics/gcp/exercises/create_project/versions.tf 声明了运行环境的最低要求:
terraform {
required_version = ">=1.3.0"
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.10.0, < 5.0"
}
}
}
required_version = ">=1.3.0":需要 Terraform 1.3.0 及以上版本;googleprovider:官方源hashicorp/google,版本范围>= 4.10.0且< 5.0(即 4.x 系列)。超出该范围的 provider 版本可能引入参数或行为的兼容性差异。
2.3 运行流程
在 topics/gcp/exercises/create_project 目录下依次执行:
terraform init # 拉取 google provider 插件
terraform plan # 预览将要创建的项目与文件夹
terraform apply # 应用变更,创建 GCP 项目
执行 apply 前需确保:
- 本地已通过
gcloud auth application-default login或环境变量配置好 GCP 凭据,且账号拥有创建项目所需的权限; - 若使用了
organizations/<organization-id>,该账号需在对应组织下具有创建文件夹与项目的权限; - 项目创建后如需删除,应通过
terraform destroy或控制台执行,避免残留孤立的 IAM 绑定与资源。
方式三:结合 gcloud CLI 的日常管理
虽然该练习的解法只提供了 Console 与 Terraform 两条路径,但仓库中同板块的后续练习展示了 gcloud 命令在项目维度的实际用法,可作为项目创建后的补充。在 topics/gcp/exercises/instance_101/solution.md 中,创建实例前先要指定工作项目与默认区域:
gcloud config set project <PROJECT_ID>
gcloud config set compute/region <REGION NAME>
gcloud config set compute/zone <ZONE NAME>
其中 <PROJECT_ID> 即上文 Terraform 中 project_id 的值。此外,topics/gcp/README.md 也收录了资源查询类命令,例如:
gcloud compute regions list # 列出所有可用区域,供选择部署区域
这些命令与 Console/Terraform 互为补充:Terraform 负责"声明与落地",gcloud 负责"切换与查询",二者配合可覆盖项目生命周期的大部分场景。
从源码结构看:项目是后续所有 GCP 练习的前置依赖
从仓库目录结构可以推断,GCP 板块的练习存在明显的递进关系,"创建项目"被刻意安排在首位:
- 完成项目创建后,assign_roles/main.tf 通过
google_project_iam_member资源在project = "${var.project_id}"上绑定 IAM 角色(如roles/compute.storageAdmin、roles/compute.networkAdmin、roles/compute.securityAdmin),这正是"资源必须隶属项目、策略挂载在项目之上"的落地体现; - 再往后,instance_101 才会在项目内创建带标签的 e2-micro 虚拟机。
因此,把这套 google_project + google_folder 配置固化为团队的基础设施模板,可以让每位成员的云账号启动成本降至最低,并保证所有项目统一挂在组织层级之下,便于统一实施 IAM 策略与审计。
常见问题与注意事项汇总
- 名称冲突:GCP 项目名称与 project_id 均为全局唯一,创建前可通过
gcloud projects list或控制台搜索确认未被占用; - project_id 不可变更:一旦创建成功,project_id 即固定,所有 API、SDK、命令行引用都依赖它,规划阶段应慎重命名;
- 组织与文件夹为可选项:个人账号/非组织场景可跳过
parent与folder_id,直接创建"无父级"的项目;但加入组织后,IAM 父级策略会作用于其下所有项目; - provider 版本边界:本仓库配置锁定 google provider 为 4.x(
< 5.0),升级主版本前应查阅官方升级指南并回归验证google_project与google_folder的参数行为; - 权限要求:Console 方式要求账号有
resourcemanager.projects.create权限;Terraform 方式还需组织级resourcemanager.folders.create权限(若使用 Folder 参数)。
小结
围绕 devops-exercises 的 "Create a Project" 练习,本文完整还原了 Console 的 5 步操作,并基于仓库内的 main.tf 与 versions.tf 深入讲解了 google_project、google_folder 的核心参数、版本约束与运行流程。结合 topics/gcp/README.md 的资源层级问答可以确认:项目名称全局唯一是 GCP 的硬性约束,项目是组织、文件夹与具体资源之间的关键纽带。把这份 Terraform 模板纳入版本管理,即可在团队中复用地完成"唯一命名 + 组织归类"的标准化项目初始化,为后续的 IAM 授权与实例部署打下坚实基础。