Multi-Cloud: Azure & GCP

GCP Fundamentals

18 min Lesson 5 of 28

GCP Fundamentals

Google Cloud Platform is architected around a resource hierarchy that is meaningfully different from AWS and Azure. Before you touch a single VM or bucket, you need to internalize Organizations, Folders, Projects, and IAM — because getting this wrong at the start causes permission sprawl, audit failures, and billing surprises that are painful to unwind at scale. This lesson gives you the mental model that Google SREs and enterprise customers use on day one.

The GCP Resource Hierarchy

Every GCP resource belongs to exactly one Project. Projects are the fundamental unit of ownership: they carry their own billing account, API enablements, and IAM policies. Above projects sit Folders (optional, but essential at enterprise scale), which group projects into business units or environments. At the root sits the Organization — tied to a Google Workspace or Cloud Identity domain and required for any serious production deployment.

The hierarchy is not just organisational tidiness — it is how IAM inheritance works. A role granted on a Folder propagates down to every Project inside it. A role granted on the Organization propagates to everything. This top-down inheritance is the primary mechanism Google-scale companies use to enforce least-privilege without managing hundreds of individual project policies.

GCP Resource Hierarchy: Organization, Folders, Projects Organization example.com (domain-bound) Folder: Engineering Inherits Org IAM policies Folder: Finance Inherits Org IAM policies Folder: Production Folder: Staging Project: api-prod-8a3f Project: data-prod-c19e Project: billing-svc-d7b2 IAM roles inherit downward
GCP resource hierarchy — IAM policies set at a higher level automatically apply to all child resources below it.
Project IDs are globally unique and immutable. When you create a project, GCP assigns a Project ID (e.g., api-prod-8a3f) that can never be changed and is unique across all of GCP. The Project Name is human-readable and mutable. Always derive your Project ID from a pattern like {team}-{env}-{short-hash} — never rely on auto-generated names in IaC.

Setting Up the Hierarchy with gcloud

In practice, Organizations and Folders are provisioned via the Google Cloud Console or Terraform — they require domain verification and the resourcemanager.googleapis.com API. Projects, however, are the daily operational unit and are created frequently. The gcloud CLI is the canonical tool.

# Authenticate and set a default project gcloud auth login gcloud config set project api-prod-8a3f # List your organization ID (required for folder/project creation at org scope) gcloud organizations list # Create a folder under the organization (requires resourcemanager.folders.create) gcloud resource-manager folders create \ --display-name="Engineering" \ --organization=123456789012 # Create a sub-folder under Engineering (use folder ID from previous output) gcloud resource-manager folders create \ --display-name="Production" \ --folder=987654321098 # Create a project inside the Production folder gcloud projects create api-prod-8a3f \ --name="API Service Production" \ --folder=111222333444 # Link a billing account to the new project (mandatory before any resources) gcloud billing projects link api-prod-8a3f \ --billing-account=XXXXXX-YYYYYY-ZZZZZZ # Enable required APIs in the new project gcloud services enable \ compute.googleapis.com \ container.googleapis.com \ secretmanager.googleapis.com \ --project=api-prod-8a3f
Billing account linking is not optional. A project without a linked billing account cannot create most paid resources — but it can create IAM policies and enable APIs, which can lead to confusing failures later. Always link billing as part of project bootstrap. In Terraform, use the google_billing_project_info resource immediately after google_project.

IAM on GCP: How It Differs from AWS and Azure

GCP IAM uses three concepts: Members, Roles, and Bindings. A binding attaches a role to a member on a specific resource. Members can be Google accounts, service accounts, Google Groups, Cloud Identity domains, or the special allUsers / allAuthenticatedUsers principals.

The most important distinction from AWS: GCP has no inline policies. There are only predefined roles (Google-managed), basic roles (Owner/Editor/Viewer — never use in production), and custom roles (fine-grained, org- or project-scoped). Every permission check is additive: deny policies exist but are an advanced feature; the default is allow-by-absence, meaning a principal with no binding has no access.

GCP IAM: Members, Roles, Bindings, and inheritance scope Member (Principal) user:dev@example.com serviceAccount:ci-runner group:backend-team domain:example.com binding Role roles/container.developer roles/storage.objectAdmin roles/secretmanager.accessor (custom: roles/org/ciDeploy) on resource Scope (Resource) Organization Folder Project Individual Resource Roles propagate: Org → Folder → Project → Resource (additive, no override)
GCP IAM binding model — a member gets a role at a specific scope; higher scopes inherit downward.

IAM in Practice: Service Accounts and Workload Identity

In GCP, applications authenticate as Service Accounts — special identities that represent a workload rather than a human. Unlike AWS IAM roles (which are assumed via STS), GCP service accounts are resources: they have their own email address (name@project-id.iam.gserviceaccount.com) and can be granted roles just like any user.

# Create a service account for the CI runner gcloud iam service-accounts create ci-runner \ --display-name="CI/CD Runner" \ --project=api-prod-8a3f # Grant it the Container Developer role on the project gcloud projects add-iam-policy-binding api-prod-8a3f \ --member="serviceAccount:ci-runner@api-prod-8a3f.iam.gserviceaccount.com" \ --role="roles/container.developer" # Grant it Secret Accessor on a SPECIFIC secret (resource-level binding — preferred) gcloud secrets add-iam-policy-binding db-password \ --project=api-prod-8a3f \ --member="serviceAccount:ci-runner@api-prod-8a3f.iam.gserviceaccount.com" \ --role="roles/secretmanager.secretAccessor" # View the full IAM policy on the project (audit this regularly) gcloud projects get-iam-policy api-prod-8a3f --format=yaml
Workload Identity Federation over service account keys: Never download service account JSON key files for workloads running inside GCP (GKE, Cloud Run, Compute Engine). Instead, attach the service account to the resource directly — the metadata server handles credential rotation automatically. For GitHub Actions or external CI, use Workload Identity Federation (OIDC token exchange) rather than a static key. Static keys are a top-5 GCP security incident cause.

Org-Level Policy Constraints

Beyond IAM, GCP provides Organization Policy constraints — guardrails enforced at the Org or Folder level that override project-level settings. Common production constraints include: disabling public IPs on VMs (compute.vmExternalIpAccess), restricting which regions resources can be created in (gcp.resourceLocations), and requiring OS Login (compute.requireOsLogin). These are enforced even if a project owner tries to bypass them — critical for compliance and cost control at scale.

Think of Org Policies as SCPs in AWS or Azure Policy assignments. They are preventative controls — even an Owner cannot violate them. Set them at the Folder level for environment-specific rules (e.g., no external IPs in Production) and at the Org level for company-wide mandates (e.g., restrict to EU regions for GDPR). Define them in Terraform from day one so they are version-controlled and auditable.

Production Failure Modes

The most common GCP IAM mistakes seen in production: granting roles/editor to a service account instead of narrowly scoped predefined roles; creating all resources in a single project instead of segregating environments; missing billing account links that cause silent API failures; and relying on service account key files that rotate manually (or never). A well-designed GCP hierarchy with Workload Identity, least-privilege predefined roles, and Org Policy constraints eliminates the majority of these incidents before they reach production.

ES
Edrees Salih
1 hour ago

We are still cooking the magic in the way!