TL;DR
- Multi-cloud means running workloads across two or more public cloud providers, and it's usually the result of M&A, best-of-breed tooling choices, or compliance needs rather than a planned architecture.
- The hard part isn't running each cloud; it's that AWS, Azure, and GCP model identity, networking, and resources differently, which fragments visibility and breaks change tracking across providers.
- Infrastructure as code is what makes a multi-cloud estate governable: one IaC tool with a provider block per cloud, codified resources, and policy checks that run before deployment, not after.
- Governance, cost control, and disaster recovery need to work consistently across all providers, using a cloud-agnostic policy engine, a unified spend view, and IaC-based recovery rather than three separate playbooks.
- Firefly automates this operational layer across AWS, Azure, GCP, Kubernetes, and connected SaaS platforms: continuous inventory, drift detection, OPA-based guardrails, and Terraform-based recovery, all within a single system of record.
Most companies did not choose multi-cloud in the way a strategy deck implies. They acquired a company that ran on Azure while the parent company ran on AWS. A product team spun up GCP because it wanted BigQuery. A vendor renewal went badly, and procurement brought in a second provider as leverage. Multi-cloud is less often a deliberate architecture decision and more often the accumulated result of normal business activity.
That origin story explains why multi-cloud management is hard in practice: nobody designed for it from day one. This guide starts with what multi-cloud actually means, then goes deep into the operational mechanics that determine whether a multi-cloud estate is governable or just expensive chaos: identity and networking, infrastructure as code, orchestration and workflow design, policy-as-code, cost, and disaster recovery. Where it's useful, this guide shows what that looks like in practice, including how a platform like Firefly approaches each layer.

