Google Cloud Project
The google_project resource provisions sandboxed Google Cloud projects for lab environments. It creates controlled GCP projects with user management, service account access, and API restrictions suitable for educational and training purposes.
Use Cases
Section titled “Use Cases”As a lab author, you can use google_project resources to:
- GCP Training Labs: Create realistic Google Cloud environments for hands-on cloud training and certification preparation
- Service-Specific Learning: Restrict access to specific Google Cloud APIs for focused learning experiences
Google Cloud project resources provide realistic cloud environments while maintaining educational control and cost management.
HCL Syntax
Section titled “HCL Syntax”Basic Syntax
Section titled “Basic Syntax”resource "google_project" "name" { regions = ["us-central1"] services = ["compute.googleapis.com", "storage.googleapis.com"]
user "student" { roles = ["roles/editor"] }}Full Syntax
Section titled “Full Syntax”resource "google_project" "name" { regions = ["us-central1", "europe-west1"] services = ["compute.googleapis.com", "storage.googleapis.com", "container.googleapis.com"]
labels = { environment = "training" purpose = "lab" team = "education" }
user "admin" { roles = ["roles/owner", "roles/iam.securityAdmin"] }
user "developer" { roles = ["roles/editor"] }
service_account "automation" { roles = ["roles/viewer", "roles/editor"] }}Fields
| Field | Type | Required | Description |
|---|---|---|---|
services | list(string) | ✓ | Enable specific GCP APIs (e.g., 'compute.googleapis.com', 'storage.googleapis.com'). At least one service is required. Constraintsat least one service must be specified |
regions | list(string) | ✓ | Limit resource provisioning to specific GCP regions (e.g., 'us-central1', 'europe-west1'). At least one region is required. Constraintsat least one region must be specified |
labels | map(string) | — | Add metadata labels to organize and track GCP resources (e.g., 'env: staging') |
user | block | — | Define GCP users with specific IAM roles for lab participantsrepeatable Constraintsat least one user must be specified |
service_ | block | — | Define service accounts for application authentication with specific IAM rolesrepeatable |
service_ | block | — | One block per service, named by its service ID. Each service block must also be listed in services. |
User
Cloud users to create in the GCP project
| Field | Type | Required | Description |
|---|---|---|---|
slug | label | — | Unique identifier for the GCP user (e.g., 'alice', 'developer') |
roles | list(string) | ✓ | Assign IAM roles to the user (e.g., 'roles/viewer', 'roles/editor') Constraintsuser must have at least one role assigned |
Service Account
Service accounts to create in the GCP project
| Field | Type | Required | Description |
|---|---|---|---|
slug | label | — | Unique identifier for the service account (e.g., 'app-backend', 'automation') |
roles | list(string) | ✓ | Assign IAM roles to the service account (e.g., 'roles/storage.admin') Constraintsservice account must have at least one role assigned |
Service Limits
Restrictions on the services listed in services
| Field | Type | Required | Description |
|---|---|---|---|
aiplatform | block | — | Only the listed models can be invoked |
Vertex AI
Vertex AI models learners may invoke, with optional token limits per model
| Field | Type | Required | Description |
|---|---|---|---|
model | block | — | Learners can invoke only the models listed hererepeatable |
Model
A model learners may invoke
| Field | Type | Required | Description |
|---|---|---|---|
slug | label | — | Any name, unique within the service block |
name | string | ✓ | For example 'publishers/google/models/gemini-2.5-flash' |
input_ | number | — | Input tokens a session may use on this model ConstraintsMinimum 1 |
output_ | number | — | Output tokens a session may use on this model ConstraintsMinimum 1 |
Computed Attributes
These attributes are set by the system and are read-only.
| Attribute | Type | Description |
|---|---|---|
project_id | string | The GCP project ID assigned to this sandbox |
project_name | string | The GCP project name assigned to this sandbox |
user[].email | string | The email address assigned to this user |
user[].password | string | The password for this user |
service_account[].email | string | The email address of this service account |
service_account[].key | string | The JSON key for this service account |
User Block
Section titled “User Block”google_project → user
User blocks define Google Cloud users to create within the project:
| Field | Required | Type | Description |
|---|---|---|---|
name | ✓ | label | Username for the Google Cloud user (specified as block label) |
roles | ✓ | list(string) | Google Cloud IAM roles to assign to the user. |
Service Account Block
Section titled “Service Account Block”google_project → service_account
Service account blocks define Google Cloud service accounts for application authentication:
| Field | Required | Type | Description |
|---|---|---|---|
name | ✓ | label | Name for the Google Cloud service account (specified as block label) |
roles | list(string) | Google Cloud IAM roles to assign to the service account. Defaults to empty list. |
User Computed Attributes
Section titled “User Computed Attributes”For each user block, these attributes are computed:
| Field | Type | Description |
|---|---|---|
email | string | The user’s Google Cloud email address |
password | string | The user’s password for Google Cloud Console access |
Service Account Computed Attributes
Section titled “Service Account Computed Attributes”For each service_account block, these attributes are computed:
| Field | Type | Description |
|---|---|---|
email | string | The service account email address |
key | string | The service account private key in JSON format |
Service Limits Block
Section titled “Service Limits Block”google_project → service_limits
The service_limits block lists the Vertex AI models users can call in the project, with optional token limits for each model. Its fields are listed under Service Limits.
resource "google_project" "ai_lab" { regions = ["us-central1"] services = ["aiplatform.googleapis.com"]
service_limits { aiplatform { model "gemini" { name = "publishers/google/models/gemini-3.5-flash" input_token_count = 1000000 } } }
user "student" { roles = ["roles/aiplatform.user"] }}- One block per service:
service_limitsholds one block per service, named after the service without.googleapis.com, because block names can’t contain dots.aiplatform(Vertex AI) is the only service block agoogle_projectaccepts; any other fails validation withunknown block. - Listed in services: The service must also be in
services. Anaiplatformblock without"aiplatform.googleapis.com"inservicesfails withservice_limits: aiplatform.googleapis.com: not listed in services. - Empty service block: An
aiplatformblock withoutmodelblocks validates but restricts nothing. Users can call any Vertex AI model the project allows. - Model label: The label, such as
"gemini", is your own name for the entry. It must be unique within the service block and doesn’t have to match the model. - Model ID:
nameis the Vertex AI model ID, and it must be a model Instruqt supports. Any other ID fails withunknown model "<id>" for service "aiplatform.googleapis.com", and the error lists the supported model IDs. - Token limits:
input_token_countandoutput_token_countare optional. Each must be a whole number of at least 1. A model without them has no token limit.
Examples
Section titled “Examples”Basic GCP Training Environment
Section titled “Basic GCP Training Environment”resource "google_project" "training" { regions = ["us-central1"] services = ["compute.googleapis.com", "storage.googleapis.com", "container.googleapis.com"]
labels = { environment = "training" course = "gcp-fundamentals" }
user "student" { roles = ["roles/editor"] }}
output "student_credentials" { value = { email = resource.google_project.training.user.0.email # e.g., "student@training-project.iam.gserviceaccount.com" password = resource.google_project.training.user.0.password # e.g., "TempPass123!" project_id = resource.google_project.training.project_id # e.g., "training-project-abc123" } sensitive = true}Multi-User Workshop Environment
Section titled “Multi-User Workshop Environment”resource "google_project" "workshop" { regions = ["us-central1", "europe-west1"] services = [ "compute.googleapis.com", "storage.googleapis.com", "container.googleapis.com", "cloudsql.googleapis.com", "monitoring.googleapis.com" ]
labels = { environment = "workshop" event = "gcp-solutions-architect-training" instructor = "jane-doe" }
# Instructor with full access user "instructor" { roles = ["roles/owner", "roles/iam.securityAdmin"] }
# Student with controlled permissions user "student" { roles = ["roles/editor"] }
# Observer with read-only access user "observer" { roles = ["roles/viewer"] }
# Service account for automation service_account "automation" { roles = ["roles/editor", "roles/container.admin"] }}Service Account Integration Lab
Section titled “Service Account Integration Lab”resource "google_project" "automation_lab" { regions = ["us-central1"] services = [ "compute.googleapis.com", "storage.googleapis.com", "cloudbuild.googleapis.com" ]
labels = { environment = "automation-lab" technology = "service-accounts" level = "advanced" }
user "developer" { roles = ["roles/editor"] }
service_account "ci_cd" { roles = ["roles/editor", "roles/cloudbuild.builds.editor"] }
service_account "monitoring" { roles = ["roles/monitoring.viewer", "roles/logging.viewer"] }}
resource "container" "gcloud_cli" { image { name = "gcr.io/google.com/cloudsdktool/cloud-sdk:alpine" }
environment = { GOOGLE_APPLICATION_CREDENTIALS = "/tmp/service-account.json" GOOGLE_CLOUD_PROJECT = resource.google_project.automation_lab.project_id # e.g., "automation-lab-xyz789" }
volume { source = "./service-account.json" destination = "/tmp/service-account.json" type = "bind" read_only = true }}Template Integration
Section titled “Template Integration”resource "google_project" "gcp_lab" { regions = ["us-central1"] services = ["compute.googleapis.com", "storage.googleapis.com"]
user "student" { roles = ["roles/editor"] }
service_account "app" { roles = ["roles/viewer"] }}
resource "template" "service_account_key" { source = resource.google_project.gcp_lab.service_account.0.key # JSON service account key destination = "./service-account.json"}
resource "template" "gcloud_auth" { source = <<-EOF #!/bin/bash # Authenticate with service account gcloud auth activate-service-account \ --key-file=./service-account.json \ --project=${resource.google_project.gcp_lab.project_id}
# Set default project gcloud config set project ${resource.google_project.gcp_lab.project_id}
# Verify authentication gcloud auth list gcloud projects describe ${resource.google_project.gcp_lab.project_id} EOF
destination = "./gcloud-auth.sh"}
resource "template" "lab_info" { source = <<-EOF # Google Cloud Lab Environment
## Project Details - Project ID: ${resource.google_project.gcp_lab.project_id} # e.g., "lab-project-abc123" - Project Name: ${resource.google_project.gcp_lab.project_name} # e.g., "Lab Project ABC123"
## User Credentials - Email: ${resource.google_project.gcp_lab.user.0.email} # e.g., "student@lab-project.iam.gserviceaccount.com" - Password: ${resource.google_project.gcp_lab.user.0.password} # e.g., "TempPass123!"
## Service Account - Email: ${resource.google_project.gcp_lab.service_account.0.email} # e.g., "app@lab-project.iam.gserviceaccount.com" - Key File: ./service-account.json EOF
destination = "./lab-info.md"}Multi-Region Development Environment
Section titled “Multi-Region Development Environment”resource "google_project" "global_dev" { regions = [ "us-central1", # Iowa "europe-west1", # Belgium "asia-southeast1" # Singapore ]
services = [ "compute.googleapis.com", "storage.googleapis.com", "container.googleapis.com", "cloudsql.googleapis.com", "cloudresourcemanager.googleapis.com" ]
labels = { environment = "multi-region-dev" purpose = "global-architecture-training" duration = "3-days" }
user "architect" { roles = ["roles/editor"] }
service_account "deployment" { roles = ["roles/editor", "roles/container.admin"] }}IAM Role Management Lab
Section titled “IAM Role Management Lab”resource "google_project" "iam_lab" { regions = ["us-central1"] services = ["compute.googleapis.com", "storage.googleapis.com", "iam.googleapis.com"]
labels = { environment = "iam-training" focus = "access-management" }
# Different users with different permission levels user "owner_user" { roles = ["roles/owner"] }
user "editor_user" { roles = ["roles/editor"] }
user "viewer_user" { roles = ["roles/viewer"] }
user "compute_admin" { roles = ["roles/compute.admin"] }
user "storage_admin" { roles = ["roles/storage.admin"] }
# Service accounts for different scenarios service_account "backup_service" { roles = ["roles/storage.objectAdmin"] }
service_account "monitoring_service" { roles = ["roles/monitoring.viewer", "roles/logging.viewer"] }}Kubernetes Engine Lab
Section titled “Kubernetes Engine Lab”resource "google_project" "k8s_lab" { regions = ["us-central1"] services = [ "compute.googleapis.com", "container.googleapis.com", "containerregistry.googleapis.com" ]
labels = { environment = "kubernetes-lab" technology = "gke" level = "intermediate" }
user "k8s_admin" { roles = [ "roles/container.admin", "roles/compute.viewer", "roles/storage.admin" ] }
service_account "gke_node" { roles = [ "roles/logging.logWriter", "roles/monitoring.metricWriter", "roles/monitoring.viewer" ] }}
resource "template" "kubectl_config" { source = <<-EOF #!/bin/bash # Set up kubectl context gcloud container clusters get-credentials lab-cluster \ --zone=us-central1-a \ --project=${resource.google_project.k8s_lab.project_id}
# Verify connection kubectl cluster-info kubectl get nodes EOF
destination = "./setup-kubectl.sh"}Terraform Integration
Section titled “Terraform Integration”resource "google_project" "terraform_lab" { regions = ["us-central1"] services = [ "compute.googleapis.com", "storage.googleapis.com", "cloudresourcemanager.googleapis.com" ]
user "terraform_user" { roles = ["roles/editor"] }
service_account "terraform" { roles = ["roles/editor", "roles/storage.admin"] }}
resource "template" "terraform_vars" { source = <<-EOF # terraform.tfvars project_id = "${resource.google_project.terraform_lab.project_id}" # e.g., "terraform-lab-def456" region = "us-central1" zone = "us-central1-a"
# Service account for Terraform service_account_email = "${resource.google_project.terraform_lab.service_account.0.email}" # e.g., "terraform@terraform-lab.iam.gserviceaccount.com" EOF
destination = "./terraform.tfvars"}Best Practices
Section titled “Best Practices”- Principle of Least Privilege: Assign only the minimum roles required for the lab objectives
- API Restrictions: Enable only the Google Cloud APIs essential for the learning experience
- Regional Constraints: Restrict regions to control costs and simplify the environment
- Role Separation: Use different users and service accounts for different lab scenarios
- Service Account Keys: Manage service account keys securely and rotate them regularly
- Cost Controls: Monitor resource usage and implement appropriate quotas and limits
- Labeling Strategy: Use consistent labels for cost tracking and resource management
- Credential Security: Mark credential outputs as sensitive and manage access carefully
