Home Blog GCP Architecture Series #26 — Infrastructure Manager: Managed Terraform…
GCP Architecture GCP Architecture Series

GCP Architecture Series #26 — Infrastructure Manager: Managed Terraform

Infrastructure Manager takes the two decisions post #25 spent its length on — where state lives and how the bucket is configured — and makes them for you. What it does not remove is the question underneath them. It relocates it, from who can read a bucket to who can act as a service account, and the second question is easier to get wrong because nothing about it looks like storage.

Verified against current vendor documentation on 8 September 2026. Pricing, limits and API behaviour were checked against the official docs on that date. Cloud services change fast — if you are reading this much later, treat the specifics as a starting point and re-check the linked sources.

Business Challenge

Adopting a managed service usually removes a category of decision. This one removes some and relocates others, and the relocated ones are the surprises.

1
"It is managed, so we do not think about state"

Until the day you must. The state file is still there and still yours to reckon with, but reaching it is a procedure rather than a path: the deployment must be locked to be able to download the state file, and the download comes through a signed Cloud Storage URL rather than a bucket you browse.

Correct approach

Learn the lock, export and unlock sequence before an incident, not during one. It is three commands and they are not the ones muscle memory reaches for.

2
"Deployments run with the permissions of whoever triggers them"

They do not. Infra Manager executes Terraform using the identity of a service account you configure, and that identity is fixed regardless of who pressed the button. A user needs only the Service Account User role on it to deploy.

Correct approach

Size the service account's permissions to the configuration it deploys, and treat the grant of Service Account User on it as equivalent to granting everything that account can do. It is the real access decision here.

3
"We will delete the deployment but keep the resources"

You can, and Google is direct about the consequence: after you delete the deployment, Infra Manager is not able to identify or manage the Google Cloud resources that are kept. The infrastructure keeps running and becomes invisible to the thing that made it.

Correct approach

Treat it as a deliberate hand-off with an owner named on the day, not as a tidy-up. Post #23's asset export is how those resources stay findable afterwards, because the deployment no longer knows them.

4
"The revision history is our audit trail"

It is bounded. Infra Manager keeps 100 historical revisions per deployment, along with the logs, the configuration used, the resource list and the state file for each. That is generous for debugging and finite for compliance.

Correct approach

The same conclusion as post #23 reached about the 35-day asset history: if a claim will ever be made about a change from a year ago, the record has to be somewhere you control.

Architecture

Infrastructure Manager is a managed service that simplifies and automates the deployment and management of your Google Cloud infrastructure resources. Concretely, it runs Terraform for you and keeps the bookkeeping.

Diagram: what Infrastructure Manager takes over from self-managed Terraform, the service account identity model, the lock required to read state, the bounded revision history, and the abandon deletion path
What the service takes over, what it relocates, and the two doors that only open one way.

What it takes over

It creates a Cloud Storage bucket and stores the deployment metadata in it — the logs, the configuration used for each revision, the list of resources that revision created, and the state file for each deployment and revision. Configurations can come from a Cloud Storage bucket, a Git repository or a local directory, and you choose which supported Terraform version each deployment uses.

Read against post #25, that is most of a morning's work removed. The bucket, its versioning, its access settings and the backend block all stop being decisions. What does not disappear is the state file itself, which still exists, still holds whatever the configuration put in it, and is still the thing you need when something goes wrong.

The identity model is the whole design

This is the difference that matters, and it is easy to read past. With Terraform on a laptop or in a pipeline, the apply runs with the credentials of whoever or whatever invoked it. With Infra Manager, it does not: the service executes Terraform using the identity of a configured service account, which needs the Infra Manager Agent role plus permissions for every resource type the configuration touches. A person triggering a deployment needs the Service Account User role on that account.

Post #25's risk did not go away — it changed shape

Post #25 said the state bucket is a credential store and only the build system and highly privileged administrators should read it. Infra Manager creates and holds that bucket, so that specific exposure narrows. But the deployment service account must hold permissions for everything the configuration deploys, and Service Account User on it is enough to run a deployment. So the question moves from who can read a bucket to who can act as this account — and the second is harder to notice, because an IAM binding on a service account does not look like access to infrastructure. Audit the members of that role the way you would audit readers of the state bucket.

Deployments, revisions and previews

A deployment is the unit; a revision is one update to it. A preview describes the actions to actuate a specific Terraform configuration — a plan, produced without provisioning anything, that you read before deciding to create or update.