What Is a Multi-Cloud Environment?
Multi-cloud refers to running workloads across multiple public cloud providers, such as AWS, Azure, and Google Cloud, rather than standardizing on a single provider. The term gets used loosely alongside a few related ones, and the differences show up operationally:
Every hybrid cloud is technically a multi-cloud, since it spans multiple environments. Not every multi-cloud is hybrid, though: plenty of organizations run purely on multiple public clouds with no private infrastructure at all. The distinction that actually affects day-to-day operations is integration: whether those environments share identity, networking, and governance, or sit side by side as separate silos with separate tooling. Once a multi-cloud footprint exists, whether by design or by accumulation, the operational question becomes how to run it deliberately instead of reactively. Our guide on how to employ a multi-cloud strategy walks through that decision in more depth, from provider selection through the governance model that holds it together.
What Counts as Multi-Cloud?
Ask most platform teams what their multi-cloud footprint looks like, and AWS, Azure, and GCP come up first. Ask who still has cluster-admin on the EKS cluster running checkout, or how many of the forty people with Super Admin in Okta actually still need it, and the confidence drops fast.
That gap is the real risk. IAM gets locked down tight across every cloud account. A stray ClusterRoleBinding grants cluster-admin to a service account nobody's touched since last Black Friday, or Okta's admin list still includes someone who left the company months ago. Okta, or whatever identity provider sits in front of the clouds, is what federates access to all of them, so one stale admin account there quietly undoes every IAM policy downstream. Kubernetes RBAC and SaaS admin lists aren't a side project for later. They're part of the multi-cloud estate the moment they can grant access to it.
Why Most Organizations End Up Running Multiple Clouds
A few scenarios show up repeatedly across companies that land in multi-cloud, whether they planned it or not:
- Best-of-breed services. The ML team wants Vertex AI or BigQuery, so a GCP project shows up next to the AWS account everyone else has been deploying to for years, and nobody ever consolidates the two.
- Avoiding lock-in. A company renews its AWS Enterprise Discount Program agreement and negotiates harder on price because half the workload could realistically move to Azure if the numbers no longer work.
- Compliance and data residency. A customer's procurement team requires EU data to remain within the EU, so a SaaS company spins up an Azure region in Frankfurt for that one account, while the rest of the product stays on AWS.
- Redundancy. A payments company runs transaction processing across both AWS and GCP, so a single us-east-1 outage doesn't take checkout down for every customer at once.
- Inherited infrastructure. The company acquires a startup that built its entire product on GCP; the acquirer has run AWS for a decade, and 18 months later, nobody has migrated it because the startup's product still works fine where it is.
Firefly's 2026 State of IaC report found that 63% of organizations now run multi-cloud or hybrid environments, and Flexera's 2026 State of the Cloud report puts hybrid adoption at 73%. Both reports point to the same underlying trend: multi-cloud growth increasingly comes from M&A and siloed application decisions, not top-down architecture.
Where Multi-Cloud Management Gets Genuinely Difficult
The complexity in multi-cloud management doesn't come from any single cloud being hard to run on its own. It comes from AWS, Azure, and GCP, each modeling resources, identity, and networking differently, with none of that translating cleanly across providers.
Fragmented visibility is the first symptom, and it's the one that costs real time during an actual incident. Each provider has its own console, its own API shape, and its own resource taxonomy, so nobody can answer "what's actually running right now" without stitching together three separate exports by hand. A security team responding to a leaked credential might burn the first hour just figuring out which cloud the affected resource even lives in, before containment can start. A useful way to see how granular this problem actually gets is to look at how a governance platform models resource state. Firefly, for example, tracks eight distinct asset states rather than a simple managed-or-unmanaged binary:
This level of granularity exists because drifted and ghost assets are genuinely different problems that require different fixes: reapplying code solves drift, while reconciling state solves ghost assets. A team troubleshooting a failed Terraform apply against a security group that no longer exists is usually looking at a ghost asset, deleted by someone through the console after the last state refresh, not a drift issue that a simple re-apply will fix. Multiply that across three providers with three different native consoles, and spreadsheet-based tracking breaks down fast.
That breakdown isn't hypothetical. Firefly's 2026 State of IaC report found that a third of respondents have tied infrastructure drift to a costly production incident. Nearly 20% have no drift detection or remediation process in place at all, and those numbers are for a single cloud account. Spread the same blind spot across three providers, each with its own console and its own definition of "managed," and the risk doesn't just triple. It compounds, since a tracking gap in one cloud makes the inventory in the other two that much harder to trust.

Identity Federation Is the Next Thing to Break
If fragmented visibility is the first problem, identity federation is the second. AWS IAM, Azure Active Directory, and Google Cloud IAM don't share a permission model: roles, service accounts, and policy boundaries are structured differently in each. Most organizations solve this with a central identity provider (Okta or Azure AD acting as the hub) that federates into each cloud via SSO and SCIM provisioning, so a user's access gets managed once and mapped consistently outward instead of being maintained three separate times.
Worth flagging: the old opening line said identity "breaks first," directly contradicting the earlier section that called fragmented visibility "the first symptom." That contradiction was likely a big part of why the heading felt disconnected, two different sections both claiming to be the "first" problem. The new heading and opening line now explicitly position this as the second problem in the same sequence, so it reads as a continuation of "Where Multi-Cloud Management Gets Genuinely Difficult" instead of a fresh, unrelated topic.

Networking needs equally deliberate design. Common patterns include:
- Site-to-site VPN between cloud VPCs or VNets, for lower-throughput or temporary connectivity.
- Direct interconnects, such as AWS Direct Connect, Azure ExpressRoute, and Google Cloud Interconnect, provide consistent, high-bandwidth links back to on-prem or between clouds.
- Hub-and-spoke transit architectures, where a central transit gateway or virtual WAN routes traffic between cloud environments instead of full-mesh peering, which becomes unmanageable beyond a handful of networks.

