GCP DevOps Engineer common mistakes
GCP DevOps Engineer · Understand the traps and how to avoid them.
When a scenario says 'prevent any VM in the org from having an external IP' or 'block service account key creation', the candidate answers with IAM changes (removing roles/compute.networkAdmin, adding a deny policy on the principal) instead of naming the Organization Policy constraint.
IAM and Organization Policy both feel like 'guardrails', so candidates reach for the control they use day to day. The exam deliberately tests whether you know that IAM governs who can act while org policy governs what configuration is allowed, regardless of permissions held.
What to do instead
Use the decision rule: 'no identity may do X' -> IAM; 'no resource may ever be configured as X' -> Organization Policy constraint (compute.vmExternalIpAccess, iam.disableServiceAccountKeyCreation, storage.publicAccessPrevention) applied at org or folder level and inherited downward. State the constraint name explicitly in the answer.
Designs a clean folder-per-team hierarchy with roles/resourcemanager.projectCreator at the folder, then claims teams can self-serve new projects end to end, omitting any grant on the billing account.
Candidates model the org tree as the whole permission surface and forget that Cloud Billing IAM is a separate resource with its own bindings.
What to do instead
Grant roles/billing.user (or roles/billing.admin) on the specific billing account, or create per-business-unit billing sub-accounts and bind there; pair it with folder-level projectCreator plus org policy constraints so self-service project creation stays bounded. Also confirm the service account used by automation has roles/resourcemanager.folderAdmin scoped to the folder, not the org.
Defines a 99.9% availability SLO and then configures the alert to fire when the 28-day rolling SLI drops below 99.9%.
The SLO number is the most visible number on the page, so it becomes the alert threshold by default. That produces one slow-burning alert that only fires after the error budget is nearly spent.
What to do instead
Configure multi-window, multi-burn-rate SLO alerting (e.g. 14.4x burn over 1h and 5m, 6x over 6h and 30m, 1x over 3d) using Cloud Monitoring's SLO monitoring, and alert on burn rate rather than on the raw SLI value.
When asked what happens after the error budget is exhausted, answers 'add more dashboards', 'tighten the alert thresholds', or 'page more people' instead of stopping the release pipeline.
Troubleshooting instinct dominates; the error budget as a release-control contract is a policy artefact candidates rarely write in practice.
What to do instead
State the error budget policy explicitly: non-critical releases and feature launches freeze, engineering effort is redirected to reliability work, and normal flow resumes only when the budget recovers. Tie postmortem action items and the CI/CD release gate to that policy so it is enforced mechanically, not socially.
Writes a cloudbuild.yaml containing a test step and a deploy step, assumes they run in order, and ships a pipeline where a failing test does not actually block deployment.
Most CI systems execute steps sequentially, and Cloud Build's default is to start every step as soon as its image is available, so ordering must be declared.
What to do instead
Give each step an id and chain dependencies with waitFor (waitFor: ['-'] starts immediately; waitFor: ['run-unit-tests'] serializes). Make the deploy step waitFor the test step, and verify the behaviour by pushing an intentionally failing test through the trigger.
Puts database passwords, API keys, or deploy tokens directly into substitutions in cloudbuild.yaml or into the trigger's substitution variables, and logs them by echoing in a step.
Substitutions are the obvious parameterization mechanism, triggers display them in the console, and they land in build logs by default.
What to do instead
Store values in Secret Manager, reference them with availableSecrets (secretManager + env) and secretEnv inside the step, and bind the build service account to roles/secretmanager.secretAccessor on that single secret version. Use a dedicated user-managed service account per environment and promote artifacts by digest, not by a mutable 'latest' tag.
Plans long-term retention of audit and application logs by assuming logs stay in the _Default log bucket, and never enables Data Access audit logs, then discovers after an incident that the relevant records were never captured or have expired.
Logs Explorer shows historical-looking entries and the default retention window and the fact that Data Access logs are off by default are both invisible in the UI.
What to do instead
Create a log sink to Cloud Storage or BigQuery (or a custom log bucket) with the required retention, and configure project-level audit log configs for DATA_READ/DATA_WRITE on the services that matter. Document that _Default is 30 days and that Admin Activity logs are always on while Data Access logs must be enabled explicitly.
Diagnoses a p99 latency regression across microservices by reading Cloud Monitoring CPU/memory graphs and grepping Cloud Logging text, concluding the cause is 'the service is under-provisioned'.
Infrastructure metrics are the default tab in the console and need no instrumentation, while spans require the app to emit them.
What to do instead
Instrument with OpenTelemetry/Cloud Trace to get span-level latency attribution per hop, add log-based metrics for error classes, and correlate against SLO burn rate. Use uptime checks plus dependency SLOs to localize the failing edge before touching capacity, and check whether the regression is a dependency rather than the service itself.
Recommends 3-year committed use discounts for a CI/build farm or batch ML workload whose usage is spiky and expected to shrink or migrate.
CUDs are the canonical 'save money' answer for any compute question, and the fact that commitments are per-project/region, non-refundable, and only pay off above a utilization break-even is easy to skip.
What to do instead
Match the instrument to the usage pattern: CUDs for steady-state baseline that you are confident about, Spot VMs for fault-tolerant batch and CI runners, autoscaling with sustained use discounts for variable load. Model the break-even utilization and the commitment's project/region scope before recommending it.
Fixes a slow Cloud Run service by raising CPU and memory limits, or fixes GKE capacity problems by pinning a larger, fixed node pool, rather than tuning the platform's scaling controls.
Vertical scaling is the familiar lever, and concurrency limits, min/max instances, and cluster autoscaler settings are platform-specific knobs candidates may not have operated.
What to do instead
For Cloud Run, tune max concurrency and min/max instances and check cold-start behaviour before changing CPU/memory. For GKE, set accurate requests/limits, enable HPA on a meaningful metric, and use the cluster autoscaler or node auto-provisioning. Validate every change with a load test rather than assuming a bigger machine is faster.