Cloud Data Platforms Overview#

Every major cloud provider offers a suite of managed services that together form a complete data platform — ingestion, storage, transformation, orchestration, serving, and governance. Choosing the right combination depends on existing cloud investments, team skills, and specific workload requirements.


AWS Data Stack#

AWS has the broadest set of data services, though the landscape can feel fragmented.

Core Services#

ServiceRoleDescription
S3StorageObject storage — the foundation of every AWS data lake
GlueETL + CatalogueServerless Spark ETL, schema crawler, Data Catalog
AthenaQueryServerless SQL over S3 (Presto/Trino engine)
RedshiftWarehouseMPP columnar warehouse (provisioned or serverless)
Lake FormationGovernanceFine-grained access control, data sharing, lineage
KinesisStreamingData Streams (Kafka-like), Firehose (delivery), Analytics (Flink)
EMRProcessingManaged Spark, Hive, Presto, Flink clusters
Step FunctionsOrchestrationServerless workflow orchestration
MWAAOrchestrationManaged Apache Airflow
MSKStreamingManaged Apache Kafka

AWS Data Lake Architecture#

Sources                     Ingestion              Storage           Transform          Serve
─────────                   ─────────              ───────           ─────────          ─────
RDS (PostgreSQL) ──▶ Glue ETL Job ──▶ S3 (bronze) ──▶ Glue ETL / dbt ──▶ S3 (gold) ──▶ Athena
Kinesis Streams ──▶ Firehose ──────▶ S3 (bronze)                               └──▶ Redshift
Third-party APIs ──▶ Lambda ───────▶ S3 (bronze)                               └──▶ QuickSight

                    Glue Data Catalog (schema registry, table metadata)
                    Lake Formation (access control, permissions)

AWS Glue ETL Job (PySpark)#

import sys
from awsglue.context import GlueContext
from awsglue.job import Job
from awsglue.transforms import *
from pyspark.context import SparkContext

sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(sys.argv[0], {"JOB_NAME": "orders_bronze_to_silver"})

# Read from Glue Data Catalog
orders_dyf = glueContext.create_dynamic_frame.from_catalog(
    database="raw_db",
    table_name="raw_orders"
)

# Transform
orders_df = orders_dyf.toDF()
silver_df = (
    orders_df
    .filter(orders_df.order_id.isNotNull())
    .withColumn("amount", orders_df.amount.cast("decimal(10,2)"))
    .withColumn("order_date", orders_df.order_date.cast("date"))
    .dropDuplicates(["order_id"])
)

# Write to S3 as Parquet, partitioned
silver_df.write \
    .mode("overwrite") \
    .partitionBy("year", "month") \
    .parquet("s3://data-lake/silver/orders/")

job.commit()

Athena Query#

-- Query S3 data via Glue Data Catalog — no infrastructure to manage
SELECT
    order_date,
    COUNT(*) AS order_count,
    SUM(amount) AS total_revenue
FROM silver_db.orders
WHERE year = '2025' AND month = '06'
GROUP BY order_date
ORDER BY order_date;

Athena pricing: $5 per TB scanned. Use Parquet (not CSV) and partition tables to minimise cost.

Lake Formation Permissions#

-- Grant fine-grained access (column-level and row-level)
Grant SELECT on database silver_db
    table orders
    columns (order_id, order_date, amount, status)
    to IAM role data-analyst-role
    with data filter (country = 'GB')

GCP Data Stack#

GCP centres around BigQuery as the universal analytics engine, with a tightly integrated ecosystem.

Core Services#

ServiceRoleDescription
GCSStorageObject storage (Google Cloud Storage)
BigQueryWarehouse + LakeServerless analytics, also supports external tables
DataflowProcessingManaged Apache Beam (batch + streaming)
Pub/SubMessagingFully managed pub/sub messaging
DataprocProcessingManaged Spark/Hadoop clusters
Cloud ComposerOrchestrationManaged Apache Airflow
Data CatalogGovernanceMetadata management, tagging, search
DataformTransformationdbt-like SQL transformations (acquired by Google)

GCP Data Pipeline#

Cloud SQL / APIs ──▶ Dataflow ──▶ GCS (bronze) ──▶ Dataform / dbt ──▶ BigQuery (gold)
Pub/Sub ──────────▶ Dataflow ──▶ BigQuery (streaming insert)
                                                                └──▶ Looker (BI)

Dataflow (Apache Beam) Example#

import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions

options = PipelineOptions([
    "--runner=DataflowRunner",
    "--project=my-gcp-project",
    "--region=europe-west1",
    "--temp_location=gs://my-bucket/temp/",
])

