Dictionary
Which resource in each provider plays the same part, and when it isn't 1:1. Every name is checked in CI against the real schema of azurerm ~> 5.8, aws ~> 6.67 and google ~> 8.6.
Grouping of accounts/subscriptions/projects
1:1Concept: resource-hierarchyAccount / subscription / project
Not 1:1Concept: resource-hierarchyazurerm_subscription creates an alias for a subscription and needs a billing scope; the resource doesn't "create" the tenant relationship. In GCP, besides creating the project, each API is enabled separately (google_project_service).
Resource container inside the account
No equivalentConcept: resource-hierarchyAn Azure resource group owns the lifecycle of its resources (deleting it deletes them). In AWS, aws_resourcegroups_group is a tag- or stack-based query, not a container; in GCP the closest container is the project itself.
Enabling services before use
No equivalentIn GCP each API is enabled per project and a terraform apply on a new project fails until it is. In Azure the provider registers the resource providers it needs automatically unless you turn that off. AWS has no per-service equivalent step.
Organization-level guardrails
Not 1:1Capability: governance-guardrailsThey limit different things: Azure Policy evaluates resource properties (and can audit, deny or modify), AWS SCPs cap IAM actions, and GCP org policies apply predefined or custom constraints. Definition and assignment are separate resources in Azure and AWS.
Workload identity
Not 1:1Capability: workload-identityaws_iam_role bundles identity, trust policy and (with attached policies) permissions. In Azure and GCP the identity is one resource and permissions are separate role assignments or bindings.
Granting permissions
Not 1:1Capability: access-controlIn GCP every resource has three variants: _iam_policy (authoritative for the whole policy), _iam_binding (authoritative per role) and _iam_member (additive). Mixing an authoritative one with _iam_member on the same resource makes them fight on every apply. In Azure the scope lives on the role assignment itself.
Custom role or policy
Not 1:1Capability: access-controlAn Azure or GCP custom role is a list of actions later assigned on a scope. An AWS policy is a document that can include conditions and specific resources, and it's attached to an identity.
OIDC federation (CI/CD, another cloud)
Not 1:1Capability: external-identity-federationIn Azure each credential is an exact issuer + subject pair on an identity. In AWS the provider is one per URL per account, and trust lives in the role's trust policy. In GCP the pool and provider carry the CEL condition, and access is granted with bindings on a principalSet.
Virtual network
Not 1:1Capability: virtual-networkConcept: network-scopeThe VNet and the AWS VPC are regional; the GCP VPC is global and its subnets are regional.
Subnet
Not 1:1Capability: virtual-networkConcept: network-scopeaws_subnet lives in a single availability zone (availability_zone); the Azure subnet spans the region and the GCP one is regional too. High availability in AWS = one subnet per AZ.
Traffic filtering
Not 1:1Capability: network-filteringThe NSG is associated with subnets or NICs. The AWS security group attaches to network interfaces and is stateful (NACLs are per subnet and stateless). In GCP rules belong to the VPC and target instances by network tags or service accounts.
Routes
Not 1:1Capability: virtual-networkAzure and AWS associate a route table with each subnet. GCP has no per-subnet table: each route is a VPC resource and can target instances by network tags.
Network peering
Not 1:1Capability: virtual-networkIn Azure and GCP you need one resource per side of the peering. In AWS it's one connection the other side accepts (aws_vpc_peering_connection_accepter for another account or region).
Internet egress with NAT
Not 1:1Capability: virtual-networkIn Azure the NAT gateway is associated with the subnet. In AWS it lives in a public subnet and private subnets reach it via a route. In GCP Cloud NAT is a configuration on a Cloud Router.
Private access to a managed service
Not 1:1Capability: private-service-accessaws_vpc_endpoint covers the Interface and Gateway types (vpc_endpoint_type). In GCP it depends on the service: a Private Service Connect endpoint is a forwarding rule, and Cloud SQL's private IP uses private services access (google_service_networking_connection).
Private DNS zone
Not 1:1Capability: private-dnsIn Azure the private zone is its own resource type and is linked to each VNet. In AWS and GCP it's the same resource as a public zone, with a vpc block (AWS) or visibility = private (GCP).
Hybrid DNS forwarding
Not 1:1Capability: dns-forwardingAzure
Azure and AWS model inbound and outbound endpoints. In GCP inbound is a server policy and outbound is a forwarding_config block inside a managed zone.
Managed firewall (the instance)
Not 1:1Capability: managed-firewallAzure Firewall is a resource deployed into the VNet (in its own subnet) and a separate policy holds its rules. Network Firewall creates one endpoint per availability zone in the subnets you give it and the route tables must point at it. In GCP the firewall endpoint is zonal and is associated with each VPC; it inspects nothing until a network firewall policy rule with the apply_security_profile_group action sends it traffic (see firewall-rules).
Managed firewall rules (incl. FQDN filtering)
Not 1:1Capability: egress-fqdn-filteringIn Azure rules live in collection groups of a firewall policy, and FQDN rules can be application or network rules. In AWS domain filtering is a stateful rule group (later referenced from the firewall policy) and Network Firewall uses Suricata. In GCP rules belong to a network firewall policy associated with the VPC, and FQDN objects are a Standard-tier capability.
Network transit hub
Not 1:1Capability: virtual-networkAWS
These are the alternatives to peering when you want transit between spokes: Virtual WAN (the hub is a Microsoft-managed network with its own router), Transit Gateway (attachments with one route table per association and explicit propagation) and Network Connectivity Center (global hub with spokes; VPC spokes exchange subnet routes). The pattern's modules use peering in Azure and GCP (not transitive) and Transit Gateway in AWS: they are not the same topology.
Object storage
Not 1:1Capability: object-storageAzure has one more level: the storage account (network, Shared Key, encryption) with containers inside. In the AWS provider bucket configuration is split into separate resources (aws_s3_bucket_versioning, _public_access_block, _lifecycle_configuration…). In GCP almost everything is a block on the bucket.
Object expiration
Not 1:1Capability: object-lifecycleGCP
In GCP it isn't a separate resource but a lifecycle_rule block inside google_storage_bucket.
Managed PostgreSQL
1:1Capability: managed-postgresFor Aurora PostgreSQL on AWS the resource is aws_rds_cluster (with aws_rds_cluster_instance).
Secrets
Not 1:1Capability: secrets-storeKey Vault is a container with its own access model, and secrets live inside it. In AWS and GCP each secret is a top-level resource and the value is a separate version.
Encryption keys
Not 1:1Capability: key-managementIn GCP key rings and crypto keys can't be deleted: a terraform destroy removes them from state and destroys their versions, but the name stays taken.
Access to a specific secret
Not 1:1Capability: secrets-storeIn Azure data-plane access to the vault is granted with a role assignment (for example Key Vault Secrets User), recommended at vault scope; assigning it on an individual secret is the exception. In AWS you can combine a resource policy on the secret with an identity policy. In GCP the binding (Secret Manager Secret Accessor) can be granted on the secret.
Automatic secret rotation
No equivalentCapability: secrets-storeAzure
No direct equivalent
GCP
Only AWS has a resource that schedules rotation (with a Lambda function for most secrets). In GCP the secret's rotation block only publishes notifications to Pub/Sub and a subscriber has to create the new version. Azure Key Vault has no rotation resource for secrets: it publishes a near-expiry event to Event Grid and a function does the rotation.
Auditing secret access
Not 1:1Capability: secrets-storeIn Azure the vault's resource logs (AuditEvent category) aren't collected until you create a diagnostic setting. In GCP Data Access audit logs are off by default and are turned on with the project's audit config. In AWS CloudTrail records Secrets Manager calls; a trail (aws_cloudtrail) keeps events beyond the 90-day event history.
Message queue
Not 1:1Capability: message-queueService Bus has a namespace (tier, network, authentication) with queues inside. SQS is one resource per queue. Pub/Sub separates topic and subscription, and messages are retained per subscription.
Functions
Not 1:1Capability: event-driven-computeAn Azure Function App needs its own plan and storage account; Lambda and Cloud Functions are a single resource.
Serverless containers
Not 1:1Capability: container-platformContainer Apps separates environment (network, logs) and app. ECS separates cluster, task definition and service. Cloud Run is a single resource per service.
Managed Kubernetes
Not 1:1Capability: managed-kubernetesAKS requires a default node pool as a block inside the cluster. For GKE the provider docs recommend removing the default pool (remove_default_node_pool) and managing pools as separate resources. In EKS node groups are always separate resources.
Linux virtual machine
Not 1:1AWS
In Azure the NIC is a separate resource the VM references; in AWS and GCP the primary interface is declared inside the instance.
Centralized logs
Not 1:1Capability: centralized-loggingIn Azure resource logs don't reach the workspace until you create a diagnostic setting per resource. In GCP logs already land in the project; sinks route them to another bucket or destination.
CDN distribution in front of an origin
Not 1:1Capability: cdn-edgeAzure
In CloudFront a single distribution declares origins, cache behaviors and security. Front Door splits that into profile, origin group, origin and route. GCP has no separate CDN resource: Cloud CDN is enabled on a backend bucket behind an external Application Load Balancer (URL map, HTTPS proxy and forwarding rule), and if it isn't enabled at that step the load balancer serves straight from Cloud Storage with no cache.
Letting only the CDN read the origin
Not 1:1Capability: cdn-edgeAzure
Three different mechanisms. Front Door Premium creates a private endpoint to the storage (the origin's private_link block) and the connection must be approved on the origin side before traffic flows. CloudFront signs every request to S3 with an OAC and the bucket needs a policy that allows the cloudfront.amazonaws.com principal with a condition on the distribution. GCP has no OAC-like resource: you grant read on the bucket to the Cloud CDN service account, which only exists once the first signed URL key is added to the backend bucket.
WAF at the CDN edge
Not 1:1Capability: cdn-edgeIn Front Door the WAF policy is a resource and is tied to the endpoint or domain through a separate security policy; managed rules are Premium only. In CloudFront you create an AWS WAF web ACL and associate it with the distribution. In GCP only Cloud Armor edge security policies (type CLOUD_ARMOR_EDGE) can be applied to backend buckets, and they attach to the backend service.
Time-bound exception to a guardrail
No equivalentCapability: governance-guardrailsAzure Policy has its own exemption object, with a category (waiver or mitigated), an optional expiry (expiresOn; when it passes the object isn't deleted, it just stops being honored) and metadata on who requested and approved it. GCP has no exception object: you set an org policy on the child resource, which replaces the inherited one. AWS has no equivalent resource: an SCP Deny applies to everything under the level where it is attached.
Sending audit logs to a central destination
Not 1:1Capability: centralized-loggingIn AWS an organization trail (is_organization_trail, created from the management account) logs the events of all accounts into a single S3 bucket. In GCP an aggregated sink on the organization or a folder (include_children) routes the logs of everything under it, and its writer identity needs permissions on the destination. In Azure the activity log is per subscription and leaves through a per-subscription diagnostic setting; a management group one doesn't cover every subscription-level event.
Logging data reads and writes
Not 1:1Capability: centralized-loggingAzure
AWS
Data-plane events aren't recorded by default in any cloud. In GCP Data Access audit logs are off (except some BigQuery services) and are enabled per service and type (ADMIN_READ, DATA_READ, DATA_WRITE) at organization, folder or project level; Admin Activity logs can't be turned off. In Azure resource logs are enabled through the categories of a per-resource diagnostic setting. In CloudTrail they are the trail's data events, chosen per resource.