GCP Lesson 97 of 98

Real-World Google Cloud Portfolio Projects: From a Static Site to a Landing Zone

In a nutshell

Think of a portfolio as the cloud engineer’s version of a chef’s tasting menu. A certificate says you passed a cooking exam; a portfolio is a set of dishes the hiring manager can actually taste. On Google Cloud, “a dish” means a small, real, working system you built and put on GitHub for anyone to inspect — the code, an architecture diagram, a note on what it costs, and a one-command way to build it and tear it down. That is the single most persuasive thing you can show, because it turns “I know GCP” (a claim) into “here, look” (proof).

This lesson is a ladder of six such projects, arranged from easy to hard. The bottom rung is a plain website, shipped the professional way — automated, no clicking around a console. Each rung up adds one new muscle an interviewer at the next seniority level expects you to have: writing application code, moving streams of data, running containers, operating a live service, and finally building the governed foundation a whole company runs on. The lower rungs get you a first cloud job; the higher rungs are what senior, platform, and architect interviews are really testing for. That is what “escalates from starter to senior-signal” means in practice — the same GitHub profile can say “safe junior hire” or “can build our platform,” depending on how high you climb.

You do not need to climb all six to benefit. Three finished, well-presented projects beat six half-built ones every time. Pick the rung that matches the role you want plus the one just below it, build them properly, write them up the way this lesson shows, and you will walk into interviews carrying something roughly nine in ten candidates never bring: evidence.

Level: Beginner → Advanced (it’s a ladder) · Time: ~36 min read · Cost: the Free Tier plus the $300 trial credit cover projects 1–5; you need only a Google Cloud account and a GitHub account to start.

Two candidates apply for the same mid-level Google Cloud role. Both list the same certifications — Associate Cloud Engineer, maybe a Professional Cloud Architect in progress. The first attaches a CV that says “experienced with Compute Engine, Cloud Storage, Cloud Run, and IAM.” The second attaches a GitHub profile with six pinned repositories: a static site with a real CI/CD pipeline, a serverless API with tests, a streaming data pipeline feeding a live dashboard, a containerised microservices app on GKE Autopilot, an observability stack with SLOs and burn-rate alerts, and a Terraform-built landing zone with an organisation hierarchy, Shared VPC, and Org Policy guardrails — each with a tidy README, an architecture diagram, a cost note, and a teardown script. As the hiring manager, you have read perhaps forty CVs that morning. Which of these two do you phone first? The answer is not close, and it is the entire reason this lesson exists.

Certifications prove you can recognise the right answer in a multiple-choice question. A portfolio proves you can build the thing. Those are different skills, and interviewers know it. A certification is a filter that gets your CV past the first screen; a portfolio is the evidence that survives the technical interview, because the questions stop being “what does Cloud CDN do?” and become “walk me through your CDN setup — why a global external Application Load Balancer and not just a bucket website? how does your cache invalidate on deploy? what did it cost?” You can only answer those crisply if you have actually shipped it. This article gives you six projects, deliberately arranged as a hiring ladder — each one a rung harder, each mapping to a tier of Google Cloud roles and certifications — so that by the time you finish the sixth you are not “studying GCP,” you are demonstrably a Google Cloud engineer.

The ladder is designed so the projects compound. Project 1 teaches you Infrastructure as Code and CI/CD on the gentlest possible surface. Project 2 adds application logic and a managed serverless database. Project 3 introduces streaming data, analytics, and visualisation — the discipline that pays the best on GCP. Project 4 brings containers, Kubernetes, and keyless identity. Project 5 makes all of it observable and operable — the difference between a demo and production. Project 6 is the platform-engineering capstone that puts everything inside a governed organisation with a Shared VPC, which is where senior, platform, and architect roles live. You do not have to build all six to get hired — three good ones will land you an associate-level role — but the higher you climb, the more senior the conversations you can hold.

Learning objectives

By the end of this lesson you will be able to:

Prerequisites

You should be comfortable with the Google Cloud fundamentals, the IAM model (roles, the allow policy and inheritance, service accounts), and basic VPC networking — the earlier rungs of this course cover all three. You will need a Google Cloud account (the Free Tier plus the $300, 90-day free trial credit comfortably covers projects 1–5; project 6 benefits from a fresh organisation, which you get free with a Cloud Identity or Google Workspace domain), the Google Cloud CLI (gcloud, which bundles gsutil and bq), Terraform, Git, and a GitHub account. A little familiarity with one programming language — Python, Go, or Node.js are the most portable choices for Cloud Run and Cloud Functions — will carry you through projects 2, 3, and 5. None of the projects require paid third-party tooling; everything here uses the free tiers of Google Cloud and GitHub.

This lesson sits in the Career module of the Google Cloud Zero-to-Hero course, immediately after the architecture ladder (which teaches the designs); here you build and present them. It pairs naturally with the certification prep kit that follows it and with the capstone, which takes project 6 to full production depth.

The portfolio ladder: how the six projects map to roles and certs

Before the projects themselves, internalise the shape of the ladder. Each rung adds a capability that an interviewer at the next seniority tier expects you to have touched. The table below is the map; treat the “Hiring signal” column as the sentence a reviewer says to themselves when they see the repo.

# Project Core new capability Targets role Maps to cert Hiring signal
1 Static site + CI/CD IaC + automated deploys Junior / Cloud Support Cloud Digital Leader, ACE “Knows IaC, doesn’t click in the console”
2 Serverless API App logic + managed NoSQL + tests Associate / Developer ACE, PCA “Can build a real serverless backend”
3 Streaming data pipeline Ingest → process → warehouse → BI Data Engineer PDE, ACE “Thinks in pipelines, ships analytics”
4 GKE microservices Kubernetes, Gateway API, keyless identity Associate / DevOps ACE, PCA, DevOps “Comfortable with containers and K8s networking”
5 Observability / SRE Operability, SLOs, burn-rate alerts DevOps / SRE DevOps, ACE “Operates systems, not just deploys them”
6 Landing zone Governance, org-scale identity, platform IaC Senior / Platform / Architect PCA, Security Engineer “Can build the foundation other teams land on”

A useful rule of thumb: build the rung that matches the role you want, plus the one below it. Targeting an associate developer role? Projects 1, 2, and 4 tell the strongest story. Targeting a data engineer role? Projects 1, 3, and 5. Targeting DevOps/SRE? Projects 4, 5, and 6. Targeting a solutions-architect or platform role? Projects 4, 5, and 6 again, with 1 as the polished “I know the fundamentals cold” showpiece. Quality beats quantity every time — three excellent, well-documented repos outshine six abandoned ones.

A word on cost discipline, because it is itself a hiring signal: every project below stays on or near the Free Tier and the $300 trial credit, and every one ships with a teardown path (terraform destroy or a documented cleanup). Leaving a regional Cloud SQL instance, a GKE Standard cluster, or a Dataflow job running for a month is exactly the mistake a cost-conscious employer is screening for. Build, screenshot, document, tear down.


Project 1 — Static site with a CI/CD pipeline

