IaC parity — Terraform and Infra Manager against CloudFormation and ARM/Bicep, with the template ceilings side by side
Counterpart names for the IaC family, then the differences that change an estimate: Google Cloud's first-party language is Terraform itself while AWS and Azure each have a native one, the template ceilings are an order of magnitude apart, Deployment Manager is out of support, and the Kubernetes-operator route exists on all three.
markdownguidev1RCDY-AANNstage: designtrust: officialfamily: iacservice: terraforminterface: iaciac parityterraforminfrastructure managercloudformationarm templatebicepconfig connectorACKazure service operatortemplate limitsdeployment manager
IaC parity
1. The names
| Google Cloud | AWS | Azure |
|---|---|---|
Terraform (google provider) — the de facto first-party language | CloudFormation (native); CDK; Terraform aws provider | ARM templates / Bicep (native); Terraform azurerm provider |
| Infrastructure Manager — managed Terraform runs | CloudFormation itself is the managed runner; Service Catalog | ARM deployments; deployment stacks |
| Cloud Deployment Manager — out of support since 31 March 2026 | — | Azure Resource Manager (the pairing Microsoft's table gives) |
| Config Connector — Google Cloud resources as Kubernetes objects | AWS Controllers for Kubernetes (ACK) | Azure Service Operator |
| Cloud Build | CodeBuild, CodeDeploy, CodePipeline | Azure Pipelines, GitHub Actions |
| Organization Policy Service | AWS Config | Azure Policy |
Two cautions about the published tables. Microsoft's mapping pairs Cloud Deployment Manager with *Azure Resource Manager* — a reasonable name match that is now misleading, because Deployment Manager reached end of support on 31 March 2026 and Google's named successor is Infrastructure Manager. And Google's own table is dated December 3, 2024, so the CI/CD rows predate Infra Manager's current shape. Where a mapping table and a product page disagree, prefer the product page.
2. The difference that changes how the work is organised
Google Cloud's first-party IaC language is Terraform. Google documents Terraform in its own documentation set, publishes Blueprints as Terraform modules, and ships Infra Manager as *a managed runner for Terraform configurations*. AWS and Azure each have a native language (CloudFormation, ARM/Bicep) with Terraform as a well-supported third-party alternative.
Estimate consequences, and they cut in opposite directions:
- To Google Cloud from a Terraform estate: this is the cheapest IaC migration of any pair. The language,
the tooling, the state model and the CI integration all survive; what changes is the provider and the resource schemas. Budget per resource type.
- To Google Cloud from CloudFormation or ARM/Bicep: a full rewrite into a different language, plus a
decision about whether resources are imported or recreated. Budget per resource, and separately per stateful resource.
- From Google Cloud: you may keep Terraform and change provider — which is why a Terraform-first estate is
the most portable thing in this comparison, and worth saying out loud to anyone sizing a future exit.
3. The template ceilings, side by side
These are not the same quantity measured three ways; they are three different models. Read the row labels carefully.
| Google Cloud (Terraform) | AWS (CloudFormation) | Azure (ARM/Bicep) | |
|---|---|---|---|
| resources in one unit | no vendor-published per-configuration ceiling read here | 500 per template; 2,500 per nested-stack operation | 800 per template, copy count included |
| template size | n/a — HCL is not submitted to an API as a document | 51,200 bytes in a request; 1 MB from an S3 object | 4 MB template, 1 MB per resource definition |
| parameters / variables / outputs | n/a | 200 / — / 200 | 256 / 512 / 64 |
| units per account | no published stack equivalent | 2,000 stacks, increase requestable | deployments per scope (see Microsoft's limits page) |
| other | state is yours (a gcs bucket) or Infra Manager's | concurrent-operation limit must be read with DescribeAccountLimits | 10 unique locations per subscription/tenant/management-group scope; 24,576 characters per expression |
Three readings:
- Google Cloud has no equivalent ceiling because it has no equivalent object. Terraform submits API calls,
not a document, so "resources per template" is a Terraform-side concern (plan time, blast radius), not a platform refusal. This is why a Google Cloud estate often has fewer, larger IaC units than the same estate on AWS — and why a CloudFormation estate converted one-stack-to-one-module produces more modules than it needs.
- Azure's limits apply to the expanded template. The best-practices page is explicit that they apply
"to the final state of the template after it has been expanded with iterative resource definitions". A loop that is small in source can exceed 800 resources after expansion, which no source-level review catches.
- Azure's 10-unique-locations limit per scope has no counterpart on the other two. A multi-region Azure
deployment is split by that limit alone. Budget it when the target is Azure; ignore it when the target is Google Cloud.
4. The Kubernetes-operator route exists on all three
Config Connector, AWS Controllers for Kubernetes and Azure Service Operator are the same idea. One Google Cloud fact transfers as a warning rather than a feature: Config Connector reconciles as its own service account, "not the identity of the human user or service account that submitted the manifest". Every operator of this kind has that property, and every estimate that assumes the applying engineer's permissions are the ones that matter is wrong by one identity per cluster.
5. Pricing dimension (never a price)
| Google Cloud | AWS | Azure | |
|---|---|---|---|
| the IaC service | Terraform is free; Infra Manager is a Google Cloud service — check its own pricing page | CloudFormation: no charge for most resource types; third-party and private resource-type handler operations are metered | ARM deployments: no charge |
| what you actually pay for | the state bucket and the resources created | the resources created | the resources created |
So on all three, IaC cost is a rounding error beside the resources, with one exception worth naming: on AWS, private and third-party resource types are metered per handler operation, which turns a custom resource in a tight loop into a line item. There is no Google Cloud equivalent of that charge in the pages read here.
6. What this guide cannot tell you
Whether terraform import can adopt a given resource type, on any of the three clouds. That is per resource
type and it is the question that decides whether an IaC migration is a rewrite or a re-adoption. The method is
guides/parity-and-migration-method.md; the Google Cloud side of it is
reference/iac/deployment-manager-status.md §3.