That is the same instinct as post #21's dry-run mode for organization policies, and it is worth using for the same reason: it is the only chance to see what a change does while the change costs nothing. The difference is that a preview here is complete, whereas a dry-run policy only observes the traffic that happens to arrive.

The numbers

LimitValueWhy it matters
Deployments per project per region1,000Generous. Reaching it means one deployment per resource rather than per component.
Historical revisions100The audit trail is finite, per deployment.
Terraform input variables150A configuration approaching this is asking to be split.
Identifier length40 charactersShorter than the naming budget post #18 worked through — plan for it.
Mutating requests20 per minute per project per regionThe ceiling on automated deploy loops.
API payload950,000 bytesA very large configuration hits a wall that is not Terraform's.

The 40-character identifier limit deserves a note, because post #18 spent its length on naming budgets and this is a tighter one than any there. A deployment name carrying environment, component and region can run out, and the limit applies to the name you will be typing into every command afterwards.

Why This Architecture Holds Up

Reading your own state is now a transaction

With a Cloud Storage backend you read state by reading an object. Here you take a lock, export a signed URL, download, and unlock — the deployment must be locked to be able to download the state file, and there are separate commands to take the lock, retrieve the lock id, and release it.

This is better engineering than the thing it replaces. Terraform state corruption from two simultaneous applies is a real failure and the lock prevents it structurally rather than by convention. The cost is that the emergency path has more steps, and an unreleased lock is a new way to block your own pipeline. Both are worth knowing before the night you need them.

Abandon is the one-way door

Deleting a deployment deletes its metadata and files, and you choose whether the provisioned resources go with it. Keeping them is a legitimate move — handing a stack over to be managed in the console, or splitting it into a different tool. But Google states the consequence without softening it: after you delete the deployment, Infra Manager is not able to identify or manage the resources that are kept. There is no re-attach, the resources do not announce themselves, and the only record that they were ever deployed together is the one you kept. Name an owner and write down what was abandoned, on the day.

When the managed service is the right answer

  • You want the state decisions made for you. Post #25's bucket, versioning and access settings are real work and easy to get subtly wrong. This removes them.
  • You want locking you cannot forget to configure. It is structural here rather than optional.
  • You want deployments that do not run as a human. A fixed service account identity is more auditable than "whichever engineer ran it".

When it is not

  • Your state is your record. A hundred revisions is a debugging history, not a compliance archive.
  • You need the full Terraform ecosystem. A supported-version list is narrower than "whatever we pin to", and post #25's minor-version pin strategy becomes someone else's decision.
  • Your identity model cannot support it. If you cannot scope a service account tightly to a configuration, you have built a broad grant with a convenient interface.

Key Architecture Decisions

DecisionChoose thisBecause
The real access control Audit Service Account User on the deploy account Infra Manager executes Terraform as that identity, not as the person triggering it.
Service account scope One per configuration, permissions sized to it A shared broad account makes every deployment as powerful as the widest one.
Before any update Run a preview It describes the actions to actuate the configuration, and provisions nothing.
Emergency state access Rehearse lock, export, unlock The deployment must be locked to download the state file, and an unreleased lock blocks the pipeline.
Long-term change record Export it yourself Revision history is capped at 100 per deployment.
Deleting a deployment Decide the resource fate explicitly Keeping them means Infra Manager can no longer identify or manage them.
Abandoned resources Record them, and rely on Cloud Asset Inventory Nothing marks them as orphaned; the export from #23 is how they stay findable.
Deployment naming Budget for 40 characters Tighter than any limit in post #18, and you type it into every command.
Configuration size Split well before 150 input variables The limit is a symptom; #25's hundred-resource guidance is the cause.
Automated deploy loops Rate-limit to the 20-per-minute mutating ceiling Per project per region, and it is the first wall a busy pipeline meets.

Closing Thought

The honest summary of a managed service is usually a trade rather than a saving, and this one trades well. It removes the state bucket decisions, makes locking structural instead of optional, and gives deployments an identity that is not a person. Those are three genuine improvements on the arrangement post #25 described.

What it does not do is remove the question. Post #25's version was who can read this bucket, and it was at least legible — a bucket looks like storage, and storage looks like something to lock down. The version here is who can act as this service account, which is a line in an IAM policy that looks like nothing at all. Managed services tend to move risk from where you are looking to where you are not, and the discipline is to go and look at the new place with the same seriousness you gave the old one.

Next in this series

#27 takes the third approach to the same problem: Config Connector, which puts Google Cloud resources behind the Kubernetes API — what that buys, and what it costs to have your cluster own your infrastructure.

Comments

How was your experience?
Your feedback helps improve this site.
PoorExcellent