
google-cloud-data-engineering-hub
Production-grade GCP data engineering projects using BigQuery, Dataflow, Beam, Composer, Pub/Sub, Dataproc, and Vertex AI
- Installs
- 1.1K
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/reason-machines/data-skills --skill google-cloud-data-engineering-hub- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads google-cloud-data-engineering-hub automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Google Cloud Data Engineering Hub Skill
Skill by ara.so — Data Skills collection
This skill enables AI coding agents to help developers build production-grade Google Cloud Platform (GCP) data engineering solutions using this comprehensive reference repository of 54+ working projects covering BigQuery, Dataflow, Apache Beam, Cloud Composer, Pub/Sub, Dataproc, Gemini AI, and Vertex AI.
What This Project Provides
A curated collection of complete, runnable GCP data engineering projects. Each project includes:
- Modular Python code (not scripts)
- ASCII architecture diagrams
- Sample data fixtures
deploy.shwith GCP setup automation- End-to-end working examples tested against live GCP environments
Built by Vishal Bulbule (Google Developer Expert, 12x GCP Certified).
Installation & Setup
Clone the Repository
git clone https://github.com/vishal-bulbule/google-cloud-data-engineering-hub.git
cd google-cloud-data-engineering-hub
Prerequisites
- Python 3.10+
- Google Cloud SDK (
gcloudCLI) - Active GCP project with billing enabled
- Appropriate IAM permissions
Environment Setup
# Set up Python virtual environment
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies (per project)
cd <project-directory>
pip install -r requirements.txt
# Configure GCP credentials
export GOOGLE_CLOUD_PROJECT=your-project-id
export GOOGLE_CLOUD_LOCATION=us-central1
gcloud auth application-default login
Project Categories & Key Examples
BigQuery Projects (01-07)
CSV Ingestion Pipeline (01-bq-csv-ingestion-pipeline)
from google.cloud import bigquery
def load_csv_to_bigquery(
project_id: str,
dataset_id: str,
table_id: str,
csv_file_path: str
):
"""Load CSV from local disk to BigQuery."""
client = bigquery.Client(project=project_id)
table_ref = f"{project_id}.{dataset_id}.{table_id}"
job_config = bigquery.LoadJobConfig(
source_format=bigquery.SourceFormat.CSV,
skip_leading_rows=1,
autodetect=True,
write_disposition=bigquery.WriteDisposition.WRITE_TRUNCATE,
)
with open(csv_file_path, "rb") as source_file:
job = client.load_table_from_file(
source_file,
table_ref,
job_config=job_config
)
job.result() # Wait for completion
print(f"Loaded {job.output_rows} rows into {table_ref}")
UPSERT/MERGE Pattern (03-bq-upsert-merge-pattern)
from google.cloud import bigquery
def upsert_data(project_id: str, dataset_id: str, table_id: str):
"""Perform MERGE operation for upsert pattern."""
client = bigquery.Client(project=project_id)
merge_query = f"""
MERGE `{project_id}.{dataset_id}.{table_id}` AS target
USING `{project_id}.{dataset_id}.staging_table` AS source
ON target.id = source.id
WHEN MATCHED THEN
UPDATE SET
name = source.name,
value = source.value,
updated_at = CURRENT_TIMESTAMP()
WHEN NOT MATCHED THEN
INSERT (id, name, value, created_at, updated_at)
VALUES (source.id, source.name, source.value,
CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP())
"""
query_job = client.query(merge_query)
result = query_job.result()
print(f"MERGE completed. Rows modified: {result.total_rows}")
BigQuery ML (05-bq-ml-train-predict)
from google.cloud import bigquery
def train_ml_model(project_id: str, dataset_id: str):
"""Train a logistic regression model using BigQuery ML."""
client = bigquery.Client(project=project_id)
training_query = f"""
CREATE OR REPLACE MODEL `{project_id}.{dataset_id}.classification_model`
OPTIONS(
model_type='LOGISTIC_REG',
input_label_cols=['label'],
max_iterations=10
) AS
SELECT
feature1,
feature2,
feature3,
label
FROM `{project_id}.{dataset_id}.training_data`
"""
job = client.query(training_query)
job.result()
print("Model training completed")
def predict_with_model(project_id: str, dataset_id: str):
"""Make predictions using trained BQML model."""
client = bigquery.Client(project=project_id)
prediction_query = f"""
SELECT
*
FROM ML.PREDICT(
MODEL `{project_id}.{dataset_id}.classification_model`,
(SELECT feature1, feature2, feature3
FROM `{project_id}.{dataset_id}.prediction_data`)
)
"""
results = client.query(prediction_query).to_dataframe()
return results
Cloud Storage Projects (08-10)
File Management (08-gcs-file-management)
from google.cloud import storage
def upload_blob(bucket_name: str, source_file: str, destination_blob: str):
"""Upload a file to GCS."""
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(destination_blob)
blob.upload_from_filename(source_file)
print(f"File {source_file} uploaded to {destination_blob}")
def list_blobs_with_prefix(bucket_name: str, prefix: str):
"""List all blobs with a specific prefix."""
storage_client = storage.Client()
blobs = storage_client.list_blobs(bucket_name, prefix=prefix)
return [blob.name for blob in blobs]
def copy_blob(bucket_name: str, blob_name: str,
destination_bucket: str, destination_blob: str):
"""Copy a blob within or across buckets."""
storage_client = storage.Client()
source_bucket = storage_client.bucket(bucket_name)
source_blob = source_bucket.blob(blob_name)
dest_bucket = storage_client.bucket(destination_bucket)
source_bucket.copy_blob(source_blob, dest_bucket, destination_blob)
print(f"Blob {blob_name} copied to {destination_blob}")
Signed URLs & Lifecycle (09-gcs-signed-urls-lifecycle)
from google.cloud import storage
from datetime import timedelta
def generate_signed_url(bucket_name: str, blob_name: str,
expiration_minutes: int = 15):
"""Generate a v4 signed URL for secure access."""
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(blob_name)
url = blob.generate_signed_url(
version="v4",
expiration=timedelta(minutes=expiration_minutes),
method="GET"
)
return url
def set_lifecycle_policy(bucket_name: str):
"""Set lifecycle rules for storage cost optimization."""
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
lifecycle_rules = [
{
"action": {"type": "SetStorageClass", "storageClass": "NEARLINE"},
"condition": {"age": 30, "matchesPrefix": ["archive/"]}
},
{
"action": {"type": "Delete"},
"condition": {"age": 365, "matchesPrefix": ["temp/"]}
}
]
bucket.lifecycle_rules = lifecycle_rules
bucket.patch()
print(f"Lifecycle policy set for bucket {bucket_name}")
Pub/Sub Streaming (31-pubsub-streaming-pipeline)
from google.cloud import pubsub_v1
import json
def publish_messages(project_id: str, topic_name: str, messages: list):
"""Publish messages to Pub/Sub topic."""
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path(project_id, topic_name)
futures = []
for message in messages:
message_json = json.dumps(message)
future = publisher.publish(
topic_path,
message_json.encode("utf-8"),
origin="data-pipeline",
priority="high"
)
futures.append(future)
# Wait for all messages to publish
for future in futures:
future.result()
print(f"Published {len(messages)} messages to {topic_name}")
def subscribe_messages(project_id: str, subscription_name: str,
callback_fn, timeout: int = None):
"""Subscribe and process messages from Pub/Sub."""
subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path(
project_id, subscription_name
)
flow_control = pubsub_v1.types.FlowControl(
max_messages=100,
max_bytes=10 * 1024 * 1024, # 10MB
)
streaming_pull_future = subscriber.subscribe(
subscription_path,
callback=callback_fn,
flow_control=flow_control
)
print(f"Listening for messages on {subscription_path}...")
try:
streaming_pull_future.result(timeout=timeout)
except KeyboardInterrupt:
streaming_pull_future.cancel()
# Example callback
def message_callback(message):
"""Process received message."""
print(f"Received: {message.data.decode('utf-8')}")
message.ack()
Apache Beam / Dataflow (47-50)
Basic Beam Pipeline (47-beam-data-transformation)
import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions
def run_word_count_pipeline(input_path: str, output_path: str):
"""Classic WordCount example with Beam."""
options = PipelineOptions()
with beam.Pipeline(options=options) as pipeline:
(pipeline
| 'Read' >> beam.io.ReadFromText(input_path)
| 'Split' >> beam.FlatMap(lambda line: line.split())
| 'PairWithOne' >> beam.Map(lambda word: (word, 1))
| 'GroupAndSum' >> beam.CombinePerKey(sum)
| 'Format' >> beam.Map(lambda kv: f"{kv[0]}: {kv[1]}")
| 'Write' >> beam.io.WriteToText(output_path)
)
def csv_transform_pipeline(input_file: str, output_file: str):
"""Transform CSV data with Beam."""
def parse_csv(line):
import csv
from io import StringIO
reader = csv.DictReader(StringIO(line))
return next(reader)
def transform_record(record):
return {
'id': record['id'],
'name': record['name'].upper(),
'value': float(record['value']) * 1.1,
'processed': True
}
options = PipelineOptions()
with beam.Pipeline(options=options) as pipeline:
(pipeline
| 'Read CSV' >> beam.io.ReadFromText(input_file, skip_header_lines=1)
| 'Parse' >> beam.Map(parse_csv)
| 'Transform' >> beam.Map(transform_record)
| 'Format JSON' >> beam.Map(lambda x: json.dumps(x))
| 'Write' >> beam.io.WriteToText(output_file)
)
Beam to BigQuery (48-beam-csv-to-bigquery-load)
import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions
from apache_beam.io.gcp.bigquery import WriteToBigQuery
def csv_to_bigquery_pipeline(
input_file: str,
project_id: str,
dataset_id: str,
table_id: str
):
"""Load CSV to BigQuery using Beam."""
table_spec = f"{project_id}:{dataset_id}.{table_id}"
table_schema = {
'fields': [
{'name': 'id', 'type': 'INTEGER', 'mode': 'REQUIRED'},
{'name': 'name', 'type': 'STRING', 'mode': 'REQUIRED'},
{'name': 'value', 'type': 'FLOAT', 'mode': 'NULLABLE'},
{'name': 'timestamp', 'type': 'TIMESTAMP', 'mode': 'REQUIRED'}
]
}
def parse_csv_row(line):
parts = line.split(',')
return {
'id': int(parts[0]),
'name': parts[1],
'value': float(parts[2]),
'timestamp': parts[3]
}
options = PipelineOptions()
with beam.Pipeline(options=options) as pipeline:
(pipeline
| 'Read CSV' >> beam.io.ReadFromText(input_file, skip_header_lines=1)
| 'Parse Rows' >> beam.Map(parse_csv_row)
| 'Write to BigQuery' >> WriteToBigQuery(
table_spec,
schema=table_schema,
write_disposition=beam.io.BigQueryDisposition.WRITE_TRUNCATE,
create_disposition=beam.io.BigQueryDisposition.CREATE_IF_NEEDED
)
)
Advanced Beam Patterns (49-beam-advanced-patterns)
import apache_beam as beam
from apache_beam import window
from apache_beam.transforms.trigger import AfterWatermark, AfterCount
def windowing_pipeline(input_subscription: str, output_table: str):
"""Event-time windowing with late data handling."""
class ParseEvent(beam.DoFn):
def process(self, element):
import json
from datetime import datetime
data = json.loads(element)
timestamp = datetime.fromisoformat(data['timestamp'])
yield beam.window.TimestampedValue(
data,
timestamp.timestamp()
)
options = PipelineOptions()
with beam.Pipeline(options=options) as pipeline:
events = (pipeline
| 'Read from Pub/Sub' >> beam.io.ReadFromPubSub(
subscription=input_subscription)
| 'Parse Events' >> beam.ParDo(ParseEvent())
)
windowed = (events
| 'Apply Window' >> beam.WindowInto(
window.FixedWindows(60), # 1-minute windows
trigger=AfterWatermark(early=AfterCount(10)),
allowed_lateness=300, # 5-minute late data
accumulation_mode=beam.trigger.AccumulationMode.ACCUMULATING
)
)
(windowed
| 'Count by Key' >> beam.CombinePerKey(sum)
| 'Format Output' >> beam.Map(lambda kv: {'key': kv[0], 'count': kv[1]})
| 'Write to BigQuery' >> beam.io.WriteToBigQuery(output_table)
)
def branching_pipeline_with_dead_letter():
"""Branching with side outputs and dead-letter queue."""
class ValidateAndRoute(beam.DoFn):
OUTPUT_TAG_VALID = 'valid'
OUTPUT_TAG_INVALID = 'invalid'
def process(self, element):
try:
if self.is_valid(element):
yield element
else:
yield beam.pvalue.TaggedOutput(
self.OUTPUT_TAG_INVALID,
{'error': 'validation_failed', 'data': element}
)
except Exception as e:
yield beam.pvalue.TaggedOutput(
self.OUTPUT_TAG_INVALID,
{'error': str(e), 'data': element}
)
def is_valid(self, element):
return 'id' in element and 'value' in element
options = PipelineOptions()
with beam.Pipeline(options=options) as pipeline:
results = (pipeline
| 'Read' >> beam.io.ReadFromText('input.txt')
| 'Validate' >> beam.ParDo(ValidateAndRoute()).with_outputs(
ValidateAndRoute.OUTPUT_TAG_INVALID,
main=ValidateAndRoute.OUTPUT_TAG_VALID
)
)
# Main path
(results[ValidateAndRoute.OUTPUT_TAG_VALID]
| 'Process Valid' >> beam.Map(lambda x: x)
| 'Write Valid' >> beam.io.WriteToText('valid_output')
)
# Dead-letter queue
(results[ValidateAndRoute.OUTPUT_TAG_INVALID]
| 'Format Errors' >> beam.Map(lambda x: json.dumps(x))
| 'Write DLQ' >> beam.io.WriteToText('dead_letter_queue')
)
Cloud Composer / Airflow (51-54)
Basic DAG (51-cloud-composer-dag-basics)
from airflow import DAG
from airflow.operators.python import PythonOperator, BranchPythonOperator
from airflow.operators.dummy import DummyOperator
from airflow.utils.task_group import TaskGroup
from datetime import datetime, timedelta
default_args = {
'owner': 'data-eng-team',
'depends_on_past': False,
'start_date': datetime(2024, 1, 1),
'email_on_failure': True,
'email_on_retry': False,
'retries': 2,
'retry_delay': timedelta(minutes=5),
}
def extract_data(**context):
"""Extract data from source."""
data = {'records': 1000, 'source': 'api'}
context['ti'].xcom_push(key='extract_result', value=data)
return data
def decide_branch(**context):
"""Branch based on extracted data volume."""
ti = context['ti']
data = ti.xcom_pull(key='extract_result', task_ids='extract')
if data['records'] > 500:
return 'process_large'
else:
return 'process_small'
with DAG(
'data_pipeline_basic',
default_args=default_args,
schedule_interval='@daily',
catchup=False,
tags=['data-engineering', 'example']
) as dag:
start = DummyOperator(task_id='start')
extract = PythonOperator(
task_id='extract',
python_callable=extract_data,
provide_context=True
)
branch = BranchPythonOperator(
task_id='branch',
python_callable=decide_branch,
provide_context=True
)
process_large = PythonOperator(
task_id='process_large',
python_callable=lambda: print("Processing large dataset")
)
process_small = PythonOperator(
task_id='process_small',
python_callable=lambda: print("Processing small dataset")
)
end = DummyOperator(
task_id='end',
trigger_rule='none_failed_min_one_success'
)
start >> extract >> branch >> [process_large, process_small] >> end
BigQuery Pipeline (52-composer-bigquery-pipeline)
from airflow import DAG
from airflow.providers.google.cloud.sensors.gcs import GCSObjectExistenceSensor
from airflow.providers.google.cloud.transfers.gcs_to_bigquery import GCSToBigQueryOperator
from airflow.providers.google.cloud.operators.bigquery import BigQueryInsertJobOperator
from airflow.operators.python import PythonOperator
from datetime import datetime
GCS_BUCKET = 'your-data-bucket'
PROJECT_ID = 'your-project-id'
DATASET_ID = 'analytics'
def validate_data(**context):
"""Validate loaded data quality."""
from google.cloud import bigquery
client = bigquery.Client()
query = f"""
SELECT
COUNT(*) as total_rows,
COUNTIF(id IS NULL) as null_ids,
COUNTIF(value < 0) as negative_values
FROM `{PROJECT_ID}.{DATASET_ID}.staging_table`
"""
results = client.query(query).result()
for row in results:
if row.null_ids > 0 or row.negative_values > 0:
raise ValueError(f"Data quality check failed: {dict(row)}")
print(f"Validation passed: {row.total_rows} rows")
with DAG(
'bigquery_etl_pipeline',
start_date=datetime(2024, 1, 1),
schedule_interval='0 2 * * *', # 2 AM daily
catchup=False
) as dag:
wait_for_file = GCSObjectExistenceSensor(
task_id='wait_for_file',
bucket=GCS_BUCKET,
object='data/input_{{ ds_nodash }}.csv',
timeout=3600,
poke_interval=60
)
load_to_staging = GCSToBigQueryOperator(
task_id='load_to_staging',
bucket=GCS_BUCKET,
source_objects=['data/input_{{ ds_nodash }}.csv'],
destination_project_dataset_table=f'{PROJECT_ID}.{DATASET_ID}.staging_table',
source_format='CSV',
skip_leading_rows=1,
write_disposition='WRITE_TRUNCATE',
autodetect=True
)
transform_data = BigQueryInsertJobOperator(
task_id='transform_data',
configuration={
'query': {
'query': f"""
INSERT INTO `{PROJECT_ID}.{DATASET_ID}.final_table`
SELECT
id,
UPPER(name) as name,
value * 1.1 as adjusted_value,
CURRENT_TIMESTAMP() as processed_at
FROM `{PROJECT_ID}.{DATASET_ID}.staging_table`
WHERE value > 0
""",
'useLegacySql': False
}
}
)
validate = PythonOperator(
task_id='validate_data',
python_callable=validate_data,
provide_context=True
)
wait_for_file >> load_to_staging >> transform_data >> validate
Gemini AI Integration (11-13)
Text Generation (11-gemini-text-generation-basics)
import vertexai
from vertexai.generative_models import GenerativeModel, GenerationConfig
def generate_text(project_id: str, location: str, prompt: str):
"""Generate text using Gemini."""
vertexai.init(project=project_id, location=location)
model = GenerativeModel("gemini-1.5-pro")
generation_config = GenerationConfig(
temperature=0.7,
top_p=0.95,
top_k=40,
max_output_tokens=1024,
)
response = model.generate_content(
prompt,
generation_config=generation_config,
stream=False
)
return response.text
def stream_generation(project_id: str, location: str, prompt: str):
"""Stream text generation for real-time output."""
vertexai.init(project=project_id, location=location)
model = GenerativeModel("gemini-1.5-pro")
responses = model.generate_content(prompt, stream=True)
for response in responses:
print(response.text, end='')
Multimodal Analysis (12-gemini-multimodal-analysis)
import vertexai
from vertexai.generative_models import GenerativeModel, Part
from google.cloud import storage
def analyze_image(project_id: str, location: str,
gcs_uri: str, prompt: str):
"""Analyze an image using Gemini."""
vertexai.init(project=project_id, location=location)
model = GenerativeModel("gemini-1.5-pro")
image_part = Part.from_uri(gcs_uri, mime_type="image/jpeg")
response = model.generate_content([prompt, image_part])
return response.text
def analyze_pdf_document(project_id: str, location: str, pdf_gcs_uri: str):
"""Extract and analyze content from PDF."""
vertexai.init(project=project_id, location=location)
model = GenerativeModel("gemini-1.5-pro")
pdf_part = Part.from_uri(pdf_gcs_uri, mime_type="application/pdf")
prompt = """
Analyze this document and provide:
1. Main topics covered
2. Key data points or statistics
3. Summary of conclusions
"""
response = model.generate_content([prompt, pdf_part])
return response.text
Function Calling (13-gemini-function-calling-tools)
import vertexai
from vertexai.generative_models import (
GenerativeModel,
FunctionDeclaration,
Tool
)
def get_weather(location: str):
"""Simulated weather API."""
return {
"location": location,
"temperature": 72,
"conditions": "sunny"
}
def setup_function_calling(project_id: str, location: str):
"""Set up Gemini with function calling."""
vertexai.init(project=project_id, location=location)
# Define function schema
get_weather_func = FunctionDeclaration(
name="get_weather",
description="Get current weather for a location",
parameters={
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name"
}
},
"required": ["location"]
}
)
weather_tool = Tool(function_declarations=[get_weather_func])
model = GenerativeModel(
"gemini-1.5-pro",
tools=[weather_tool]
)
# User asks about weather
chat = model.start_chat()
response = chat.send_message("What's the weather in San Francisco?")
# Check if function call is requested
function_call = response.candidates[0].content.parts[0].function_call
if function_call.name == "get_weather":
# Execute function
weather_data = get_weather(
location=function_call.args["location"]
)
# Send result back to model
response = chat.send_message(
Part.from_function_response(
name="get_weather",
response={"content": weather_data}
)
)
return response.text
Common Deployment Patterns
Project Deployment Script
Each project includes a deploy.sh script:
#!/bin/bash
set -e
PROJECT_ID=${GOOGLE_CLOUD_PROJECT}
LOCATION=${GOOGLE_CLOUD_LOCATION:-us-central1}
# Enable required APIs
gcloud services enable bigquery.googleapis.com \
storage.googleapis.com \
dataflow.googleapis.com \
--project=${PROJECT_ID}
# Create resources
bq mk --dataset ${PROJECT_ID}:analytics
gsutil mb -l ${LOCATION} gs://${PROJECT_ID}-data
echo "✓ Deployment complete"
Running a Project
cd <project-directory>
# Review and run deployment
chmod +x deploy.sh
./deploy.sh
# Run main pipeline
python main.py
# Or with arguments
python main.py --project-id=$GOOGLE_CLOUD_PROJECT \
--location=us-central1 \
--input-file=data/sample.csv
Configuration Patterns
Environment Variables
# Required for all projects
export GOOGLE_CLOUD_PROJECT=your-project-id
export GOOGLE_CLOUD_LOCATION=us-central1
# Optional performance tuning
export BEAM_MAX_NUM_WORKERS=10
export BQ_BATCH_SIZE=1000
# Credentials (use Application Default Credentials)
gcloud auth application-default login
Config Files (config.yaml)
project_id: ${GOOGLE_CLOUD_PROJECT}
location: us-central1
bigquery:
dataset: analytics
staging_dataset: staging
storage:
bucket: ${GOOGLE_CLOUD_PROJECT}-data
temp_location: gs://${GOOGLE_CLOUD_PROJECT}-data/temp
dataflow:
runner: DataflowRunner
num_workers: 2
max_num_workers: 10
machine_type: n1-standard-2
composer:
environment: production-composer
dag_folder: dags/
Loading Configuration
import os
import yaml
from string import Template
def load_config(config_path: str = 'config.yaml') -> dict:
"""Load configuration with environment variable substitution."""
with open(config_path, 'r') as f:
config_template = f.read()
FAQ
What does the google-cloud-data-engineering-hub skill do?
Production-grade GCP data engineering projects using BigQuery, Dataflow, Beam, Composer, Pub/Sub, Dataproc, and Vertex AI
How do I install google-cloud-data-engineering-hub?
Run npx skills add https://github.com/reason-machines/data-skills --skill google-cloud-data-engineering-hub in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/google-cloud-data-engineering-hub/ (personal) or .claude/skills/google-cloud-data-engineering-hub/ (project).
Which AI agents can use google-cloud-data-engineering-hub?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is google-cloud-data-engineering-hub safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains google-cloud-data-engineering-hub?
It is published by reason-machines in reason-machines/data-skills. It has 1,085 recorded installs.
More from reason-machines/data-skills
apache-airflow-orchestration
reason-machines/data-skills
Expert knowledge of Apache Airflow for building, scheduling, and monitoring data pipelines and workflows
datatalks-data-engineering-zoomcamp
reason-machines/data-skills
Free 9-week data engineering course covering Docker, Terraform, Kestra, BigQuery, dbt, Spark, and Kafka with hands-on projects
llm-public-opinion-analytics-assistant
reason-machines/data-skills
Multi-platform hot search crawler and LLM-powered public opinion analysis system with clustering, sentiment analysis, and multi-channel push notifications
roblox-mm2-analytics-toolkit
reason-machines/data-skills
Analytics and inventory management toolkit for Roblox Murder Mystery 2 gameplay optimization
mm2-analytics-roblox-tracker
reason-machines/data-skills
Analyze Murder Mystery 2 gameplay data, track inventory, and optimize strategy using this Roblox analytics toolkit
mm2-roblox-analytics-toolkit
reason-machines/data-skills
Murder Mystery 2 gameplay analytics, inventory tracking, and strategy optimization toolkit for Roblox
Popular devops & cloud skills
microsoft-foundry
microsoft/azure-skills
Build, deploy, evaluate, optimize, fine-tune, and manage Microsoft Foundry agents, models, and resources end to end. USE FOR: foundry, azd ai agent, azd provision/deploy, hosted agent scaffold/develop/run/deploy/troubleshoot, prompt agent create, managed harness agent create, GitHub Copilot harness agent, create agent, update agent, add tool to agent, invoke agent, agent insights, evaluate agent, batch eval, continuous eval, continuous monitoring, agent CI/CD, optimize prompt, improve prompt, optimize agent instructions, Agent Optimizer scaffold, dataset curation from traces, deploy model, model fine-tuning (SFT/DPO/RFT), Foundry project, RBAC, role assignment, permissions, quota, capacity, region, deployment failure, AI Services, create Foundry resource, knowledge index, customize deployment, onboard, availability, training-data, grader, distillation, large file upload. DO NOT USE FOR: Azure Functions, App Service, general Azure deploy (use azure-deploy), general Azure prep (use azure
azure-diagnostics
microsoft/azure-skills
Debug Azure production issues on Azure using AppLens, Azure Monitor, resource health, and safe triage. WHEN: debug production issues, troubleshoot app service, app service high CPU, app service deployment failure, troubleshoot container apps, container app 503 or target port mismatch, troubleshoot functions, function telemetry missing or stopped after a config/connection-string change, troubleshoot AKS, VM RDP, Linux SSH, VM black screen, can't connect to VM, reset VM password, NSG or firewall blocking, kubectl cannot connect, kube-system/CoreDNS failures, pod pending, crashloop, node not ready, upgrade failures, analyze logs, KQL, insights, image pull failures, cold start issues, health probe failures, resource health, root cause of errors, troubleshoot event hubs, troubleshoot service bus, messaging SDK error, AMQP connection failure, message lock lost, lock renewal during long-running processing, service bus dead letter.
azure-prepare
microsoft/azure-skills
Prepare azd-based Azure projects for deployment: generates azure.yaml, infrastructure (Bicep/Terraform), and Dockerfiles for the Azure Developer CLI (azd) workflow. USE ONLY when the user explicitly wants to use azd as the deployment tool, or the project already has an azure.yaml file. DO NOT USE FOR: non-azd deployments, Python App Service code-only deploys (use python-appservice-deploy), or cross-cloud migration (use azure-cloud-migrate). WHEN: prepare app for azd, create azure.yaml, set up azd infrastructure, modernize app for Azure with azd, deploy with azd, function app, timer trigger, service bus trigger, event-driven function, managed identity, generate Bicep, generate Terraform, create and deploy to Azure.
azure-ai
microsoft/azure-skills
Use for Azure AI: Search, Speech, OpenAI, Document Intelligence. Helps with search, vector/hybrid search, speech-to-text, text-to-speech, transcription, OCR. WHEN: AI Search, query search, vector search, hybrid search, semantic search, speech-to-text, text-to-speech, transcribe, OCR, convert text to speech.
azure-deploy
microsoft/azure-skills
Execute Azure deployments for ALREADY-PREPARED applications that have existing .azure/deployment-plan.md and infrastructure files. DO NOT use this skill when the user asks to CREATE a new application — use azure-prepare instead. This skill runs azd up, azd deploy, terraform apply, and az deployment commands with built-in error recovery. Requires .azure/deployment-plan.md from azure-prepare and validated status from azure-validate. WHEN: "run azd up", "run azd deploy", "execute deployment", "push to production", "push to cloud", "go live", "ship it", "bicep deploy", "terraform apply", "publish to Azure", "launch on Azure". DO NOT USE WHEN: "create and deploy", "build and deploy", "create a new app", "set up infrastructure", "create and deploy to Azure using Terraform" — use azure-prepare for these.
azure-validate
microsoft/azure-skills
Pre-deployment validation for Azure readiness. Run deep checks on configuration, infrastructure (Bicep or Terraform), RBAC role assignments, managed identity permissions, and prerequisites before deploying. WHEN: validate my app, check deployment readiness, run preflight checks, verify configuration, check if ready to deploy, validate azure.yaml, validate Bicep, test before deploying, troubleshoot deployment errors, validate Azure Functions, validate function app, validate serverless deployment, verify RBAC roles, check role assignments, review managed identity permissions, what-if analysis, validate Container Apps deployment.