In plain terms: you are putting a normal website online — but instead of dragging files into a console, you describe the whole setup in code and let automation deploy it every time you git push. It is the “hello, world” of professional cloud: a trivial app delivered like a grown-up team delivers. That gap — automated versus hand-clicked — is the first thing a reviewer reads off a repo, and it is the junior-versus-amateur line.

The brief. Host a static website (a portfolio page, a blog, or a single-page app build) on Google Cloud so that it is globally fast, served only over HTTPS, and deployed automatically from a Git push — no console clicking, no manual bucket uploads. The whole thing must be defined as code and destroyable with one command. This is the gentlest possible surface on which to prove the two skills every modern cloud role assumes: Infrastructure as Code and CI/CD.

The GCP services.

Service Role in this project
Cloud Storage Backend bucket holding the built site (private; fronted by the load balancer)
Global external Application Load Balancer Global anycast entry point, HTTPS termination, URL maps
Cloud CDN Edge caching on the load balancer’s backend bucket
Google-managed SSL certificate Free, auto-renewing TLS for the custom domain
Cloud DNS DNS for the custom domain (optional but recommended)
Cloud Build CI/CD: build the site, sync to the bucket, invalidate the CDN cache
Workload Identity Federation Keyless auth from GitHub Actions to GCP (no service-account keys)
Terraform Defines every resource above as code

Build outline.

  1. Write the Terraform: a Cloud Storage backend bucket (uniform bucket-level access on, not public), a global external Application Load Balancer (a global forwarding rule → target HTTPS proxy → URL map → backend bucket), Cloud CDN enabled on that backend bucket, a Google-managed SSL certificate, and (optionally) a Cloud DNS A record pointing at the load balancer’s anycast IP. Prefer the LB + CDN path over the bare “bucket website” because it gives you HTTPS, a global anycast IP, CDN, and a clean upgrade path — and it is the more senior choice to defend.
  2. Configure the URL map’s default route to the backend bucket and set the main page suffix (index.html) and a custom 404 on the bucket.
  3. Put your site source in the same repo. Build it (or just use plain HTML for a first pass).
  4. Set up Workload Identity Federation so GitHub Actions can impersonate a deploy service account with no exported key — this is the modern, secure pattern. Write a workflow that, on push to main, authenticates via google-github-actions/auth (Workload Identity), runs the build, gsutil rsyncs the output to the bucket, and runs gcloud compute url-maps invalidate-cdn-cache so visitors see the new version immediately.
  5. Document the architecture, capture a screenshot of a green pipeline run, and add a terraform destroy note.

The GitHub deliverable. A repo containing infra/ (Terraform), the site source, .github/workflows/deploy.yml, an architecture diagram, and a README that explains the LB-and-CDN-over-bucket-website decision, the Workload-Identity-not-keys decision, and the cache-invalidation step. Pin it.

Copy-paste résumé bullet.

Built and deployed a globally distributed static site on Google Cloud (Cloud Storage backend bucket behind a global external Application Load Balancer with Cloud CDN and a Google-managed TLS certificate), defined entirely in Terraform, with a Cloud Build / GitHub Actions CI/CD pipeline authenticating via Workload Identity Federation (zero exported service-account keys) that ships every commit to production in under 3 minutes with automatic CDN invalidation, cutting global page-load latency ~60% versus single-region bucket hosting.

Done when. terraform apply from a clean clone stands the whole thing up; the site loads over HTTPS on the load balancer’s IP or domain; the bucket is not publicly readable (uniform bucket-level access on, no allUsers binding); a push to main turns the GitHub Actions run green and the change is live within a couple of minutes without you touching the console; and terraform destroy removes everything. Screenshot the green pipeline run for the README.


Project 2 — Serverless REST API

In plain terms: you are building the “back office” behind an app — the part that stores and serves data — with no servers to patch or babysit. It answers real HTTP requests, saves them to a database, and has tests that prove it works. This is the first rung that shows you can write software on the cloud, not just wire boxes together.

The brief. Build a working REST API — a URL shortener, a notes/todo service, or a simple bookmarking backend — with no servers to manage. It must persist data, validate input, return proper HTTP status codes, be defined as code, and have automated tests. This proves you can build application logic on GCP, not just wire up infrastructure.

The GCP services.

Service Role in this project
Cloud Run Fully managed container running the API (scales to zero)
Firestore (Native mode) Serverless NoSQL document persistence
API Gateway Managed front door: routing, API keys, request validation, quotas
Artifact Registry Private registry for the container image
IAM service account Least-privilege runtime identity for the Cloud Run service
Cloud Logging & Monitoring Logs, metrics, and a basic alert on the error rate
Cloud Build + Terraform CI to build/push the image; IaC for the whole stack

Build outline.

  1. Model the data for Firestore first — choose collections and document IDs around your main access pattern (e.g. document ID = shortCode for a URL shortener) and decide where you need composite indexes. Design for the query, not the entity.
  2. Write a small containerised service (Python/FastAPI, Go, or Node/Express) implementing the CRUD operations. Keep handlers thin; validate input and return correct status codes (201 on create, 404 on miss, 400 on bad input). Build the image and push it to Artifact Registry.
  3. Deploy to Cloud Run with a dedicated, least-privilege service account (Firestore user on exactly your database, nothing wildcard). Put API Gateway in front for an OpenAPI-defined contract, API keys, and per-key quotas so a runaway client cannot drive your bill up.
  4. Set Cloud Run concurrency, min instances = 0 (scale to zero for cost), and a sane max instances cap. Make the service require authentication (no allUsers) and let API Gateway be the only caller.
  5. Add unit tests for the handlers (mock the Firestore client) and at least one integration test that hits the deployed endpoint. Wire the tests into a GitHub Actions / Cloud Build workflow that runs tests then deploys.
  6. Add a log-based metric and an alerting policy on the 5xx rate. Document the data model and the access patterns.

The GitHub deliverable. A repo with src/ (handlers), tests/, a Dockerfile, the IaC (infra/ Terraform for Cloud Run, Firestore, API Gateway, Artifact Registry, the service account, the alert), a CI workflow that runs tests then deploys, an OpenAPI spec plus a curl examples section in the README, and an architecture diagram. The README should justify the Firestore document-ID design and show example requests/responses.

Copy-paste résumé bullet.

Designed and shipped a serverless REST API on Google Cloud (API Gateway → Cloud Run → Firestore) with a document model tuned to the primary access pattern, a per-service least-privilege IAM service account, OpenAPI request validation with per-key quotas, and a log-based 5xx alerting policy; covered by unit and integration tests in a CI pipeline, scaling to zero at idle (effectively zero idle cost) while sustaining sub-100 ms median latency.

Done when. The API is reachable through API Gateway (not the Cloud Run URL directly), returns correct status codes (201/404/400), and persists data across restarts; the Cloud Run service runs as a dedicated least-privilege service account and is set to --min-instances=0; allUsers cannot invoke Cloud Run directly (only the gateway’s service account can); unit tests plus at least one integration test pass in CI before the deploy step; and an alerting policy exists on the 5xx rate.


Project 3 — Streaming data pipeline with a live dashboard