with beam.Pipeline(options=options) as p:
    (
        p
        | "Read from Pub/Sub" >> beam.io.ReadFromPubSub(topic="projects/my-project/topics/orders")
        | "Parse JSON" >> beam.Map(lambda msg: json.loads(msg))
        | "Filter valid" >> beam.Filter(lambda order: order.get("amount", 0) > 0)
        | "Window" >> beam.WindowInto(beam.window.FixedWindows(300))  # 5-minute windows
        | "Count per status" >> beam.combiners.Count.PerKey(lambda order: order["status"])
        | "Write to BigQuery" >> beam.io.WriteToBigQuery(
            table="my_project:analytics.order_counts",
            schema="status:STRING,count:INTEGER",
            write_disposition=beam.io.BigQueryDisposition.WRITE_APPEND,
        )
    )

Azure Data Stack#

Azure organises data services around Synapse Analytics as the unified experience.

Core Services#

ServiceRoleDescription
ADLS Gen2StorageAzure Data Lake Storage (built on Blob Storage)
Synapse AnalyticsWarehouse + SparkUnified: SQL pools, Spark pools, pipelines
Data FactoryETL/OrchestrationVisual ETL and orchestration (similar to Glue)
Event HubsStreamingKafka-compatible event ingestion
Stream AnalyticsStreamingSQL over streaming data
Databricks (Azure)ProcessingManaged Databricks on Azure
PurviewGovernanceData catalog, lineage, classification

Azure Data Pipeline#

SQL Server / APIs ──▶ Data Factory ──▶ ADLS Gen2 (bronze) ──▶ Synapse Spark / dbt ──▶ Synapse SQL pool (gold)
Event Hubs ─────────▶ Stream Analytics ──▶ ADLS Gen2 / Synapse                       └──▶ Power BI
                                                                                       
                     Purview (catalog, lineage, governance)

Platform Comparison#

AspectAWSGCPAzure
WarehouseRedshiftBigQuerySynapse SQL
Serverless queryAthenaBigQuerySynapse Serverless SQL
ETL engineGlue (Spark)Dataflow (Beam)Data Factory + Synapse Spark
OrchestrationMWAA (Airflow), Step FunctionsCloud Composer (Airflow)Data Factory, Synapse Pipelines
StreamingKinesis, MSK (Kafka)Pub/Sub, DataflowEvent Hubs, Stream Analytics
GovernanceLake FormationData CatalogPurview
BI integrationQuickSightLookerPower BI
SparkEMR, GlueDataprocSynapse Spark, Databricks
StrengthsBreadth, maturity, flexibilityBigQuery simplicity, AI/MLEnterprise integration, Power BI
WeaknessService sprawl, complex IAMFewer services, GCP lock-inSynapse complexity

Choosing a Platform#

Decision Factors#

FactorGuidance
Existing cloud providerUse the data services of your primary cloud — avoid multi-cloud complexity unless necessary
Team skillsSQL-first teams → BigQuery or Snowflake; Spark teams → EMR or Databricks
ScaleAll three scale to petabytes; choose based on cost model and operational preference
Streaming needsKafka (MSK) for high throughput; Pub/Sub for simplicity; Event Hubs for Azure
BI toolPower BI → Azure; Looker → GCP; QuickSight or Tableau → AWS
Governance maturityLake Formation (AWS), Purview (Azure), or Unity Catalog (Databricks)
Multi-cloudSnowflake or Databricks — both run on all three clouds

Multi-Cloud Options#

ToolRuns OnBest For
SnowflakeAWS, GCP, AzureMulti-cloud warehouse, data sharing
DatabricksAWS, GCP, AzureMulti-cloud lakehouse, ML
dbtAny warehousePortable transformations
AirflowAny cloud (self-hosted or managed)Portable orchestration
Apache KafkaAny cloud (self-hosted or Confluent Cloud)Portable streaming

Common Architecture Patterns#

Lakehouse on AWS: S3 + Glue Catalog + Delta Lake/Iceberg + Athena/Redshift Spectrum + dbt + Airflow (MWAA)

Lakehouse on GCP: GCS + BigQuery (with external tables) + Dataform/dbt + Cloud Composer

Lakehouse on Databricks (any cloud): Object storage + Delta Lake + Unity Catalog + Databricks SQL + Databricks Workflows


Key Takeaways#

  1. AWS offers the broadest set of data services (Glue, Athena, Redshift, Kinesis, EMR, Lake Formation) but requires more architecture decisions due to service overlap
  2. GCP centres around BigQuery as a unified serverless warehouse — simple, powerful, and tightly integrated with Dataflow and Looker
  3. Azure provides Synapse Analytics as a unified experience combining SQL pools, Spark, and pipelines, with strong Power BI and enterprise integration
  4. Snowflake and Databricks run on all three clouds, offering portability and avoiding lock-in — consider them when multi-cloud is a requirement
  5. Choose based on existing investments — the best platform is the one your team already knows, integrated with the cloud you already use
  6. The core pattern is consistent across all clouds: object storage (lake) → catalogue (metadata) → compute engine (warehouse/Spark) → orchestrator (Airflow/native) → BI tool — the services differ but the architecture is the same