Home / Insights / Cloud Abstraction Layers Fail When They Hide the Wrong Things
Cloud Architecture 5 min read

Cloud Abstraction Layers Fail When They Hide the Wrong Things

I've moved workloads between AliCloud, AWS, Azure, GCP, and bare metal. Every abstraction layer I've met made the same mistake: it hid the cloud primitives and exposed the workflow, when it should have done the opposite.

multi-cloudabstractionplatform-engineeringkubernetesterraformmigration

Every few years someone builds a layer that promises to make the cloud underneath not matter. Sometimes it’s a company. Sometimes it’s an internal platform team with a Helm chart and a dream.

I’ve spent a decade migrating between clouds (AliCloud to GCP at Tokopedia, AWS to GCP at Koo, Azure to GCP for a mobile advertising platform at 4.5M requests per second, on-prem to GKE at Bukalapak, and lately bare-metal Talos alongside GCP for a securities brokerage). Migration is where abstractions get audited, because the day you move is the day you find out what the layer was hiding.

My conclusion, held fairly firmly: abstract the workflow, expose the primitives.

Layer of the stackHide it?Why
Build, artefact promotion, GitOpsHideIdentical everywhere and nobody’s competitive advantage
Identity for humans and workloadsHideGroups, roles and short-lived credentials should be one pattern, not per-team folklore
Secrets request and rotationHideThe failure mode of getting this wrong per-team is a breach, not an inconvenience
Policy applied before creationHideGuardrails as code, e.g. GCP organization policies
Regions and availability zonesExposeLatency profiles do not survive a move, and the app team has to know they exist
Load balancer and TLS terminationExposeWhich hop sees the client IP is a correctness question, not a config detail
Database failover semanticsExposeBehaviour under failover is behaviour under migration
Network egress pathsExposeThe undocumented external dependency is always allowed by a rule nobody remembers writing
IAM edge casesExposeWhere “it worked in staging” comes from

What the good layers hide

The stuff that’s the same everywhere and shouldn’t require thought:

  • How code becomes an artefact and how the artefact reaches an environment. Pipeline templates, GitOps, promotion rules.
  • How identity works for humans and workloads. Groups, roles, short-lived credentials, keyless CI.
  • How secrets are requested and rotated.
  • What policy applies before anything is created. Guardrails as code.
  • Where logs and metrics go by default.

At the brokerage we standardised about 100 applications onto one GitLab CI and ArgoCD workflow with image governance and deployment controls. The apps stopped caring which cluster or which cloud they landed on. That abstraction earned its keep. It hid the workflow.

What the bad layers hide

Cloud primitives. Regions, availability zones, load balancer behaviour, database failover semantics, network egress paths, IAM edge cases.

When a layer hides those, the application team stops knowing they exist. Then you migrate, and:

  • The service that “just talked to the database” was relying on a same-zone latency profile that doesn’t hold in the new region.
  • The load balancer in the new cloud terminates TLS one hop earlier and the app never sees the client IP it was logging for fraud checks.
  • The undocumented external dependency (there’s always one) was allowed by an egress rule that lived in the abstraction’s config, and no one knew.

None of those are the abstraction’s fault, exactly. But the abstraction taught the team not to look.

The migration test

Here’s the check I run on any platform layer: if we had to move this workload to a different cloud in six months, what would the layer have to expose that it currently hides?

If the answer is “nothing, the workflow is portable and the primitives are visible”, good. If the answer is “we’d need to read the layer’s source to find out what it does with networking”, the layer is a liability with nice ergonomics.

Portability is a property of the team, mostly

Real portability came, in my experience, from a few unglamorous things: Terraform for everything, so the primitives had a written form. Standardised runbooks (at Tokopedia we reused them across business units; the “Migration Hero” award was really for the runbooks). Service discovery that didn’t assume a cloud (Consul, at the time). And engineers who understood their dependencies because the platform made them visible rather than convenient.

An abstraction that keeps that knowledge alive is worth building. One that lets it atrophy will cost you exactly once, at the worst possible time.

Common questions

Short, direct answers to what people actually ask about this.

What should a platform abstraction hide, and what should it expose?

Hide the workflow: how code becomes an artefact and reaches an environment, how identity and secrets work, what policy applies before anything is created, where logs and metrics go by default. Expose the primitives: regions, availability zones, load-balancer behaviour, database failover semantics, egress paths and IAM edge cases.

How do you tell whether a platform abstraction is a liability?

Ask what the layer would have to expose if this workload had to move to a different cloud in six months. If the answer is nothing, because the workflow is portable and the primitives are visible, it is sound. If the answer is that you would need to read its source, it is a liability with good ergonomics.

What actually makes a workload portable between clouds?

Unglamorous things, mostly: Terraform for everything so the primitives have a written form, standardised runbooks reusable across teams, service discovery that does not assume a cloud, and engineers who understand their dependencies because the platform made them visible rather than convenient.

Discussion