In plain terms: you are building a conveyor belt for events — clicks, sensor readings, transactions — that flows in continuously, gets cleaned and counted on the way, lands in a warehouse, and shows up on a dashboard you can watch update. This is the thing Google Cloud is most famous for, and the single strongest rung for a data role.

The brief. Build an end-to-end streaming analytics pipeline: events arrive on a message bus, a stream-processing job transforms and enriches them, results land in a data warehouse, and a live dashboard visualises them. This is the project that proves you can do the thing Google Cloud is known for — data and analytics — and it is the strongest single rung for a Data Engineer role.

The GCP services.

Service Role in this project
Pub/Sub The ingestion bus (at-least-once, decoupled, buffered)
Dataflow (Apache Beam) Stream processing: parse, window, enrich, deduplicate
BigQuery Serverless data warehouse (partitioned, clustered tables)
Looker Studio Free BI layer for the live dashboard
Cloud Storage Staging/temp for Dataflow and a raw-events archive
IAM service accounts Least-privilege identities for the pipeline and the job

Build outline.

  1. Create a Pub/Sub topic and subscription for your event stream (e.g. clickstream, IoT readings, or synthetic transactions). Add a small producer (a script or a Cloud Run job) that publishes JSON events.
  2. Write a Dataflow streaming pipeline in Apache Beam (Python or Java). Read from Pub/Sub, apply windowing, parse and validate, and handle late and duplicate data — Pub/Sub is at-least-once, so dedupe on a message attribute or an idempotency key. Route malformed records to a dead-letter path (a separate table or a GCS prefix) rather than failing the job.
  3. Design the BigQuery sink table for cost and speed: partition by ingestion/event date and cluster by your highest-cardinality filter column, so queries scan less and cost less. Use the Storage Write API sink for streaming inserts.
  4. Build a Looker Studio dashboard on the BigQuery table — a couple of time-series charts, a top-N table, and a scorecard. This is the deliverable a non-technical reviewer can see working.
  5. Give the pipeline and the Dataflow worker dedicated, least-privilege service accounts (Pub/Sub subscriber, BigQuery data editor on the one dataset, GCS object admin on the one bucket). Run Dataflow on a private subnet with Private Google Access where you can.
  6. Document the data flow, the windowing and dedupe reasoning, the partition/cluster choice, and a sample query. Note the Dataflow cost lever (it bills for worker time) and drain or cancel the job when not demonstrating.

The GitHub deliverable. A repo with the producer, the Beam pipeline, the BigQuery schema/DDL, the IaC (Pub/Sub, BigQuery dataset/table, GCS, service accounts), a CI workflow, a Looker Studio share link or screenshots, an architecture diagram of the ingest → process → warehouse → BI flow (with the dead-letter branch), and a README explaining at-least-once delivery, windowing, and the partition/cluster design. A screenshot of the live dashboard is the headline artefact.

Copy-paste résumé bullet.

Built a streaming analytics pipeline on Google Cloud (Pub/Sub → Dataflow/Apache Beam → BigQuery → Looker Studio) with windowed, idempotent stream processing and a dead-letter path for malformed events, landing data in date-partitioned, clustered BigQuery tables that cut query bytes-scanned (and cost) ~80%, and surfaced it on a live Looker Studio dashboard refreshed end-to-end in seconds.

Done when. A producer publishes events to Pub/Sub; the Dataflow job reads, windows, de-duplicates, and writes to a partitioned + clustered BigQuery table with malformed records routed to a dead-letter path; a Looker Studio dashboard visibly updates from that table; each component runs under a least-privilege service account; and you can drain or cancel the job to stop billing. The dashboard screenshot is the headline artefact.


Project 4 — Containerised microservices on GKE Autopilot

In plain terms: you are running several small services together on Kubernetes — the industry-standard way to run containers at scale — the managed (Autopilot) way, so Google runs the machines and you just describe the workloads. It proves you are comfortable with containers, cluster networking, and pods reaching Google APIs without a password file.

The brief. Take a small multi-service application (two or three containerised services with a database) and run it on GKE Autopilot as a production-shaped Kubernetes deployment: ingress via the Gateway API, pod-level keyless identity to Google APIs, and a managed database. This is the project that proves you understand Kubernetes, container networking, and workload identity — the things serverless lets you skip and that DevOps interviews probe hard.

The GCP services.

Service Role in this project
GKE Autopilot Managed, node-less Kubernetes (you pay per pod, Google runs the nodes)
Artifact Registry Private container image registry
Gateway API (GKE) Modern, role-oriented ingress / external HTTPS load balancing
Workload Identity Federation for GKE Pods authenticate to Google APIs with no node keys
Cloud SQL (PostgreSQL) Managed relational database, private IP
Secret Manager Database credentials — never in env files or the image
Cloud Build + Terraform CI to build/push images; IaC for the cluster and network

Build outline.

  1. Provision a GKE Autopilot cluster with Terraform on a VPC with a private subnet. Autopilot manages nodes, bin-packing, and security defaults, so you focus on workloads — and you do not pay for idle nodes, which is the cost story to tell.
  2. Containerise two or three services, push to Artifact Registry, and write Kubernetes manifests (Deployments, Services). Expose the front service through the Gateway API (a Gateway + HTTPRoute) with a Google-managed certificate — the successor to the older Ingress, and the more current thing to demonstrate.
  3. Wire Workload Identity Federation for GKE: bind a Kubernetes service account to a Google service account so pods call Google APIs (e.g. Cloud SQL, Secret Manager) without any exported key. This keyless pattern is the headline security talking point.
  4. Stand up Cloud SQL (PostgreSQL) with private IP; connect from the cluster via the Cloud SQL Auth Proxy / built-in connector. Store the DB credentials in Secret Manager and mount them into pods — they never appear in the image or plaintext manifests.
  5. Set resource requests (Autopilot schedules on them), liveness/readiness probes, a HorizontalPodAutoscaler, and a PodDisruptionBudget so the app survives node maintenance. Apply a NetworkPolicy so only the front service can reach the backend.
  6. Document the cluster/network diagram, the Gateway API routing, the Workload Identity binding, and the Secret Manager flow. Provide terraform destroy and note that Autopilot bills per running pod.

The GitHub deliverable. A repo with the services, Dockerfiles, Kubernetes manifests (or Helm/Kustomize), the IaC (VPC, GKE Autopilot, Cloud SQL, Artifact Registry, service accounts, Workload Identity binding), a CI workflow that builds/pushes images and rolls out, an architecture diagram showing the Gateway → pods → Cloud SQL path and the Workload Identity flow, and a README explaining Autopilot vs Standard, the Gateway-API-over-Ingress choice, and keyless pod identity.

Copy-paste résumé bullet.

Deployed a containerised microservices application on GKE Autopilot — Gateway API ingress with a Google-managed certificate, two services with HPA, probes, a PodDisruptionBudget, and a NetworkPolicy — using Workload Identity Federation for keyless pod access to Cloud SQL (private IP) and Secret Manager; fully defined in Terraform, with per-pod billing eliminating idle-node cost and zero exported service-account keys in the platform.