Without one of these patterns deliberately chosen, cross-cloud services end up communicating over the public internet with ad hoc security group rules, which is both a latency and a security problem.
Choosing an Infrastructure as Code Strategy for Multi-Cloud
Infrastructure as code makes multi-cloud management repeatable rather than manual. The common pattern is one IaC tool with a separate provider block per cloud, so the same workflow and state discipline apply everywhere:
provider "aws" {
region = "us-east-1"
}
provider "azurerm" {
features {}
}
provider "google" {
project = "example-project"
region = "us-central1"
}
Terraform and OpenTofu dominate this space, but they're not the only options, and the right choice depends on how much cross-cloud abstraction is actually needed:
Writing the code is the easy part. The harder problem is bringing existing, manually created resources under management without breaking them and keeping state in sync afterward. This is where codification comes in: generating IaC for resources that already exist in the cloud, rather than deploying new ones. A team that just inherited or acquired a company's AWS account full of console-built resources doesn't need to hand-write Terraform for every instance and security group; codification generates it from what's already running. The generated code has to include real dependencies (an EC2 instance pulls in its VPC, subnet, and security groups), and for Terraform or OpenTofu specifically, it should use import blocks rather than a plan that would recreate the resource:
import {
to = aws_instance.web_app
id = "i-0abcd1234efgh5678"
}
resource "aws_instance" "web_app" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.medium"
tags = {
Environment = "production"
}
}
Firefly's Codification engine automates this across a wide range of output formats, including Terraform, OpenTofu, Terraform CDK, Terragrunt, CloudFormation, AWS CDK, Crossplane, Kubernetes manifests, Helm charts, CDK8s, Config Connector, ARM templates, Bicep, Ansible, and Pulumi. It packages related resources into reusable modules with variables and outputs, instead of flat, one-off resource blocks. It also handles a specific automation case worth knowing: an aws_instance with a lowercase tag key containing karpenter.sh (for example, karpenter.sh/discovery) gets marked as codified automatically, since Karpenter-managed nodes churn too fast to codify individually. That detection currently works only for AWS EC2, not for GCP or Azure equivalents. For cross-cloud migrations, the same codification flow can generate an equivalent Azure VM or GCP Compute Instance definition from an existing AWS EC2 instance, which is useful when consolidating or rebalancing workloads between providers. For a closer walkthrough of what that consolidated approach looks like end to end - one IaC tool, one governance layer, spanning multiple clouds and multiple IaC formats at once - see our guide on how to tame your cloud across multi-cloud and multi-IaC environments.

Visibility into the IaC layer itself requires a separate view, distinct from the cloud resources it manages. Firefly's IaC Explorer analyzes Terraform, OpenTofu, CloudFormation, Helm, Kustomize, and ArgoCD sources across six views:
Two statuses are worth distinguishing precisely. A stack is "Unsynced" when its state hasn't picked up a change to a module it depends on. A module is "Partially Applied" when it's been updated, but not every dependent stack has caught up yet. They're not interchangeable, and the UI cross-links them, so it's possible to jump from an unsynced stack straight to the module version that caused the unsynced state.

Orchestrating IaC Workflows Across Multiple Clouds
Writing and codifying IaC is only half the picture. The other half is how the plan and application are actually executed safely, especially once multiple teams are deploying across multiple clouds concurrently.
Firefly structures this around Projects and Workspaces. A Project is the organizational and access-control boundary, supporting up to five levels of nested hierarchy (Organization to Project to Sub-Project). A Workspace sits beneath it and hosts the execution environment: VCS settings, variables, and run history for a given IaC configuration. Variables can be defined at multiple levels through Variable Sets, and precedence is resolved from most specific to least specific:
- Workspace-level variables
- Variable Set variables consumed by the workspace
- Sub-Project variables
- Project variables
- Organization-level variables
Execution itself can run through three deployment models: Firefly-Managed Runners (Firefly-managed compute), Self-Hosted Runners (customer-managed, typically required for network isolation or compliance boundaries), or FireflyCI, a CLI and Docker tool that plugs into an existing CI/CD pipeline and forwards plan and apply logs and metadata back to Firefly for visualization and guardrail evaluation. That last option fits teams that already run GitLab CI, GitHub Actions, or Jenkins pipelines and don't want to migrate execution. It lets them keep their existing pipeline and layer governance on top of it rather than replace it.

