Architecture kata · K—02

Open Lakehouse with Data Contracts and a Shared Semantic Layer

Architecture kata · design study on a fictional brief

Sector
E-commerce group
Technologies
Apache Iceberg, Apache Polaris, Trino, OpenMetadata, Open Policy Agent, Apache Airflow, dbt, Keycloak
Flow: brand engines write Iceberg tables to regional buckets via one REST catalog; a compiled metric layer serves consumers.
The design at a glance: the one-page, 30-minute live drawing.

In short

Six brands keep their query engines, shared data is written once as an open table, guarded by a contract in CI and one metric definition.

Problem

An e-commerce holding has six brands acquired over eight years. Each brand has its own data stack: two on BigQuery, two on Snowflake, one on Databricks and one on an on-premises PostgreSQL warehouse. Group finance consolidates monthly in spreadsheets, and the numbers never match brand dashboards, because “net revenue” is defined differently in each brand. Brands will not accept a forced migration. The group will not accept a seventh copy of the data. Three brands operate in the EU, two in the UK and one in Türkiye, so personal data must stay in its region.

Approach

The design makes the table format and catalog independent of the engines, and the metric definition independent of any SQL dialect. Each shared data product is produced in the owning brand’s engine and written once to a regional bucket as an Apache Iceberg table. One REST Iceberg catalog, Apache Polaris or Lakekeeper, lets all four engines read the same table. A contract lives next to the table and blocks breaking changes in CI. Metrics are defined once in YAML and compiled for each engine.

Architecture

  • Tables and catalog: Iceberg in regional object storage, with one REST catalog and short-lived credentials per engine.
  • One writer per table: the owner’s engine. A policy in Open Policy Agent rejects commits from any other principal.
  • Contracts: Open Data Contract Standard YAML with schema, PII class, SLA, owner and chargeback label. A post-commit job tags a snapshot as verified, and consumers read only verified snapshots.
  • Semantic layer: a compiler turns the metric spec into BigQuery, Snowflake, Databricks and Trino SQL. Power BI, Looker, notebooks and an LLM assistant use one metric API.
  • Regions and catalog: regional Trino pools aggregate data. OpenMetadata shows lineage, freshness and contract status.
Architecture: brand engines write Iceberg tables to regional buckets via one REST catalog; one metric layer serves readers.
Solution overview: producing brands, the REST catalog, regional buckets, contract CI, the semantic layer, consumer engines and group finance consolidation.Open full size (opens in new tab)

Why these components

Need Choice Why
Open table format Apache Iceberg All four engines read it, and the standard REST catalog protocol they implement is Iceberg’s. Atomic snapshots, schema evolution, row-level deletes for erasure. Delta and Hudi lack an equal neutral catalog protocol: capability, not licence.
Catalog Apache Polaris or Lakekeeper, both Iceberg REST One catalog with a warehouse per region and short-lived, table-scoped credentials for each engine. OPA policy applies here. Per-engine catalogs like Glue, Unity or BigLake metastore would mean three permission models.
Regional storage Cloud Storage in the EU, S3-compatible in the UK, Ceph RGW on premises in Türkiye Data stays in its region, with one KMS key per region. Files are written once and never copied, so there is no seventh copy. Ceph over MinIO, given its licence and distribution doubts.
Cross-brand and group query engine Trino Iceberg connector, OPA row and column policies and a pool per region. It is also the on-premises brand’s writer. Spark would work, but Trino suits interactive, federated queries better. Athena is commercial and single-cloud.
Data contract Open Data Contract Standard YAML with CI Schema, PII class, SLA, owner, version and chargeback label live with the table. CI blocks breaking changes before merge; a post-commit job tags snapshots. A catalogue entry filled in afterwards is not a contract.
Transformation dbt Core or Dataform The tools the brands already use, with model and contract in one repository and lineage for free. A new tool would be a migration in disguise. dbt Cloud and Semantic Layer stay out on purpose.
Semantic layer Open metric spec in YAML, a custom compiler, a metric API One definition outside the engines, compiled into four SQL dialects and checked by a conformance suite. Power BI models or LookML tie it to one tool; dbt Semantic Layer depends on dbt Cloud.
Metadata catalogue OpenMetadata Lineage from dbt and Iceberg snapshots, freshness against SLA, contract status and version notices. Apache 2.0. DataHub was a candidate, but OpenMetadata’s quality and contract features are more mature.
Policy Open Policy Agent One policy bundle in the catalog and in Trino: the single-writer rule, masking by region and role, and aggregate-only access for the group principal. Apache Ranger is heavier and centred on Hadoop.
Identity Keycloak OpenID Connect for people and for engine service principals. One principal per brand and region, and a separate group principal.
Orchestration Apache Airflow Group jobs only: regional aggregation, consolidation, reconciliation and the conformance suite. Brand pipelines stay in their own schedulers.
Observability, secrets and delivery Prometheus, Grafana, Loki, Tempo, OpenTelemetry; OpenBao; Argo CD Contract breaches, freshness, read latency per engine, chargeback and conformance drift on one dashboard. GitOps runs three regions from one repository. OpenBao, because HashiCorp Vault moved to BSL.