Done when. Two or three services run on an Autopilot cluster; the front service is reachable through a Gateway API Gateway + HTTPRoute with a managed certificate; pods reach Cloud SQL (private IP) and Secret Manager via Workload Identity with no key file; the app has resource requests, liveness/readiness probes, an HPA, a PodDisruptionBudget, and a NetworkPolicy; and everything comes from Terraform with a clean terraform destroy.


Project 5 — Observability and SRE

In plain terms: you take an app you already built and make it operable — so that when it misbehaves at 3 a.m. you can see why in seconds and get paged only when it actually matters. This is the leap from “I deployed it” to “I run it,” which is what an SRE interview is entirely about.

The brief. Take one of the earlier applications (project 2, 3, or 4 is ideal) and make it observable and operable: structured logs, custom metrics, dashboards, actionable alerts, distributed tracing, an uptime check, and a defined SLO with an error budget and multi-window burn-rate alerting. The deliverable is the difference between “I deployed an app” and “I operate a service” — exactly the gap DevOps and SRE interviews probe.

The GCP services.

Service Role in this project
Cloud Logging Centralised, structured (JSON) logs; log-based metrics
Log Analytics SQL querying of logs for diagnostics
Cloud Monitoring dashboards The four golden signals on one screen
Cloud Monitoring SLOs Define SLIs/SLOs with error budgets, the native way
Alerting + burn-rate policies Multi-window, multi-burn-rate alerts (not noisy single-spike ones)
Uptime checks Outside-in availability probing the public endpoint
Cloud Trace + Error Reporting Distributed tracing and automatic error grouping
Notification channels Email/Slack/PagerDuty delivery for alerts

Build outline.

  1. Make the app emit structured JSON logs with a trace/correlation ID so you can pivot from a single request to its full trace. View and query them in Log Analytics with SQL.
  2. Publish or derive custom metrics (log-based metrics, or OpenTelemetry from the app) and build a Cloud Monitoring dashboard showing the four golden signals — latency, traffic, errors, saturation — on one screen.
  3. Enable Cloud Trace (and Error Reporting) and capture a trace/service view showing the call path and where latency accumulates.
  4. Define a concrete SLO in Cloud Monitoring’s native SLO tooling (e.g. “99.5% of requests succeed and return in <300 ms over a rolling 28 days”), which computes the error budget for you. Create multi-window, multi-burn-rate alerting policies (a fast-burn page and a slow-burn ticket) so alerts fire on real budget consumption, not single blips. Route them to notification channels.
  5. Add an uptime check that exercises the public endpoint from multiple regions and feeds the availability SLI.
  6. Write a one-page runbook: what each alert means and the first three diagnostic steps. Document the SLO, the dashboard, and a sample Log Analytics query.

The GitHub deliverable. A repo (or a folder added to an existing project) with the dashboard, SLO, and alerting-policy definitions as IaC (Terraform google_monitoring_* — monitoring-as-code is a strong signal), the uptime-check config, the runbook, a screenshot of the dashboard under load, a Cloud Trace screenshot, and a README stating the SLO and error budget. Treating monitoring as code, not click-ops, is the thing that impresses here.

Copy-paste résumé bullet.

Instrumented a production Google Cloud workload for SRE — structured JSON logging with trace correlation in Log Analytics, a four-golden-signals Cloud Monitoring dashboard, Cloud Trace distributed tracing, and a native SLO (99.5%/300 ms over 28 days) with multi-window, multi-burn-rate alerting and a multi-region uptime check — all defined in Terraform, cutting mean-time-to-diagnose from guesswork to a single Log Analytics query.

Done when. The app emits structured JSON logs with a trace ID queryable in Log Analytics; a dashboard shows the four golden signals; Cloud Trace shows a request’s path; a named SLO (e.g. 99.5%/300 ms over 28 days) computes an error budget with multi-window burn-rate alerts routed to a notification channel; an uptime check feeds availability; a one-page runbook exists; and the dashboard, SLO, and alert policies are defined in Terraform, not clicked in the console.


Project 6 — Enterprise landing zone

In plain terms: you build the ground floor a whole company’s cloud sits on — the org chart of projects, the shared network, the identity groups, and the guardrails that stop teams doing dangerous things — all in code. This is the platform-team capstone; it is what senior, platform, and architect roles are hired to do.

The brief. Build the governed foundation that real organisations run on: a Google Cloud organisation with a sane folder hierarchy, a shared/host networking project, centralised identity via groups, preventive guardrails, and a baseline of org-wide logging — provisioned and version-controlled with Terraform. This is the platform-engineering capstone; it is where senior, platform, and architect roles live, because it demonstrates you can build the thing other teams land on rather than a single app.

The GCP services.

Service Role in this project
Resource hierarchy (Organisation → Folders → Projects) The governance topology; IAM and policy inherit down it
Cloud Identity Org-level identity, groups for role assignment (no per-user grants)
Org Policy Service Preventive, inherited guardrails (constraints)
Shared VPC One host project’s network, shared to service projects
Cloud NAT + hierarchical firewall + Private Google Access Controlled egress and centralised network security
Cloud Logging sinks (aggregated) Org-wide audit/log export to a central logging project
IAM service accounts + Workload Identity Federation The Terraform automation identity, keyless from CI
Terraform Codifies the org, folders, projects, Shared VPC, Org Policy, sinks

Build outline.

  1. Start from a fresh organisation (you get one free with a Cloud Identity / Google Workspace domain). Design a folder structure — at minimum a Common/Bootstrap folder, an Environments folder split Prod/Non-Prod, and a place for workloads. Keep it shallow; folders exist to apply policy, not to mirror the org chart.
  2. Set up a Terraform bootstrap: a seed project with the automation service account, remote state in a GCS bucket, and Workload Identity Federation so CI runs Terraform with no exported key.
  3. Author Org Policy constraints as code and apply them high in the tree so they inherit — e.g. restrict resource locations to approved regions, disable service-account key creation, require OS Login, restrict external IPs, and enforce uniform bucket-level access. Org Policies set the boundary; they do not grant access.
  4. Build a Shared VPC: a host project owning the VPC, subnets, Cloud NAT, hierarchical firewall policies, and Private Google Access, shared to one or more service projects that attach to it. This separation of network and workload ownership is a key talking point.
  5. Centralise identity with Cloud Identity groups and grant roles to groups, never individuals, at the folder level so access inherits. Create an aggregated log sink at the org or folder level exporting audit logs to a dedicated logging project (or BigQuery for analysis).
  6. Vend at least one service project through your Terraform to demonstrate the workflow end to end. Document the folder/Org-Policy design, the Shared VPC ownership model, and the identity flow. (Mind the cost: the hierarchy and Org Policy are free, but Cloud NAT, any running resources, and log storage are not — tear down what you can.)

The GitHub deliverable. A repo with terraform/ defining the folder hierarchy, Org Policy constraints, the Shared VPC (host/service projects, subnets, Cloud NAT, hierarchical firewall), group-based IAM bindings, and the aggregated log sink; an architecture diagram of the folder/project topology and the Shared VPC; and a README that explains why the project is the isolation/billing boundary, why Org Policies are guardrails not grants, why roles go to groups, and how Shared VPC separates network from workload ownership. This is the most senior-signalling repo you can pin.