Enforcing Policy as Code Across Every Cloud
Governance needs to be enforced consistently across providers, not maintained as three separate rulebooks. Open Policy Agent (OPA) and its Rego policy language have become a common standard here precisely because they're cloud-agnostic: the same policy engine evaluates a Terraform plan regardless of which provider it targets. A basic Rego policy checking that S3 buckets have encryption enabled looks like this:
package terraform.s3_encryption
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
not resource.change.after.server_side_encryption_configuration
msg := sprintf("S3 bucket %v is missing server-side encryption", [resource.address])
}
Firefly's Policy & Governance engine runs on OPA under the hood and gives three ways to author policies like this: a no-code Policy Builder for attribute-based or tag-based rules, AI-assisted generation from a plain-English description, or the Rego editor directly, with a testing playground to validate a policy against real assets before it goes live. For shared logic, Rego Packages allow reusable helper modules under a firefly.packages namespace, imported into any policy with import data.firefly.packages.<name>. Editing the package once updates every policy that imports it at the next evaluation, without re-saving each policy individually.
Guardrails are the enforcement layer that sits in front of deployment, evaluating a plan before apply runs. There are exactly four rule types:

A violation can block the deployment outright, alert an administrator, or allow an authorized override in exceptional cases, keeping the model flexible enough to fit both a strict production environment and a faster-moving dev environment. A platform team might set a Tag Rule to hard-block any missing CostCenter tag in the production AWS account, while the same rule only alerts in a short-lived dev environment on GCP, since blocking every dev deploy over a tagging miss slows teams down without reducing real risk. Policies also carry five severity levels (Info, Low, Medium, High, Critical). When something fails, remediation runs one of two paths: IaC Remediation, which opens a PR to fix the underlying code and is the recommended path, or Direct Cloud Remediation via CLI commands, reserved for unmanaged resources or genuine emergencies. Continuous compliance monitoring rolls this up into a compliance score against frameworks like SOC 2, ISO 27001, PCI-DSS, HIPAA, DORA, and CIS benchmarks, alongside a dedicated Resiliency policy category that scores how recoverable the environment actually is, so audit evidence exists on an ongoing basis instead of being assembled manually before every audit cycle.

Building a Cross-Cloud System of Record With Asset Inventory
None of the governance layers above work without a reliable, current inventory underneath them. This is usually the first thing to build and the first thing to break when maintained manually.
Firefly's Cloud Asset Inventory is a searchable, filterable table of every discovered resource, refreshed continuously rather than on a periodic scan schedule. Its scope goes beyond AWS, Azure, and GCP: it also covers Kubernetes clusters and connected SaaS platforms such as Datadog, GitHub, and Okta within a unified view. Each asset carries flags for Policy status, Mutation activity, Comments, Git linkage, GitOps status, and Relationships. Clicking into a resource opens a detail view with Info, Configuration, Mutation Log, Event Viewer, Relationships or an architecture diagram, and Comments, enough context to investigate a resource without pivoting into the native cloud console.

Two practical features round out day-to-day use. Bulk actions let a filtered set of resources be codified or deleted in one pass, rather than one at a time. CSV and JSON export, capped at 10,000 assets per export, covers reporting and offline analysis. Firefly's own docs call this the "system of record" for the environment, and treating it that way, rather than as a point-in-time report, is what keeps the rest of the governance stack accurate.
Tracking Cost and FinOps When Spend Is Scattered
Billing doesn't normalize across providers by default. AWS Cost Explorer, Azure Cost Management, and GCP's billing console each report costs differently, so getting a single number for total cloud spend requires substantial reconciliation.
The waste patterns, though, recur across all providers: idle compute instances, unattached storage volumes, orphaned IP addresses, and stale snapshots nobody remembers creating. A platform team consolidating spend after an acquisition might find thousands of dollars a month sitting in unattached EBS volumes on one account and idle Azure VMs on another, neither one visible until someone builds a cross-cloud view of it. Firefly's Cost Visibility feature tracks spend per resource and surfaces exactly these patterns, with remediation suggestions attached. Combined with the Cost Rules guardrail type described earlier, the practical shift is to catch a spend increase at the IaC plan stage, before it deploys, rather than discovering it on next month's invoice.

