---
cuppy_hub: gcp
cuppy_path: guides/parity/iac.md
cuppy_section: docs
cuppy_doc: RCDY-AANN
cuppy_doc_uuid: cf58bed4-aa4d-48f0-a394-eab4ac906359
cuppy_permalink: https://cuppy.io/gcp/d/RCDY-AANN
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/gcp/docs/guides/parity/iac
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 8a6761bbf894905986b64d7c1d791b8baa7a51caaf59d6e2c5b1bc2b908eb7b2
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# 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:

1. **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.
2. **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.
3. **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.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 91 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/gcp/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