Copy-paste résumé bullet.

Architected a governed Google Cloud landing zone in Terraform — an Organisation → Folders (Prod/Non-Prod) hierarchy, inherited Org Policy guardrails (approved-regions, no service-account keys, OS Login, no external IPs), a Shared VPC with host/service-project separation, Cloud NAT, hierarchical firewall and Private Google Access, group-based IAM, and an org-wide aggregated log sink — provisioned keylessly via Workload Identity Federation, giving new teams a compliant, audit-ready service project in minutes instead of weeks.

Done when. Terraform stands up an Organisation → Folders (Prod/Non-Prod) hierarchy; Org Policy constraints (approved regions, no service-account keys, OS Login, no external IPs, uniform bucket-level access) inherit down the tree; a Shared VPC host project shares subnets, Cloud NAT, and firewall to at least one service project vended by your code; IAM is granted to groups, not individuals; an aggregated log sink exports audit logs centrally; and the automation runs keylessly via Workload Identity Federation.


Google Cloud portfolio projects ladder

The diagram above shows the six projects as ascending rungs — read it bottom-up. Each rung is annotated with its headline Google Cloud services, the role tier it targets, and the certification it maps to, so you can see at a glance how capability and seniority compound as you climb: rung 1 proves you can automate instead of clicking, and rung 6 proves you can build the foundation other teams land on.

The GitHub presentation standard

A brilliant project hidden in a messy repo is a wasted project. Reviewers spend seconds, not minutes, on each repo; presentation is not vanity, it is the medium through which your work is read. Apply this standard to every project above.

The repository. Give it a clear, descriptive name (gcp-serverless-url-shortener, not project2). Pin your best three-to-six repos on your GitHub profile so they appear first. Add topics/tags (gcp, terraform, cloud-run) so the repo is discoverable. Include a permissive licence (MIT is fine) — its absence quietly signals “not really finished.” Ensure the default branch is clean and the repo has no committed secrets (more on this below).

The README is the product. It is the first — often only — thing read. Structure it: a one-line description and an architecture diagram at the very top; then What it does, Architecture (the diagram plus a paragraph), How to deploy (the exact commands), How to tear down (terraform destroy or cleanup steps), Cost (a Free-Tier / $300-credit note or a rough monthly estimate), and Key decisions / trade-offs (this section is what wins technical interviews — explain why a load balancer over a bucket website, why Firestore, why Autopilot over Standard). A reviewer who reads only the README should understand the whole project.

Architecture diagrams. Every repo gets one, embedded in the README. Use a consistent tool (draw.io/diagrams.net, Excalidraw, or the official Google Cloud architecture icons) and commit the source so it is editable. A clear diagram instantly communicates seniority; its absence reads as “I can’t see the whole system.”

Commit history. Make commits atomic and meaningfully messaged (“Add Cloud CDN and managed certificate to the load balancer,” not “stuff” or “fix”). A clean history shows how you work and is itself reviewed. Avoid one giant “initial commit” dump where possible — incremental, descriptive commits read as professional.

Infrastructure as Code, always. Every project is defined in Terraform and destroyable with one command. Console click-ops in a portfolio reads as junior; reproducible IaC reads as production-ready. Bonus signals: a CI badge in the README, a Makefile or task runner for common commands, and a short CONTRIBUTING/architecture-decision note.

The table below is the at-a-glance checklist to run against each repo before you pin it.

Element The standard Why a reviewer cares
Repo name Descriptive, hyphenated Signals intent at a glance
Pinned Best 3–6 on profile Controls first impression
README top One-liner + diagram Whole project understood in seconds
Deploy/teardown Exact commands, both ways Proves it actually runs — and that you clean up
Cost note Free-Tier / $300-credit / estimate Cost-awareness is a hiring signal
Key decisions Why each choice Wins the technical interview
Diagram Embedded, source committed Communicates system thinking
Commits Atomic, well-messaged Shows how you work
IaC One-command create/destroy Reads as production-ready
Secrets None committed; Workload Identity / Secret Manager Screens out a common security failure

Going deeper: from “built it” to “can present and defend it”

Building the project is half the work; the half that actually gets you hired is turning each rung into something a reviewer can read in seconds and you can defend for ten minutes. The presentation standard above is the floor. This section is the ceiling — the craft that makes a repo read as senior and converts a project into an interview talking point.

The five artifacts a strong rung ships

Every rung, regardless of difficulty, should ship the same five artifacts. Miss one and the project reads as unfinished no matter how good the code is.

Artifact What it is What it proves
README as decision log Not a feature list — a narrative of what, why, and the trade-offs You make reasoned choices, not tutorial-following
Architecture diagram One image at the top of the README, source committed You can see the whole system
Cost note A small table: Free-Tier line, realistic monthly estimate, the one resource that bites You think about the bill (a real hiring filter)
IaC + teardown terraform apply up, terraform destroy down, from a clean clone It actually runs and you clean up
Demo A 60–90s recorded walkthrough or a live-runnable path It’s real, not screenshots of someone else’s work

The README is a decision log, not a manual. Anyone can list “Cloud Run, Firestore, API Gateway.” What wins the interview is a Key decisions / trade-offs section that reads like: “Chose Firestore over Cloud SQL because the access pattern is a single-key lookup by short-code — a document store keyed on that code is O(1) and scales to zero; a relational schema would add a connection pool and a server I’d have to size and pay for.” That one paragraph is worth more than the entire codebase to a technical interviewer, because it is the conversation they want to have.

The cost note is a hiring filter, not a footnote. Cost-awareness is one of the few things every employer screens for. Ship a tiny table like this in each project’s README:

Resource Free-Tier / trial covers If you forget to tear down
Cloud Storage (5 GB, US region) Yes ~₹0
Global external ALB forwarding rule Partly ~₹1,500 / USD 18 per month
Reserved global IP (unattached) No Billed hourly while idle
Cloud DNS managed zone No ~₹40 / USD 0.50 per zone per month

Naming the resource that would bite you (here, the load balancer and an orphaned IP) signals more operational maturity than a project that never mentions money.

The demo is what makes it undeniable. A screenshot can be faked or copied; a demo cannot. For terminal-heavy rungs (1 and 6) record an asciinema cast of terraform apply → the working endpoint → terraform destroy. For visual rungs (3 and 5) record a 60-second screen capture of the Looker Studio dashboard or the Cloud Monitoring SLO updating. Embed the link in the README. Best of all is a project you can terraform apply live in the interview — few candidates can, and it ends the “did you really build this?” question instantly.

Turning a rung into an interview talking point

A project you cannot narrate is a project you cannot use. Convert each rung into a 90-second STAR story and rehearse it out loud:

Then map the follow-up question tree — every rung invites a predictable set of deeper questions, and a senior candidate has answered them before they are asked:

Rung The follow-up to pre-answer
1 · Static site “How does the cache invalidate on deploy? Why a load balancer and not a bucket website?”
2 · Serverless API “Why Firestore over Cloud SQL? How do you stop a client running up your bill?”
3 · Data pipeline “Pub/Sub is at-least-once — how do you avoid double-counting? Why partition and cluster?”
4 · GKE “Autopilot or Standard, and why? How does a pod reach Cloud SQL without a key?”
5 · SRE “What’s your SLO, and why multi-window burn-rate instead of a simple threshold alert?”
6 · Landing zone “Do Org Policies grant access? Why groups, not users? What does Shared VPC separate?”