That plan-stage check is the real difference between cost governance and cost reporting. Reporting tells a team what happened after the fact. A guardrail set to block anything over a defined dollar or percentage threshold stops the increase from happening in the first place.
Securing and Recovering Infrastructure Across Multiple Clouds
Multi-cloud multiplies attack surface by definition: more consoles, more IAM configurations, more places for a misconfiguration to slip through unnoticed. Drift is a security problem as much as a hygiene one. A resource that's quietly diverged from its IaC definition is a resource nobody's actively reviewing, and an unmanaged resource is, by definition, one nobody explicitly approved.
Recovery posture consistently lags behind how confident teams feel about it. Firefly's 2026 State of IaC report found that only 11% of teams describe their disaster recovery posture as tested and validated, and 30% have little to no confidence that they could restore within their recovery time objective. That gap tends to surface during an actual outage rather than before one, which is the worst possible time to discover it.
Firefly's Applications Backup & DR is specifically designed to address this gap. Backup scope is defined through Application Policies that target resources by tags rather than individual resource selection, with a data source (AWS, Azure, GCP, OCI, and others), region, required tags, and a schedule frequency of On-Demand, Daily, Weekly, or Monthly. A fintech company running payment processing on AWS and internal reporting on Azure can set a tight daily schedule for the payment application and a lighter weekly one for reporting, since the two carry very different recovery time expectations. Implicit dependencies, such as a VPC, subnet, or IAM instance profile pulled in automatically with a targeted resource, aren't backed up as separate line items; they're recreated during restoration instead. Two categories are explicitly not eligible for backup: deleted assets and assets in an undetermined state, since there's nothing reliable to capture.

Restoration itself is the part that differs most from traditional backup tooling. Rather than a direct cloud-level restore or snapshot mutation, the flow generates Terraform code to recreate the resource: open a snapshot, select the resource, choose "Restore Selected," preview the generated Terraform, and continue through the same IaC orchestration flow used for normal deployments. That's a meaningfully different guarantee than an EBS snapshot tool provides. It means rebuilding a known-good environment from code into a clean target, with the same guardrails and review process as any other change, rather than mutating live infrastructure directly during an incident.

Where an AI Layer Fits Into Multi-Cloud Automation
A layer worth understanding on top of all of this is where AI genuinely helps, versus where it's just marketing. Firefly's AI agent, branded Thinkerbell AI, operates in two modes: natural-language Q&A over the full inventory, configuration, and event history (for example, "which IAM users don't have MFA enabled?"), and remediation suggestions for governance or guardrail violations, generating the fix rather than just flagging the problem.

