Azure, AWS, and Google Cloud Compared
Consider a fictional team moving its AWS platform design to Google Cloud. Its starting design uses organizational units per environment, an account per workload, regional hub-and-spoke networks, and permissions granted per account. Before reproducing those boxes, it must decide which separations express real requirements and which merely reflect the original provider’s resource model.
The providers offer similar building blocks but give them different scopes and authorization behavior. A comparable diagram therefore needs a review of the controls and dependencies behind each box. The comparison below focuses on hierarchy, permissions, and network scope rather than service names.
Container trees that are not the same shape
A resource hierarchy organizes administrative and policy scopes. Its nodes are not interchangeable guarantees of isolation: access, performance, networking, provider failures, and cost attribution can follow different boundaries. Read each tree together with its inherited permissions and shared dependencies.
AWS Organizations groups accounts under one root and nested organizational units, with up to five OU levels below the root. An account contains resources and provides an important administrative scope. Below it, AWS Resource Groups can collect resources by tags or CloudFormation stack membership, and services have their own resource structures. Those groups do not reproduce Azure resource groups’ general RBAC and lifecycle semantics.
Azure places management groups above subscriptions and resource groups below them. Resources belong to resource groups. Management groups can nest up to six levels excluding the root and subscription levels, and each management group or subscription has one parent. These scopes support governance, but the effective access model also depends on the Entra tenant and inherited role assignments.
Google Cloud uses organizations, optional nested folders, projects, and service resources. Folders can nest up to ten levels and contain folders or projects. Projects provide a common resource and API administration scope. Services can add containers within projects: a BigQuery dataset, for example, organizes tables and views and controls access to them.
| AWS | Azure | Google Cloud | |
|---|---|---|---|
| Grouping above the administrative scope | Root and OUs; up to five OU levels below root | Root management group and up to six further management group levels | Organization and optional folders; up to ten folder levels |
| Common administrative scope | Account | Subscription | Project |
| Grouping below that scope | Resource Groups, stacks, and service-specific structures; no exact general ARM resource-group equivalent | Resource groups for resource lifecycle and access grouping | Service-specific containers such as BigQuery datasets; no exact general ARM resource-group equivalent |
| What to verify | IAM grants, cross-account access, billing ownership, and each service quota’s scope | Inherited RBAC, policy scope, billing association, and service-specific quotas | Inherited IAM, shared networks, billing association, API enablement, and quota scope |
Map the function of a grouping before choosing its replacement. Azure resource groups combine management capabilities that may require several mechanisms elsewhere: stacks for deployment lifecycle, resource groups or labels for inventory, and service-level IAM for access. A separate account or project is another option when the required administrative separation justifies it. Compare the operating cost of each arrangement rather than assuming more containers are the only way to preserve the design.
Permissions travel in different directions
For access design, ask what a grant at each level actually permits. Scope inheritance and the permissions contained in a role are separate questions.
Azure roles supported at management group scope can be inherited by resources below it. Custom roles containing DataActions cannot be assigned at that scope, so a plan for organization-wide data access must check the role and supported assignment scope. Google Cloud folder and organization grants also inherit downward. In either case, inheritance grants only the permissions in the role, subject to applicable conditions and restrictions; it does not mean unrestricted access to every kind of resource.
In AWS Organizations, a service control policy attached to a root or OU limits covered member-account principals without granting access. IAM identity-based or resource-based policies supply the grants. This describes the SCP mechanism, not every way an AWS policy can refer to an organization or its resources.
Cross-account access commonly uses either an assumed target-account role or a direct resource-policy grant where supported. Assuming a role uses a new role session rather than adding that role’s permissions to the caller’s original credentials. A direct resource grant uses the external principal instead. Review both role trust and resource policies: the resource-owning account’s SCP does not automatically constrain an external principal using a direct grant.
Compare the mechanisms separately. Inherited role assignments can grant access. SCPs constrain covered principals. Azure Policy evaluates supported resources and actions under its configured modes, conditions, and effects; it is not a general substitute for every IAM deny. Google Cloud deny policies restrict supported permissions. All can support governance, but they do not enforce identical boundaries.
| Does a grant high in the tree give access below? | Can a restriction be imposed from above? | |
|---|---|---|
| AWS Organizations SCP | No permission grant from an SCP; IAM policies provide access | Constrains covered member-account principals, with documented exceptions such as management-account principals and service-linked roles |
| Azure | Supported role assignments inherit; custom roles with DataActions cannot be assigned at management group scope | Azure Policy can enforce supported resource and action rules. Its denyAction effect supports delete, not arbitrary IAM actions. Azure-managed deny assignments are a distinct mechanism and cannot be created directly by users |
| Google Cloud | Organization and folder allow policies inherit their granted permissions | Deny policies can apply at organization, folder, or project scope for supported permissions, subject to their conditions and exceptions |
These permission differences determine which controls carry across the hierarchy and which require a separate decision.
- A permissive SCP can leave existing IAM grants less constrained but does not itself add a grant. An inherited role assignment can directly expand access. Review the actual permissions and affected principals in either change, rather than treating a high-level policy attachment as a uniform operation.
- Giving a platform team production access therefore requires different implementation work. An inherited grant may cover the supported permissions across Azure subscriptions or Google Cloud projects. AWS administrative access commonly uses roles in target accounts and a mechanism to assume them. In each case, check data-access scope, session behavior, audit evidence, and the restrictions that still apply.
- Restriction from above is possible in several forms, but verify the specific operation. A supported Google Cloud IAM deny can block access despite a lower-level allow. Azure Policy includes identity-aware conditions as well as resource evaluation, yet its supported effects and provider modes determine what it can block. Do not infer that it can deny any data read merely because it is assigned at a management group. Test the intended request and any excluded paths.
These differences change how least privilege is implemented. Trace the applicable grants, inherited restrictions, principal identity, and resource policies for the request being evaluated.
In Azure, subscriptions within a management group trust the same Entra tenant. Moving a subscription between management groups changes inherited access and policy and requires impact review; moving it to another tenant is a different operation involving identity relationships. Neither should be inferred from the box layout alone.
A network’s scope is not the same word in all three
All three have a virtual network with subnets. The geographic scope of each differs, and this is the clearest case where a working design cannot be copied.
| Network scope | Subnet scope | |
|---|---|---|
| AWS | Regional | One Availability Zone per subnet |
| Azure | Regional | Spans the region’s availability zones |
| Google Cloud | Global VPC network | Regional subnets |
Read the middle row before assuming the two regional models are equivalent. In AWS the subnet list is the zone layout, so spreading a tier across zones means a subnet per zone; in Azure the same spreading is a property of the resources, and three parallel subnets buy no zone redundancy at all.
If workloads in different AWS or Azure regional networks must communicate, design the connection between those networks. Google Cloud can instead place regional subnets in one global VPC, without peering those subnets. Shared VPC lets eligible resources in service projects use subnets of networks in a host project. A host can contain multiple shared networks; sharing ownership does not require consolidating every workload into one VPC.
Keep multiple Google Cloud VPCs when isolation, ownership, or organizational boundaries require them, and choose their connectivity deliberately. Peering remains useful between distinct VPCs. It becomes unnecessary for the regional subnets only if the design intentionally combines them into one VPC. Conversely, a design using one global VPC needs an explicit regional-network connectivity plan when moved to a provider with regional networks.
Why services with similar names are not substitutes
Comparison tables pair services by name, and the pairing is a reasonable starting point and a poor basis for an estimate. The structural reasons are worth checking explicitly rather than assuming away.
- The scope differs. Whether a thing is global, regional, or zonal decides how many of it you need and what one failure takes down. The network row above is the largest example; identity, load balancing, and DNS have their own answers per provider.
- Isolation and quota scopes differ. Identify whether the relevant limit applies to an account, project, region, network, instance, or another resource. Distinguish adjustable quotas from fixed limits. Resource cleanup, workload tuning, or a quota increase may avoid a split; adding projects will not increase a limit shared by their network.
- What the platform does for you differs, even where the names match. Two services that both run containers may differ on who patches nodes, how scaling to zero behaves, and what identity the workload gets — which is the responsibility question, and the shared responsibility model is where to settle it rather than in a feature matrix.
A practical habit covers most of it: for each service you are pairing, write down its scope, its quota unit, and the operational tasks it leaves with you. Three lines, and they catch the differences a name comparison hides.
What has to be redesigned when you move
Code, data, and foundation configuration each have portability conditions. Open formats help, but engine features, types, identity integrations, and operational contracts can still require redesign. Estimate these layers independently.
| Layer | Travels | Has to be redesigned |
|---|---|---|
| Application code | Mostly, if it was not written against provider SDKs throughout | Anything calling provider-specific APIs, and the identity mechanism the workload uses to get credentials |
| Data | Formats and schemas supported with compatible meaning by the target engine | Unsupported table features, type semantics, catalog integration, validation, and the transfer process |
| Container and account topology | The intent — environment separation, workload isolation | The structure, because the tree shapes differ and the boundary is not at the same level |
| Identity and access model | The policy you meant to express | The mechanism, because inherited allow and assumed roles are not the same design |
| Network topology | Address plans, mostly | Anything assuming a network’s scope — per-region peering, or one global network |
| Guardrails and policy | The rules, as statements | Their implementation and their reach, including which principals are exempt |
Include landing zone work explicitly in the migration estimate: identity, network connectivity, policy implementation, ownership, and operating procedures. Its share of the cost depends on the estate and the target requirements. Application inventories alone may omit this work, while data conversion or application changes can dominate other migrations.
Which is the concrete content of portability as a position. Stating it as an estimated exit cost — foundation redesign, data transfer, dual running, retraining — is more useful than a preference for open tools, and the foundation line is usually the surprising one. Note also that none of this is where data residency gets settled: regions are named per provider and a residency commitment has to be checked against the specific regions and services you are moving to.
Reading a comparison without being misled by it
Most published comparisons are organized by service category, which is the least informative axis available. Structure is more stable than feature lists and decides more of your design, so compare in this order.
- The hierarchy — which administrative and policy scopes exist, and which isolation requirements need additional controls.
- Inheritance — what a grant or a policy at each level actually does, and in which direction.
- Scope — for each foundational resource, whether it is global, regional, or zonal.
- Quota units — what each limit counts, whether it can be adjusted, and which workloads still share it after a proposed split.
- Only then services, paired by the problem they solve rather than by name.
Check current provider documentation when planning against limits or policy behavior. Include the team’s existing skills and the work needed to operate an unfamiliar foundation in total cost of ownership. Weigh those costs against the specific capabilities and requirements rather than assuming either operational familiarity or feature differences always dominate.
Where more than one provider is in use, the way to keep the cost bounded is not to make them look identical — the structures above will not allow it — but to make the common path the easy one: a golden path per provider, owned as a product, which is platform engineering applied to the differences rather than against them.
References:
- AWS Organizations User Guide, Terminology and concepts
- AWS Organizations User Guide, Service control policies
- AWS, Subnets for your VPC
- Microsoft Learn, Organize your resources with management groups
- Microsoft Learn, What is Azure Virtual Network?
- Google Cloud, Resource hierarchy
- Google Cloud, VPC networks
- Google Cloud, Create and manage folders
- Google Cloud, Deny policies
- AWS, Cross account resource access in IAM
- Microsoft Learn, Understand Azure deny assignments
- AWS, Resource Groups
- Google Cloud, BigQuery datasets
- Microsoft Learn, Azure Policy overview
- Microsoft Learn, denyAction effect
- Google Cloud, Shared VPC
- Google Cloud, VPC Network Peering
- Google Cloud, Cloud Quotas
Discover more from Insightful Data Lab
Subscribe to get the latest posts sent to your email.