Two more senior signals worth rehearsing for every rung: the “redraw it” test — can you sketch the architecture on a whiteboard from memory in two minutes? — and the “how would you scale or harden this 10×?” answer — always have one improvement ready (add Cloud Armor in front of rung 1; add a read replica and a connection pooler to rung 4; tighten the SLO and add a canary rollout to rung 5). Naming the next thing you would do shows you know the project’s limits, which reads as more senior than pretending it has none.

Hands-on lab: ship Project 1 and pin it

This lab gets the first rung done end to end on the Free Tier and the $300 trial credit, so you finish with a real, pinned repository. Set your project once: gcloud config set project <PROJECT_ID>.

Step 1 — scaffold the repo. Create a GitHub repo gcp-static-site-cicd, clone it, and add a minimal index.html. Create an infra/ directory for Terraform.

Step 2 — write the Terraform and create the backend bucket + CDN load balancer. In infra/, define a Cloud Storage backend bucket (uniform bucket-level access on), a backend-bucket resource with Cloud CDN enabled, a URL map, a target HTTPS proxy with a Google-managed certificate, and a global forwarding rule on a reserved global IP. Run:

cd infra
terraform init
terraform apply

Expected: Terraform prints the load balancer’s global IP address as an output (e.g. 34.x.x.x). For a first pass without a custom domain, you can also validate the bucket-and-CDN path quickly with the CLI:

gcloud storage buckets create gs://<BUCKET> --uniform-bucket-level-access --location=US
gcloud storage cp index.html gs://<BUCKET>/
gcloud compute backend-buckets create site-backend --gcs-bucket-name=<BUCKET> --enable-cdn

Step 3 — first manual deploy (to validate). Sync the site and confirm it serves through the load balancer over HTTPS:

gcloud storage rsync . gs://<BUCKET> --recursive --exclude="infra/.*|\.git/.*"
curl -I https://<your-domain-or-LB-IP>/

Expected: HTTP/2 200, with a via/cache header from Google’s front end once the certificate is ACTIVE (a managed certificate can take up to ~15–60 minutes to provision — check gcloud compute ssl-certificates describe). Validation: the page is reachable through the load balancer’s anycast IP from anywhere, and the bucket itself is not public (uniform bucket-level access is on and no allUsers binding exists).

Step 4 — wire CI/CD with Workload Identity Federation (no exported keys). Create a Workload Identity Pool and a GitHub provider, and a deploy service account that the pool can impersonate, scoped to your repo (and the main branch). Add .github/workflows/deploy.yml that, on push to main, authenticates via google-github-actions/auth (Workload Identity, no JSON key), builds the site, runs gcloud storage rsync to the bucket, and runs gcloud compute url-maps invalidate-cdn-cache <URL_MAP> --path="/*".

Step 5 — prove the pipeline. Edit index.html, commit, and push to main. Watch the Actions run go green; refresh the site URL and confirm the change is live. Screenshot the green run for your README.

Step 6 — document and pin. Write the README to the presentation standard above (diagram, deploy, teardown, cost, key decisions). Pin the repo on your profile.

