ARM/Bicep vs CloudFormation vs Deployment Manager
Each cloud ships its own native way to describe infrastructure in a file. The mapping is unusually clean this time — and then one honest twist rearranges the whole picture.
New to cloud? CAMPUX is a free, build-first course. Start here →
Azure's native infra-as-code is ARM templates (JSON) plus Bicep, its friendlier language that compiles down to ARM; the deployed unit is a deployment and resources land in resource groups. AWS's is CloudFormation (JSON or YAML), where the deployed unit is a stack, with CDK as the higher-level authoring layer. GCP's was Deployment Manager, now effectively deprecated — Google points you at Terraform instead. So the rows line up, but GCP's native answer is weak, and Terraform quietly became the one tool that targets all three.
This is the layer where cloud engineers stop clicking in a portal and start committing files to git. All three big clouds landed on the same idea: write a declarative template that says what should exist, hand it to a managed service, and let the platform create, update, or delete resources to match. Version it, redeploy it, review it in a pull request. The concept transfers cleanly. Where it gets interesting is that the strongest tool in this space isn't native to any of them.
What each one actually is
Same job on all three — turn a template file into a managed group of real resources you can redeploy safely. The differences are in the language, the name of the unit, and how healthy the tool still is.
Azure: ARM templates and Bicep
ARM templates are the original: big JSON documents describing resources, parameters, and outputs, submitted to the Azure Resource Manager. They work, but hand-writing ARM JSON is miserable, so Microsoft built Bicep — a clean domain-specific language that transpiles to ARM JSON before it's deployed. You write Bicep; Azure sees ARM. The deployed unit is a deployment, and the resources it creates land in a resource group. Of the three native tools, this is the one still getting real investment, and it's the nicest to actually use.
AWS: CloudFormation and CDK
CloudFormation is AWS's original template engine — JSON or YAML describing resources, submitted to the service, tracked as a stack. Stacks are the unit you create, update, and tear down as a whole, and StackSets push the same stack across many accounts and regions at once. Raw CloudFormation YAML is verbose, so AWS built CDK, which lets you author infrastructure in TypeScript, Python, or other real languages that synth down to CloudFormation templates. CDK is roughly the AWS answer to Bicep: a friendlier front end over the same engine.
GCP: Deployment Manager (fading)
Here's the row that breaks. Deployment Manager is GCP's native tool — templates in YAML with Jinja or Python for logic — but Google has de-emphasized it for years. It's effectively deprecated in spirit, and the official guidance now points you at Terraform, Config Controller, or Infrastructure Manager (which is really just hosted Terraform). So when someone asks for the "GCP equivalent of Bicep," the honest answer is that GCP doesn't have a healthy native one anymore. Its real infra-as-code story is Terraform, full stop.
| Concept | Azure | AWS | GCP |
|---|---|---|---|
| Template language | ARM JSON / Bicep | CloudFormation JSON or YAML | Deployment Manager YAML + Jinja/Python |
| The deployed unit | Deployment (into a resource group) | Stack (StackSets across accounts) | Deployment |
| Higher-level authoring | Bicep (compiles to ARM) | AWS CDK (synths to CloudFormation) | — (none native; use Terraform) |
| Where state lives | Server-side (in the platform) | Server-side (in the platform) | Server-side (in the platform) |
| Drift detection | Yes (what deployed vs actual) | Yes (native drift detection) | Limited |
| Preview before apply | az deployment what-if | Change sets | — (weak preview) |
| Health / momentum | Actively invested in | Actively invested in | De-emphasized / legacy |
The mapping is the cleanest in this whole guide — right up until you notice the strongest tool in the room isn't on any cloud's home team.
The one honest twist: Terraform ate all three
Every native tool here has the same ceiling: it only speaks its own cloud. ARM can't deploy to AWS. CloudFormation can't touch Azure. That's fine if you live on one cloud forever, but the job market doesn't. So Terraform (and now its open fork, OpenTofu) became the lingua franca precisely because one tool and one language — HCL — target all three clouds through providers. Learn the language once, and you can stand up Azure, AWS, and GCP resources from the same repo without relearning three template dialects.
That's why the practitioner advice splits in two, and I mean both halves honestly. Learn Bicep, because it teaches you Azure deeply and it's the cleanest native experience you'll find. But learn Terraform too, because that's what the job postings actually ask for and it's the real cross-cloud equivalent — the thing that lets you carry your infra-as-code skill sideways instead of starting over each time you change employers.
The native tools aren't losers — they win on two real things. First, freshness: when a cloud ships a brand-new resource type, its own native tool supports it on day one, while Terraform providers can lag by days or weeks. Second, zero state management: ARM, CloudFormation, and Deployment Manager all keep their state server-side, so there's no state file for you to store, lock, or secure. Terraform trades that away for portability. If you only touch Azure and you want the least machinery, Bicep is genuinely the better daily driver. If you touch more than one cloud, or you want the resume line hiring managers scan for, Terraform wins. Most working engineers end up fluent in both.
The state difference that trips people up
This is the detail that separates the native tools from Terraform, and it's worth slowing down on. When you deploy an ARM template or a CloudFormation stack, the platform itself remembers what that deployment created. The record of "what exists and who made it" lives on the provider's side. You never see a state file, never store one, never worry about it getting stale or locked while a teammate runs an apply.
Terraform is the opposite: it keeps its own state file, a JSON map of everything it manages. That file is the source of truth, and it's both the power and the footgun of Terraform. Power, because Terraform can reason about the whole graph independent of any one cloud's API. Footgun, because you now own a file that must be stored remotely, locked during writes, and guarded like a secret (it can contain sensitive values). Server-side state is one less thing to break; Terraform's own state is one more thing to run well. Neither is free.
So what should you actually learn?
If you're starting out, learn Bicep first on Azure. The native experience is the clearest way to feel what infrastructure as code even is — you write a file, run one command, watch resources appear in a resource group, change the file, redeploy, watch it converge. No state file to reason about while you're still learning the core loop. That's the class we build it in: Bicep from zero.
Once that loop is muscle memory, pick up Terraform next, because it's what the market runs on and because it forces you to understand state, which the native tools quietly handle for you. Do them in that order and Terraform stops looking like magic — it's the same converge-to-desired-state idea you already learned, plus a provider system and a state file you now manage yourself. The concepts sit on top of what the cloud actually is; the tools are just how you say it.
Common questions
What is the AWS or GCP equivalent of ARM and Bicep?
On AWS the native equivalent is CloudFormation, and CDK is the higher-level authoring layer that maps to Bicep. On GCP the native tool was Deployment Manager, but Google has de-emphasized it and now points you at Terraform, Config Controller, or Infrastructure Manager. So Azure and AWS both have a healthy native infra-as-code story, while GCP's native answer is weak. All three take a template file and create, update, or delete a managed group of resources.
Is Bicep the same as CloudFormation?
They occupy the same slot but sit at different layers. CloudFormation is the raw template engine on AWS, authored in JSON or YAML. Bicep is a friendlier domain-specific language that transpiles down to ARM JSON, so it's closer to AWS CDK in spirit than to raw CloudFormation. The deployed unit differs too: on Azure it's a deployment landing resources into a resource group, and on AWS it's a stack.
Where do native IaC tools keep their state?
ARM/Bicep, CloudFormation, and Deployment Manager all keep state server-side, inside the platform. The cloud remembers what a deployment or stack created, so there's no state file for you to store, lock, or secure. That's the key difference from Terraform, which manages its own state file. Server-side state is one less thing to break; Terraform's own state is both its power and its classic footgun.
Should I learn Bicep or Terraform?
Learn both, in that order. Bicep teaches you Azure deeply and is the cleanest native experience, with same-day support for brand-new resource types and no state file to manage. But the jobs ask for Terraform, because one tool and one language target all three clouds through providers, so it's the real cross-cloud equivalent. Native tools win on freshness and zero state management; Terraform wins on portability and market demand.