For teams that want to reach that context from their own tooling instead of the Firefly UI, MCP V2 exposes it through the AWS Bedrock AgentCore MCP Gateway. It works the same way across Claude Code, Cursor, and the Claude Desktop app; only the setup step looks slightly different depending on the client. In Claude Code, adding the server is a single CLI command:
claude mcp add --transport http firefly-mcp https://mcpv2.firefly.ai/mcp \
--header "X-access-Key: <your-access-key>" \
--header "X-secret-Key: <your-secret-key>"One practical limitation is worth knowing before building against it: only 30 tools are exposed to a connected client at a time, even though the Gateway backs a larger API surface underneath. Designing an integration around the specific tool set it actually needs works better than assuming full API access through MCP alone. For direct API integration outside of MCP, Firefly's REST API sits at https://api.firefly.ai/v2/ (the v1 API was deprecated in April 2026), authenticated with an access key and secret key pair, and rate-limited to 500 requests per rolling 60-second window per source IP.
How to Evaluate Multi-Cloud Management Tools
Checking a platform against the specific problems multi-cloud creates works better than comparing it to a generic feature list:
Firefly's own integration surface reflects that last point directly. Alerts for drift, ClickOps activity, policy violations, and workflow status route to Slack, Microsoft Teams, PagerDuty, Opsgenie, Torq, Webex, Google Chat, or a generic webhook, so governance shows up where engineers already work instead of a dashboard someone has to remember to check. For the broader operational playbook this evaluation criteria points toward - the pillars that keep governance, cost control, and drift detection working together as a cloud estate grows past a handful of accounts - see our guide to enterprise cloud management.
Multi-Cloud Management Best Practices to Put in Place
- Centralize identity with a single provider and federate outward via SSO and SCIM, rather than managing access 3 times.
- Choose a deliberate network topology, such as hub-and-spoke or direct interconnect, instead of ad hoc peering over the public internet.
- Standardize on one IaC tool and a provider-block pattern across all clouds, and deliberately codify unmanaged resources rather than letting ClickOps accumulate.
- Run policy checks against IaC plans before deployment, using a cloud-agnostic engine like OPA, rather than only against live infrastructure after the fact.
- Track and reconcile cost data across providers on a regular cadence and enforce cost guardrails at the plan stage, not just at renewal.
- Test disaster recovery restoration on a schedule, not just backup completion.
- Treat tagging as an enforced policy with guardrails, not a convention teams follow inconsistently.
- Route governance alerts into the tools teams already use daily, so violations get seen and fixed instead of accumulating in a dashboard.
Multi-Cloud Management Is an Ongoing Discipline, Not a One-Time Setup
Multi-cloud management isn't a project with an end date. Providers add services, teams provision resources outside of code during incidents, and compliance requirements shift underneath an organization that isn't watching closely. The organizations that handle this well treat identity, IaC, policy, cost, and recovery as a continuous discipline built on ongoing scanning and enforcement, not a setup task finished once and revisited during the next audit.
For a deeper look at the IaC and governance mechanics covered here, Firefly's Academy walks through the same concepts in more depth, and the team is available to walk through a specific environment on a demo call.
FAQs
What is multi-cloud management?
Multi-cloud management is the practice of governing identity, infrastructure as code, cost, security, and disaster recovery consistently across two or more public cloud providers, rather than managing each provider separately with its own tools and processes.
What is the difference between multi-cloud and hybrid cloud?
Multi-cloud means using two or more public cloud providers, while hybrid cloud means combining private infrastructure with public cloud. Every hybrid setup is technically multi-cloud, since it spans more than one environment, but a purely multi-cloud setup doesn't have to include any private infrastructure at all.
What is the biggest challenge in multi-cloud management?
Fragmented visibility is the biggest challenge, since AWS, Azure, and GCP each use different consoles, APIs, and resource models, so no unified inventory exists unless a team builds one. That fragmentation is also what makes identity federation, drift detection, and consistent policy enforcement hard to get right across providers.
How does Firefly support multi-cloud management?
Firefly's cloud asset inventory and IaC coverage tracking span AWS, Azure, GCP, Kubernetes, and connected SaaS platforms within a single system of record, rather than a dashboard per provider. Policy-as-code guardrails, drift detection, and Terraform-based recovery then run consistently across that entire footprint.
Does Firefly work with Terraform and OpenTofu across multiple clouds?
Yes, Firefly supports Terraform, OpenTofu, and Terragrunt natively, alongside Pulumi, CloudFormation, and other IaC formats, with a single provider-block pattern that applies the same governance and guardrails regardless of which cloud a given resource sits in.