Cleanup / cost note. Run terraform destroy to remove the load balancer, backend bucket, certificate, and IP (and gcloud compute backend-buckets delete / gcloud storage rm -r gs://<BUCKET> if you used the CLI quick-path). Almost everything here is Free-Tier eligible (Cloud Storage’s 5 GB-region free allotment, Cloud CDN cache egress within free limits, Google-managed certificates are free). The reserved global IP is free while attached to a forwarding rule but billed if you leave it reserved and unused, and Cloud DNS is about ₹40 / USD 0.50 per managed zone per month if you add a custom domain — so destroy what you do not need.

Practice challenges

These are graded “ship this rung” tasks, escalating from beginner to advanced. Do them in order — each one is a self-contained slice you can finish, screenshot, and pin. Every command and snippet below is real and current; project IDs, service-account emails, and buckets are placeholders. Try each before opening the solution.

Challenge 1 — Serve a private bucket globally over HTTPS (beginner). Stand up a Cloud Storage backend bucket with Cloud CDN behind a global external Application Load Balancer, and prove the bucket itself is not public.

<details> <summary>Acceptance criteria, hints, and why</summary>

Acceptance criteria: the site loads over HTTPS on the LB IP or domain; gcloud storage buckets get-iam-policy gs://<BUCKET> shows no allUsers / allAuthenticatedUsers binding; uniform bucket-level access is on.

Hints:

gcloud storage buckets create gs://<BUCKET> --uniform-bucket-level-access --location=US
gcloud compute backend-buckets create site-backend --gcs-bucket-name=<BUCKET> --enable-cdn
gcloud compute ssl-certificates describe <CERT> --global   # wait for MANAGED status ACTIVE

Why: the load-balancer-over-private-bucket pattern gives you HTTPS, CDN, and a global anycast IP while keeping the origin private — the defensible, production-shaped choice a reviewer wants you to be able to justify. </details>

Challenge 2 — Deploy with zero exported keys (beginner → intermediate). Wire GitHub Actions to deploy rung 1 using Workload Identity Federation instead of a service-account key.

<details> <summary>Acceptance criteria, hints, and why</summary>

Acceptance criteria: the workflow authenticates with google-github-actions/auth using a Workload Identity provider (no credentials_json key anywhere); the provider’s attribute condition is scoped to your repo; a push to main deploys and invalidates the CDN.

Hints:

gcloud iam workload-identity-pools create github-pool --location=global
gcloud iam workload-identity-pools providers create-oidc github-provider \
  --location=global --workload-identity-pool=github-pool \
  --issuer-uri="https://token.actions.githubusercontent.com" \
  --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository" \
  --attribute-condition="assertion.repository=='<OWNER>/<REPO>'"

Grant the deploy service account roles/iam.workloadIdentityUser bound to the pool’s principalSet, and run gcloud compute url-maps invalidate-cdn-cache <URL_MAP> --path="/*" after the rsync step.

Why: short-lived federated credentials have no key file to leak, and many Org Policies now disable service-account key creation outright — so keyless is both safer and more portable. </details>

Challenge 3 — A serverless API that scales to zero, behind a gateway (intermediate). Ship rung 2’s core: Cloud Run + Firestore behind API Gateway, with a least-privilege service account and a 5xx alert.

<details> <summary>Acceptance criteria, hints, and why</summary>

Acceptance criteria: requests go through API Gateway (Cloud Run has no allUsers invoker); the Cloud Run service account holds only roles/datastore.user (not Editor/Owner); the service runs with --min-instances=0; an alerting policy fires on the 5xx rate.

Hints:

gcloud run deploy notes-api \
  --image <REGION>-docker.pkg.dev/<PROJECT>/<REPO>/notes:1 \
  --service-account notes-run@<PROJECT>.iam.gserviceaccount.com \
  --no-allow-unauthenticated --min-instances=0 --max-instances=5 --region <REGION>
gcloud projects add-iam-policy-binding <PROJECT> \
  --member="serviceAccount:notes-run@<PROJECT>.iam.gserviceaccount.com" \
  --role="roles/datastore.user"

Give the gateway’s service account roles/run.invoker; add a log-based metric on severity>=ERROR and an alerting policy on it.

Why: the gateway is the only front door (keys, quotas, validation) and scale-to-zero means idle cost is effectively nothing — the two things this rung is meant to prove. </details>

Challenge 4 — A streaming pipeline that doesn’t double-count (intermediate → advanced). Ship rung 3: Pub/Sub → Dataflow → BigQuery, with a dead-letter path and a partitioned + clustered sink.

<details> <summary>Acceptance criteria, hints, and why</summary>

Acceptance criteria: the BigQuery table is partitioned by event/ingest date and clustered on your main filter column; malformed events land in a dead-letter table or GCS prefix instead of failing the job; a Looker Studio chart reads the table; you can drain the job to stop billing.

Hints:

bq mk --table \
  --time_partitioning_type=DAY --time_partitioning_field=event_date \
  --clustering_fields=user_id \
  <DATASET>.events \
  event_date:DATE,user_id:STRING,payload:JSON
gcloud dataflow jobs drain <JOB_ID> --region <REGION>   # stop billing cleanly

In Beam, apply fixed or session windows and branch parse failures to a dead-letter PCollection written to a separate sink.

Why: Pub/Sub is at-least-once, so idempotency plus a dead-letter branch keep the warehouse correct; partitioning and clustering cut the bytes scanned, which is exactly what BigQuery on-demand bills for. </details>

Challenge 5 — Keyless pods on Autopilot (advanced). Ship rung 4’s security core: a pod on GKE Autopilot that reads a secret from Secret Manager with no key file, via Workload Identity.

<details> <summary>Acceptance criteria, hints, and why</summary>

Acceptance criteria: the cluster is Autopilot; a Kubernetes service account is bound to a Google service account; a pod running as that KSA reads a secret from Secret Manager with no mounted key; a NetworkPolicy restricts pod-to-pod traffic.

Hints:

gcloud container clusters create-auto app --region <REGION>
gcloud iam service-accounts add-iam-policy-binding \
  <GSA>@<PROJECT>.iam.gserviceaccount.com \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:<PROJECT>.svc.id.goog[<NAMESPACE>/<KSA>]"

Annotate the KSA with iam.gke.io/gcp-service-account=<GSA>@<PROJECT>.iam.gserviceaccount.com, and grant the GSA roles/secretmanager.secretAccessor on the specific secret.

Why: Workload Identity gives pods short-lived credentials from the metadata server — nothing to mount, rotate, or leak — which is the pattern a DevOps interviewer expects you to name. </details>

Challenge 6 — A guardrail and a shared network, in code (advanced). Ship a slice of rung 6: an Org Policy that blocks service-account key creation, plus a Shared VPC host → service attachment, in Terraform.

<details> <summary>Acceptance criteria, hints, and why</summary>

Acceptance criteria: the iam.disableServiceAccountKeyCreation constraint is enforced on a project/folder and actually blocks gcloud iam service-accounts keys create; a host project shares a subnet to a service project that can then launch a VM on it.

Hints:

resource "google_org_policy_policy" "no_sa_keys" {
  name   = "projects/<PROJECT>/policies/iam.disableServiceAccountKeyCreation"
  parent = "projects/<PROJECT>"
  spec {
    rules {
      enforce = "TRUE"
    }
  }
}

Enable Shared VPC with google_compute_shared_vpc_host_project + google_compute_shared_vpc_service_project, then grant the service project’s principals roles/compute.networkUser on the shared subnet.

Why: Org Policy sets the boundary (what is even allowed) while IAM sets access — the two-layer model senior interviews probe — and Shared VPC separates network ownership from workload ownership. </details>

Common mistakes & troubleshooting

Symptom Likely cause Fix
Site returns 404/SSL error for the first hour Google-managed certificate not yet ACTIVE, or DNS A record not pointing at the LB IP Wait for provisioning; confirm the A record targets the LB’s anycast IP; check gcloud compute ssl-certificates describe
Stale content after a deploy CDN still serving the cached object Run gcloud compute url-maps invalidate-cdn-cache --path="/*" in the pipeline; set sensible cache-control
GitHub Actions can’t authenticate to GCP Workload Identity pool/provider attribute condition doesn’t match the repo/branch, or wrong service account Scope the provider’s attribute condition to assertion.repository == 'owner/name'; grant the SA the Workload Identity User role
Cloud Run API returns 403 to API Gateway Service requires auth but the gateway’s service account lacks run.invoker Grant the gateway service account roles/run.invoker on the service; keep allUsers off
GKE pods CrashLoopBackOff reaching Cloud SQL Workload Identity binding missing, or Cloud SQL on private IP unreachable Bind the K8s SA to a Google SA with the Cloud SQL Client role; use the connector/Auth Proxy; check VPC/firewall
Dataflow job costs more than expected Job left running, or over-provisioned workers Drain or cancel the streaming job when idle; cap maxNumWorkers; use the right machine type
BigQuery queries scan the whole table No partitioning/clustering, or SELECT * Partition by date, cluster on the filter column, select only needed columns; check the bytes-scanned estimate
Surprise bill after a project Cloud SQL, GKE Standard, Cloud NAT, or a reserved IP left running terraform destroy; prefer Autopilot/scale-to-zero; set a Budget alert as a backstop
Secrets committed to the repo Credentials in env files, key JSON, or the image Use Workload Identity / Secret Manager; run gitleaks in CI; rotate anything exposed

Common beginner mistakes

These are portfolio anti-patterns — distinct from the technical failures in the troubleshooting table above. Each is a habit that quietly caps how senior your work reads; the fix is a change of mental model, not a command.

Best practices

Security notes

A portfolio is also a security exhibit — reviewers notice both good and bad habits.

Interview & exam questions

Q1. For the static site, why a global external Application Load Balancer with Cloud CDN instead of just a public bucket website? A bucket website serves HTTP only (no managed HTTPS), from one location, with no CDN and no clean upgrade path. Fronting a private backend bucket with a global external Application Load Balancer gives you a global anycast IP, managed TLS via a Google-managed certificate, Cloud CDN edge caching, URL maps for routing, and a path to add Cloud Armor/WAF later — while keeping the bucket private. It is the more production-shaped, more defensible choice.

Q2. In your CI/CD pipeline, why Workload Identity Federation instead of a service-account key in GitHub secrets? An exported key is a long-lived, standing liability — if leaked it grants persistent access. Workload Identity Federation lets GitHub Actions exchange its OIDC token for short-lived Google credentials by impersonating a service account, with an attribute condition scoped to your specific repo and branch. There is no key to leak, credentials expire automatically, and many Org Policies now disable key creation outright.

Q3. Cloud Run vs GKE — when would you reach for each, and why did project 2 use Cloud Run but project 4 use GKE? Cloud Run is the fastest path for a stateless container or API: it scales to zero, you pay per request/CPU, and there is no cluster to operate — ideal for project 2’s serverless API. GKE (Autopilot) is the right call when you need Kubernetes primitives — multiple cooperating services, NetworkPolicies, service mesh, DaemonSets, or fine-grained scheduling — which project 4 demonstrates. The trade-off is operational surface: GKE gives control and portability at the cost of more to run; Cloud Run gives simplicity at the cost of the Kubernetes ecosystem.

Q4. GKE Autopilot vs Standard — what does Autopilot change? Autopilot is a mode where Google manages the nodes: provisioning, bin-packing, security hardening, and upgrades. You deploy pods and pay per pod (based on requested CPU/memory) rather than per node, so there is no idle-node cost and a smaller attack/ops surface. Standard gives you node-level control (custom machine types, DaemonSets, GPUs in more configurations) at the cost of managing the node pools yourself. Autopilot is the sensible default for most workloads and the better cost story in a portfolio.

Q5. Why put Pub/Sub in front of Dataflow in the data pipeline, and what delivery guarantee must you design for? Pub/Sub decouples producers from the processing job: it buffers bursts (producers never wait on the consumer), provides durable retention, and lets the pipeline scale and retry independently. Pub/Sub is at-least-once, so the Dataflow pipeline must be idempotent / dedupe-aware (e.g. on a message attribute or business key) and handle late data via windowing — otherwise duplicates corrupt the warehouse.

Q6. How did you make the BigQuery sink cheap and fast? By partitioning the table (typically by ingestion or event date) so queries prune to the relevant days, and clustering on the highest-cardinality filter column so blocks are pruned further — together cutting bytes scanned, which is what BigQuery on-demand bills for. Plus selecting only needed columns (never SELECT *) and using the Storage Write API for efficient streaming inserts.

Q7. What is Workload Identity (for GKE), and why is it better than a key file in the pod? Workload Identity binds a Kubernetes service account to a Google service account so pods obtain short-lived Google credentials automatically from the metadata server — no key file mounted, nothing to rotate or leak. It is the keyless, least-privilege way for pods to call Google APIs (Cloud SQL, Secret Manager, Pub/Sub), and it is the pattern an interviewer expects you to name.

Q8. What is an SLO, an SLI, and an error budget, and how did you implement them on GCP? An SLI is the measured indicator (e.g. % of requests succeeding under 300 ms); the SLO is the target (e.g. 99.5% over 28 days); the error budget is the allowed shortfall (0.5%). I defined the SLO in Cloud Monitoring’s native SLO tooling, which tracks the budget, and created multi-window, multi-burn-rate alerting — a fast-burn policy that pages on rapid budget consumption and a slow-burn policy that opens a ticket — so alerts reflect real degradation, not single spikes.

Q9. In the landing zone, do Org Policies grant permissions? No. Org Policies are preventive guardrails (constraints) that bound what can be configured in a part of the hierarchy — for example, restricting locations, disabling service-account key creation, or blocking external IPs. They grant nothing; access still comes from IAM allow policies. Effective behaviour is “IAM says who can do what” intersected with “Org Policy says what is even allowed.”

Q10. Why is Shared VPC a senior-signalling choice, and what does it separate? Shared VPC lets a host project own the network (VPC, subnets, Cloud NAT, firewall) and share it to service projects that run workloads. This separates network ownership (a central platform/networking team) from workload ownership (application teams), centralises egress and security controls, and avoids a sprawl of peered per-team VPCs. Demonstrating it shows you think at platform scale, not single-project scale.

Q11. A reviewer opens your repo. What are the first three things you want them to see, and why? (1) The README’s one-line description and architecture diagram at the top — instant comprehension of what and how. (2) A clear deploy and teardown section — proof it actually runs and that I clean up. (3) A “Key decisions / trade-offs” section — evidence I made reasoned choices (LB-over-bucket, Autopilot-over-Standard, keyless identity), which is what the technical interview probes.

Q12. How do you keep these projects from costing money? Stay on the Free Tier and the $300 trial credit, prefer scale-to-zero (Cloud Run) and Autopilot (per-pod billing) over always-on resources, drain/cancel Dataflow jobs when idle, partition/cluster BigQuery to cut scanned bytes, avoid leaving Cloud SQL, GKE Standard clusters, Cloud NAT, or reserved-but-unused IPs running, define everything in IaC so I can terraform destroy after capturing screenshots, and set a Budget alert as a backstop.

Quick check

  1. For the static-site rung, what keeps the Cloud Storage origin private while still serving globally over HTTPS with a CDN?
  2. What is the keyless mechanism that lets GitHub Actions deploy to GCP without an exported service-account key?
  3. What delivery guarantee does Pub/Sub provide, and what property must your Dataflow pipeline therefore have?
  4. Do Org Policy constraints grant IAM permissions?
  5. In project 4, what lets a GKE pod call Cloud SQL and Secret Manager without a key file?

Answers

  1. A global external Application Load Balancer with Cloud CDN in front of a private backend bucket (uniform bucket-level access on, no allUsers), terminating TLS with a Google-managed certificate.
  2. Workload Identity Federation — GitHub’s OIDC token is exchanged for short-lived Google credentials by impersonating a service account, scoped to the repo/branch.
  3. At-least-once delivery; therefore the pipeline must be idempotent / dedupe-aware (and handle late data via windowing).
  4. No. Org Policies are preventive guardrails that bound what can be configured; access comes from IAM allow policies. Effective = IAM ∩ Org Policy.
  5. Workload Identity (for GKE) — the Kubernetes service account is bound to a Google service account, so the pod gets short-lived credentials with no key file.

Exercise

Pick the two rungs that match the role you are currently targeting (use the ladder table) and take them to the full GitHub presentation standard: descriptive repo name, README with diagram/deploy/teardown/cost/key-decisions, IaC with a one-command destroy, keyless auth (Workload Identity), atomic commits, a gitleaks scan in CI, and the repo pinned to your profile. Then write the quantified résumé bullet for each, adapting the templates above with your own numbers (latency, cost, bytes-scanned reduction, deploy time). Finally, draft a two-sentence answer to “walk me through this project” for each — out loud, timed to under 90 seconds. If you can build it, present it, quantify it, and narrate it, that rung is interview-ready.

Certification mapping

This lesson is portfolio evidence across the Google Cloud certification ladder rather than mapped to a single exam:

Build the projects that match the certifications you are pursuing; the portfolio and the exam reinforce each other.

Glossary

Next steps

You now have a build plan and a presentation standard for a portfolio that gets you hired. Next, sharpen the exam side of the story with the Google Cloud Certification Prep Kit: Digital Leader, ACE, PCA, PDE & Security Engineer — domain checklists, scenario practice questions, and cheat sheets that pair with these projects. Then take the most senior rung all the way to production depth in the Google Cloud Capstone: Build an Enterprise Landing Zone + 3-Tier App, which turns project 6 into a single, pillar-by-pillar reference build against the Architecture Framework. Together, the portfolio, the certifications, and the capstone make the complete case: you can recognise the right answer, and you can build it.

GCPPortfolioCareerTerraformResumeProjects
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments