Google Cloud
Scope: CLI and API only. This guide covers the gcloud CLI and the Firefly API for onboarding GCP projects without the console wizard. Firefly also ships a Terraform module for Google Cloud onboarding, documented separately.
When to use this
Use this guide to bulk onboard GCP projects, drive onboarding from a CI/CD pipeline, or enable org-level discovery. For a single project, the console wizard (Settings > Integrations > Add New > Google Cloud) is faster.
Prerequisites
Admin access to the Firefly console
gcloudCLI, authenticatedGCP IAM permissions to create service accounts and grant roles
Org-level IAM permissions if you want folder-tree discovery (optional)
curlandjq
Pre-flight: can you create service account keys?
Run this before committing to a timeline. This integration depends on a downloadable service account JSON key, and some organizations block key creation with an org policy.
gcloud resource-manager org-policies describe \
constraints/iam.disableServiceAccountKeyCreation \
--project="$PROJECT_ID" --effectiveIf the constraint is enforced, key creation will fail and no amount of IAM permission will fix it. Options, in order of preference:
Request a scoped exception for the Firefly project only. Most platform teams will grant this for a single, audited service account — a narrower ask than disabling the policy org-wide.
Use a project that's out of scope of the policy, if you have one designated for third-party integrations.
Contact your Firefly representative to confirm whether a keyless option (Workload Identity Federation) is currently available for this integration.
Two related constraints worth checking at the same time, since both cause confusing failures later:
The second restricts which identities can be granted roles and is a common cause of "role binding rejected" errors that look like a permissions problem but aren't.
Phase A — Authenticate to Firefly
Create the key pair under Settings > Users > Create Key Pair, then:
Phase B — Configure Google Cloud
1. Authenticate and set the project
2. Create the service account
Use a dedicated service account rather than reusing an existing one — it keeps revocation and audit simple.
3. Grant project-level roles
roles/viewer
Read-only access for inventory discovery
roles/iam.securityReviewer
IAM and security configuration, for compliance scanning
roles/logging.configWriter
Required for event-driven integration (log sinks)
roles/storage.bucketViewer
Bucket metadata for IaC state discovery
4. Grant conditional tfstate access
Object read access is scoped by an IAM condition so Firefly can only read objects whose name ends in tfstate.
Use add-iam-policy-binding, never set-iam-policy, for this. set-iam-policy overwrites the project's entire IAM policy document; add-iam-policy-binding is additive and safe.
5. Org-level folder discovery (optional)
Only needed if you want Firefly to discover the folder tree and auto-enroll projects. Requires org admin.
For full org-wide project discovery, also grant roles/viewer at the organization scope. This is the main scale lever on GCP — with org-level viewer and auto-discovery enabled, you onboard one anchor project and Firefly enumerates the rest.
6. Generate the service account key
This file is a long-lived credential. Keep it out of version control, delete it from your workstation once uploaded, and agree a rotation schedule up front.
Service account keys don't expire. That's a common finding in security reviews — the key is scoped to a dedicated read-only service account, the tfstate binding is conditioned to a filename suffix, and rotation is a process you control. To rotate, create a second key, update the integration in the Firefly console, then delete the old key:
Agree a rotation interval during onboarding rather than after the first audit.
7. Enable required APIs
Takes 2–3 minutes. recommender.googleapis.com powers Google Cloud Insights — leaving it out silently disables that feature.
8. Additional projects (optional)
The same service account can cover multiple projects. For each additional project, repeat steps 3, 4, and 7 with PROJECT_ID set to the new project and SA_EMAIL unchanged:
Phase C — Register with Firefly
name
Display name for the integration
projectId
The GCP project ID being integrated. This is the anchor project used to discover the rest
serviceAccountKey
Full contents of firefly-sa-key.json, as a JSON string
isPrimary
True if this is your primary GCP integration
shouldAutoDiscoverProjects
Discover all accessible projects automatically
isProd
Marks the integration as production
isEventDrivenDisabled
false enables real-time event detection
isIacAutoDiscoverDisabled
false enables automatic IaC discovery
regexExcludeProjectsDiscovery
Regex list of projects to skip, e.g. [".*-test$", "sandbox-.*"]
The initially integrated project is listed first in the console, and every subsequently discovered project hangs off it. Deleting that first project deletes the whole integration — worth planning around before you tidy up unused projects.
This call isn't documented as idempotent. If a registration partially fails, check the console before retrying rather than assuming a second call will update the integration in place.
Verify
Firefly console > Settings > Integrations > Google Cloud
Confirm the project appears and the status is connected
Inventory, filtered to Google Cloud — allow 10–15 minutes for first discovery
Troubleshooting
Key creation fails outright
constraints/iam.disableServiceAccountKeyCreation is enforced — see the pre-flight check above
Role binding rejected
Org policy restricting IAM grants (allowedPolicyMemberDomains), or missing resourcemanager.projects.setIamPolicy
API enablement fails
Billing not enabled on the project, or missing serviceusage.services.enable
Registration returns 4xx
Malformed serviceAccountKey (check the jq -c . | jq -R . escaping), or an expired token
Some projects missing from Inventory
APIs not enabled on those projects, or they match an exclusion regex
No IaC state discovered
The tfstate IAM condition wasn't applied, or state objects don't end in tfstate
Last updated
Was this helpful?