How do you stop one developer's mistake from accidentally deleting your entire production database? That's the core problem that GCP project structure and IAM solve: they create secure boundaries and fine-grained permissions so that people and services can only do what they're supposed to do. For a DevOps engineer, getting this right is the difference between a controlled, auditable environment and a chaotic free-for-all where one wrong click costs the company millions.
Jump to a section
A simple way to picture Setting Up GCP Projects and Identity Access Management
Ever tried to get into a friend's apartment building when you don't have a key? You buzz their flat, they let you in, but you can't use the gym or the rooftop terrace — only they can. That's exactly how GCP projects and IAM work.
Imagine a large apartment block called 'MyCompany'. The building itself is your GCP organisation. Each flat in the building is a separate GCP project — one for your 'dev' team, one for 'staging', one for 'production'. The building manager is the organisation admin. They decide who gets a key to which flat.
Now, inside each flat, there are different rooms. The living room might be 'Compute Engine', the kitchen 'Cloud Storage', the bedroom 'BigQuery'. Each room has a door with a special lock. IAM (Identity and Access Management) is the set of locks and keys. A person might be a 'Viewer' — they can look through the peephole but not open the door. An 'Editor' can open any door in that flat and rearrange the furniture. An 'Owner' can even change the locks or sell the flat.
Service accounts are like automated robot butlers you give a key to. They don't have a human face — they're programmed to fetch data from one room and deliver it to another. You wouldn't give the butler the master key to every flat, just the specific rooms they need to access. That's the principle of least privilege: give the smallest key that still gets the job done.
Let's start with the big picture. Google Cloud Platform (GCP) is a collection of cloud services — servers, storage, databases, networking — that you can use to build and run applications. But if everyone in your company could access everything, you'd have chaos. That's where projects and IAM come in.
A GCP project is the fundamental building block. Think of it as a container that holds all the resources for a specific purpose. Every resource — a virtual machine, a storage bucket, a database — lives inside exactly one project. Projects have three key attributes: a project ID (globally unique, you choose it), a project name (human-readable, can change), and a project number (assigned by Google, never changes). When you create a project, GCP automatically creates a default network inside it.
Why multiple projects? Best practice is to separate environments. You might have one project for development ('dev'), one for testing ('staging'), one for production ('prod'), and one for shared services like monitoring. This creates a blast radius: if someone accidentally deletes everything in the dev project, the production system is untouched.
Now, how do you control who can do what inside a project? That's IAM — Identity and Access Management. IAM has three parts: who (the principal), can do what (the role), on which resource (the resource).
A principal is a 'who'. It can be a Google account (a human user), a Google group (a collection of users), a service account (an automated identity for applications), or a G Suite domain (your whole company).
A role is a collection of permissions. Permissions are the smallest atomic actions, like 'compute.instances.create' (create a virtual machine) or 'storage.objects.get' (read a file from a bucket). Roles bundle these permissions together. There are three types:
Primitive roles: These are the old-style, broad roles: Viewer (read-only), Editor (can modify resources), Owner (full control including billing). They apply to the whole project.
Predefined roles: Google creates these for specific services. For example, 'roles/storage.objectViewer' gives read access to objects in Cloud Storage. These are granular and recommended.
Custom roles: You create your own by picking specific permissions. Use these when predefined roles are too broad or too narrow.
A resource is what you're granting access to. It could be the whole project, a specific folder, a single storage bucket, or even a specific file within a bucket. IAM policies are hierarchical: you can set a policy at the organisation level, folder level, project level, or resource level. Permissions flow downwards. If you grant someone 'Editor' on a folder, they get 'Editor' on all projects inside that folder.
This hierarchy is critical for DevOps. Your company might have multiple teams with multiple projects. The organisation node sits at the top. Under it, you create folders for departments (like 'Engineering', 'Finance'). Under each folder, you create projects. Under each project, you create resources.
Service accounts are a special type of principal. They're not a person — they're an identity for a piece of software. For example, a virtual machine might need to read from a database and write to a storage bucket. You create a service account, assign it the necessary roles (like 'roles/cloudsql.client' and 'roles/storage.objectAdmin'), and attach that service account to the VM. The VM then uses the service account's credentials to authenticate to GCP APIs.
Why not just use a human's credentials? Because people leave, people change roles, and human passwords get compromised. Service accounts use cryptographic keys (either managed by GCP or a private key file) and are designed for automation. Never use your personal Google account for automated tasks — always use a service account.
IAM conditions add another layer of control. They let you enforce rules like 'only allow access if the request comes from a specific IP range' or 'only allow access between 9 AM and 5 PM'. This is called context-aware access and it's a key security feature for production environments.
For the PCDOE exam, you need to understand these concepts cold. They love asking: 'A DevOps team needs to grant a CI/CD pipeline access to deploy to a project. What should they use?' The answer is always a service account with the minimum required predefined roles. They also love testing the hierarchy: 'If you grant a role at the organisation level, which projects does it affect?' Answer: all projects under that organisation.
Plan your resource hierarchy
Decide on the organisation structure. For example, create folders for each department (Engineering, Finance) and sub-folders for environments (Dev, Staging, Prod). This ensures that IAM policies can be inherited efficiently.
Create GCP projects
Inside each folder, create a project for each distinct environment or application. Use consistent naming (e.g., 'env-app-project') to make it clear what each project is for. Each project will contain resources like VMs, storage buckets, and databases.
Create service accounts for automated workloads
For each CI/CD pipeline, application, or VM that needs to call GCP APIs, create a dedicated service account. Name it descriptively (e.g., 'ci-cd-deployer' or 'web-app-sa'). This separates permissions for each workload.
Assign roles using IAM
At the appropriate node in the hierarchy (project, folder, or resource), assign the minimal predefined roles to each principal (user, group, or service account). For example, assign 'roles/cloudbuild.builds.editor' to the CI/CD service account on the dev project.
Apply IAM conditions for additional security
Use conditions to restrict access based on attributes like source IP address, time of day, or resource type. For example, add a condition to the production folder allowing access only from the company VPN IP range.
Audit and refine IAM policies regularly
Use Cloud Audit Logs and Policy Analyzer to review who has what access. Remove unused service accounts, rotate keys, and adjust roles as team or application requirements change. This is an ongoing process.
Let's walk through a realistic scenario. You work for 'FinTech Corp', a company that builds a mobile banking app. You have three environments: development (dev), staging, and production (prod). You also have a central monitoring team that needs to see logs from all environments.
Step 1: Plan the folder structure. You create a folder called 'FinTech-Engineering'. Inside it, you create three sub-folders: 'Dev', 'Staging', 'Prod'. Inside each sub-folder, you create one GCP project. For example, 'fintech-dev-project', 'fintech-staging-project', 'fintech-prod-project'. You also create a fourth project called 'fintech-shared-monitoring' directly under the organisation for the central monitoring team.
Step 2: Create the service accounts. Your CI/CD system (like Jenkins or Cloud Build) needs to deploy code. You create a service account called 'ci-cd-deployer'. It needs permissions to create and update resources in the dev and staging projects. You assign the predefined role 'roles/editor' to the service account at the 'Dev' folder level and the 'Staging' folder level. Note: you do NOT assign it at the 'Prod' folder level — only specific senior engineers have production access.
Step 3: For the monitoring team, you create a service account called 'monitoring-collector'. You assign it the role 'roles/logging.logWriter' on the 'Dev', 'Staging', and 'Prod' folders. This lets it write logs to their central project. You also assign it 'roles/monitoring.viewer' on the same folders so it can see metrics.
Step 4: For human users, you create a Google Group called 'fintech-developers@fintechcorp.com'. You grant this group the role 'roles/viewer' on the 'Prod' folder so developers can see production logs but not change anything. You grant them 'roles/editor' on the 'Dev' folder so they can develop.
Step 5: Apply IAM conditions. You add a condition to the production folder: 'only allow access if the IP address is within the company VPN range'. This prevents a developer from accessing prod from a coffee shop.
Step 6: Audit. You use Cloud Audit Logs to monitor who did what. You check: 'Who deleted that storage bucket in dev?' The logs show the 'ci-cd-deployer' service account did it during a deployment script. You fix the script.
The key actions a DevOps engineer performs daily include:
Creating and configuring new projects for new applications or services
Creating and managing service accounts and their keys
Assigning roles at the appropriate level (resource, project, folder, organisation)
Using IAM conditions for additional security
Auditing IAM policies using Policy Analyzer
Without this structure, you'd be giving every developer full access to everything, which is a security nightmare. With proper project structure and IAM, you achieve least privilege, isolation of environments, and full auditability.
The PCDOE exam (exam code: PCAE or Google Cloud Professional DevOps Engineer) tests 'Setting Up GCP Projects and Identity Access Management' heavily in the 'Designing and Implementing GCP Project Structure, Service Accounts, and IAM Roles for DevOps Tooling' section (objective 5.1). Expect around 5-8 questions on this topic across the multiple-choice and case study sections.
Concept areas they repeatedly test:
Organisation hierarchy: The order is Organisation -> Folders -> Projects -> Resources. They will ask you to identify the correct level to assign a role. Trap: they might offer a solution that assigns a role at the project level when it should be at the folder level to apply to multiple projects.
Service accounts vs user accounts: Questions about CI/CD pipelines always need a service account. Trap: they might offer 'create a user account for the build server' as an answer — that's wrong.
Predefined vs primitive vs custom roles: They love asking the difference. Primitive roles (Viewer, Editor, Owner) are considered too broad for production. Predefined roles are preferred. Custom roles are only used when predefined roles don't exist. Trap: they might suggest using a primitive role 'Editor' when a predefined role like 'roles/cloudbuild.builds.editor' is more appropriate.
IAM conditions: They will test scenarios where you need to restrict access based on IP, time, or resource type. Trap: they might offer a solution that doesn't use conditions and just gives blanket access.
Service account keys: Understand the difference between Google-managed keys (recommended) and user-managed keys (less secure). Trap: they might suggest attaching a user-managed key to a VM when a Google-managed key would work.
Default service accounts: Every project gets a default Compute Engine service account and a default App Engine service account. Trap: questions about granting the default service account additional roles. Know that you should create custom service accounts instead of modifying default ones.
Resource hierarchy inheritance: Permissions flow from parent to child, but they are not aggregated if you grant at multiple levels. Trap: 'If I grant a role at the project level and a different role at the folder level, which one applies?' Answer: both do — the effective permissions are the union of all granted roles.
Question types:
Scenario-based multiple choice: 'A DevOps team wants to give a CI/CD pipeline the ability to deploy to staging and production. What is the correct IAM configuration?' Answer: Create a service account, assign it 'roles/editor' on the staging folder and a restricted role like 'roles/compute.instanceAdmin.v1' on the production folder.
True/false: 'Service accounts are a type of user account.' Answer: False.
Drag and drop: Arrange the GCP resource hierarchy in the correct order.
Fill in the blank: 'The principle of _____ means giving a principal only the permissions it needs to perform its functions.' Answer: least privilege.
Key definitions to memorise:
Organisation: The root node in the GCP resource hierarchy.
Folder: A container for projects, used for grouping and policy inheritance.
Project: A container for resources, with its own IAM policy and billing.
IAM policy: A set of bindings that map principals to roles.
Role: A collection of permissions.
Permission: An atomic action (e.g., 'compute.instances.create').
Principal: An identity (user, group, service account, domain).
Service account: An identity for applications or VMs.
IAM condition: An additional constraint on a role binding.
A common exam trap is the 'principle of least privilege' question. They will give you a situation where a team asks for 'Owner' access to a project, but they only need to deploy code. The correct answer is to grant a predefined role like 'roles/cloudbuild.builds.editor' at the project level or a custom role with just the permissions needed. Another trap: confusing the GCP organisation node with a folder. The organisation is the root; folders are optional containers under it.
A GCP project is a container for resources with its own IAM policy, billing account, and service configuration.
IAM policies are hierarchical: permissions flow from organisation to folder to project to resource.
Service accounts are non-human identities for automated processes; they should never be used interactively.
Predefined roles are preferred over primitive roles (Viewer, Editor, Owner) for granular access control.
IAM conditions allow you to add context-based restrictions like IP address ranges or time-of-day to role bindings.
The principle of least privilege means granting a principal only the minimum permissions needed to perform its tasks.
Service account keys should be considered highly sensitive and must be rotated regularly.
Always use Google-managed service account keys when possible; user-managed keys are less secure.
These come up on the exam all the time. Here's how to tell them apart.
Primitive Roles
Include only Viewer, Editor, Owner — broad and simple.
Apply to the entire project or organisation.
Mostly legacy; not recommended for production.
Predefined Roles
Service-specific collections of permissions (e.g., roles/compute.instanceAdmin).
Can be applied at any level (organisation, folder, project, resource).
Best practice for granular access control.
User Account
Identifies a human (e.g., email@example.com).
Can log into the GCP Console interactively.
Uses password-based authentication and optionally 2FA.
Service Account
Identifies an application or VM (e.g., my-sa@project.iam.gserviceaccount.com).
Cannot log into the Console without special configuration.
Uses cryptographic keys (Google-managed or user-managed) for authentication.
Project-Level IAM
Permissions apply to all resources within the project.
Easier to manage when many resources need the same access.
Less granular — cannot restrict to a single bucket or VM.
Resource-Level IAM
Permissions apply only to a specific resource (e.g., one Cloud Storage bucket).
More granular and secure for targeted access.
Can be combined with project-level policies (union of permissions).
Organisation Node
Root of the GCP resource hierarchy for an entire domain.
Only one per G Suite or Cloud Identity account.
All projects under the organisation inherit policies set here.
Folder Node
Optional container for grouping projects.
Can be nested up to 10 levels deep.
Projects in different folders do not share inherited policies.
Google-Managed Key
Created and rotated automatically by GCP.
Cannot be downloaded; stored securely by Google.
Recommended for most production use cases.
User-Managed Key
You create and manage the private key file (JSON format).
Can be downloaded and rotated manually.
Less secure because the private key must be stored and protected by you.
Mistake
A service account is the same as a user account and can log into the GCP Console.
Correct
A service account is a non-human identity that authenticates to APIs, not a user. It cannot log into the GCP Console interactively without special configuration (like using a browser for OAuth). It is intended for automated processes.
The word 'account' in both terms leads beginners to think they behave identically. They don't realise that service accounts are meant for machine-to-machine communication without interactive login.
Mistake
If I grant the 'roles/viewer' role at the project level, every user in the project can see all resources in that project.
Correct
Granting 'roles/viewer' at the project level gives that privilege to only the specific principals (users, groups, service accounts) named in the IAM binding. It does not automatically apply to all users who have access to the project through other means like being a member of the project's default service account.
Newcomers confuse the concept of 'project membership' (being associated with a project through billing or ownership) with IAM permissions. They think 'being in the project' means 'having permissions', which is incorrect.
Mistake
Custom roles are always better than predefined roles because they give you more control.
Correct
Custom roles are not always better. They require more maintenance because you must manually manage the permissions. Predefined roles are maintained by Google and include the correct permissions for common tasks. Use custom roles only when no predefined role fits your exact needs.
Beginners hear 'custom = flexible = better' and assume custom roles are the superior choice. They don't factor in the operational overhead of keeping custom roles up-to-date with Google's API changes.
Mistake
IAM policies can only be set on projects and not on individual resources like a Cloud Storage bucket.
Correct
IAM policies can be set on projects, folders, the organisation, and on individual resources such as a Cloud Storage bucket, a Compute Engine instance, or a BigQuery dataset. Resource-level policies are more granular than project-level policies.
Many learners think IAM only applies at the project level because that's the most common example. They don't know about resource-level IAM or Unified Access Control for services like Cloud Storage.
Mistake
A service account key is like a password and should be treated casually because it's just for automated tools.
Correct
A service account key is a highly sensitive credential. If leaked, an attacker can gain whatever permissions the service account has. Keys should be regularly rotated, stored securely (e.g., in a secrets manager), and never hard-coded in code or committed to source control.
Beginners who are new to identity security often think automated identities have less security risk because 'it's just a robot'. They neglect best practices like key rotation and private key protection.
Mistake
Granting a role at the organisation level gives that role to all projects in all folders.
Correct
Granting a role at the organisation level gives that role to all projects under that organisation, including those in folders. It is inherited by all child resources. However, it does not affect resources outside the organisation (e.g., other GCP organisations).
The nuance is that it does apply to all projects, but beginners often think it only applies to projects directly under the organisation (not sub-folders), or they think it somehow affects projects in other organisations. They need to understand the complete hierarchy inheritance.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
A project is the container for resources like VMs and storage buckets. A folder is a container for projects (and other folders) used to apply IAM policies and organise projects hierarchically. You can nest folders up to 10 levels deep.
Yes, you can create up to 100 service accounts per project by default (this quota can be increased). Each service account is independent and can have different roles assigned. You would typically create one service account per distinct application or microservice.
The VM may continue running because it may have cached credentials, but any new API calls that require authentication will fail. Always ensure you have a replacement service account with the same permissions attached before deleting the old one.
You can use the IAM tab in the Cloud Console for that specific bucket. Add the service account as a principal and assign a role like 'roles/storage.objectAdmin' or 'roles/storage.objectViewer' at the bucket level. This is resource-level IAM.
Every project is automatically given a Compute Engine default service account (usually named 'PROJECT_NUMBER-compute@developer.gserviceaccount.com') and an App Engine default service account. They have Editor role on the project by default, which is overly permissive. You should limit their permissions or create custom service accounts instead.
Because 'Editor' grants write access to all resources in the project, including billing settings and IAM policies, which the pipeline likely does not need. Use a predefined role like 'roles/cloudbuild.builds.editor' or 'roles/compute.instanceAdmin.v1' to follow the principle of least privilege.
Yes, Google Groups are valid principals in IAM. You can create a group like 'devops-team@example.com' and assign roles to that group. Then add or remove individual users from the group to manage access without editing IAM policies each time.
You've finished Setting Up GCP Projects and Identity Access Management. Continue through the PCDOE study guide to build a complete picture of the exam.
Done with this chapter?