Decisions and trade-offs

  • Federate, do not migrate. Six brands built teams and tools over eight years, and they reject a migration. If a migration failed, group data would sit empty for two years. One open format and one catalog give one truth and one copy without that risk. The cost is supporting four SQL dialects and four engines.
  • One open catalog, not one per engine. The REST catalog is the common denominator of the four engines. Per-engine catalogs would mean three policy engines and three permission models. The cost is a catalog the group must operate. If it goes down, no new commits land, but engines keep reading the snapshots they already have.
  • Single-writer rule. Each table has one writer: the owning brand’s engine, and OPA rejects any other commit. Concurrent multi-engine writes would promise a consistency no engine guarantees, so I promise no cross-engine transactions. The cost is handling brands that run two engines during a transition.
  • Pinned, verified snapshots. “Consistent across four engines” means the same snapshot, the same files, the same number. Consumers read the snapshot tagged as verified, not the latest one. If a brand renames a column and skips CI, the new snapshot stays untagged. The dashboard shows a stale but correct figure with its freshness stamp, never a wrong one.
  • Conformance suite. It runs each metric on four engines against one snapshot and compares to the cent. A dialect drift fails the suite and blocks that spec version. The cost: the group may have to write and maintain its own compiler.
  • Residency in the architecture, not in a policy. Row-level personal data never leaves its region. Regional Trino pools aggregate, and the group principal sees only tables classed as aggregate without PII. Row-level tables are not even visible to it. The cost is that cross-region analysis works only on aggregates.
Flow: readers pin one snapshot, one writer owns each table, and a CI gate blocks breaking contract changes.
Produce once, commit once, check, publish, consume from any engine and consolidate: one table per product, one writer, one catalog, one metric spec compiled per engine.Open full size (opens in new tab)

What I would revisit

  • Native writes per engine. Which engine versions can write to the Iceberg REST catalog directly? BigLake and Snowflake support depends on the version, and a brand without it needs Trino as its writer.
  • Semantic spec maturity. Is there a ready open-source compiler, or does the group write its own and open it?
  • Two engines in one brand. During a transition, is a temporary second writer acceptable, or is a writer change a new contract version?
  • Disconnected Turkish region. How many hours can the on-premises brand’s commits wait if the EU control plane is unreachable?

Outcome notes (design assumptions, not measurements)

This is a design exercise, not a running platform. The output is a four-page diagram set, a one-page whiteboard version and a 16-page Turkish PDF. The two-day finance consolidation and the 0.1% reconciliation tolerance are targets from the brief and the design.

Sources

  • Architecture PDF (Turkish, 16 pages).
  • draw.io diagrams (English labels): four-page set and a one-page 30-minute version.

Real projects on this topic

  1. P—01

    Completed

    Featured

    Enterprise Data Warehouse Migration to Google BigQuery

    80 TB warehouse moved from SQL Server and a 15-node Cloudera cluster to BigQuery: $550K annual savings, 75% lower infrastructure cost, 7x faster workflows.

    • Data platform
    • Data quality
    • Analytics-ready data
    • Orchestration
    • Cloud

    Role

    Design and lead · Senior Data Engineering & Data Architecture Group Manager

  2. P—08

    Completed

    Data Governance, Metadata Management and MDM

    Data governance, metadata management and master data management (MDM) across 100+ source systems, with data catalog and lineage tooling.

    • Data governance
    • Data lineage
    • Data quality

    Role

    Implementation · Big Data Management & Data Architecture Manager

Reliable data: projects, katas and publications

About the katas

Write to me about a similar design problem.