本文へ移動
cccskills
無料GitHub で公開

platform-engineering-internal-developer-platform

Internal Developer Platform (IDP) for data engineering — Backstage Software Catalog (catalog-info.yaml for pipelines/datasets/services), Software Templates (scaffold new DAG/dbt project/Kafka topic), TechDocs integration, golden path enforcement, Port.io alternative, self-service data pipeline provisioning, platform scorecard (production readiness checks), team ownership model, API gateway for platform services, paved road vs escape hatch pattern

日本語の概要は準備中です。原文の説明を表示しています。

ivanshamaev/de-agent-skillsスター 22(GitHub 22 + cccskills 0)

実行スコア 未検証

インストール方法を見る

含まれるファイル(1)

  • SKILL.md12.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Internal Developer Platform (IDP) for Data Engineering

When to Use

  • Standardizing how data teams create new pipelines, datasets, and services
  • Building a self-service portal where engineers provision Kafka topics, Airflow DAGs, and dbt models without tickets
  • Enforcing production readiness standards through platform scorecards
  • Creating a searchable catalog of all data assets with ownership and lineage
  • Reducing onboarding time with golden-path templates

Backstage Software Catalog

catalog-info.yaml for Data Pipeline

# dag-etl-orders/catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: etl-orders
  title: Orders ETL Pipeline
  description: "Daily ingestion of orders from Kafka → Silver → Gold"
  annotations:
    backstage.io/techdocs-ref: dir:.
    airflow.apache.org/dag-id: etl_orders
    grafana.com/dashboard-url: https://grafana.internal/d/etl-orders
    runbook-url: https://wiki.internal/runbooks/etl-orders
  tags:
    - airflow
    - kafka
    - orders
    - gold-layer
  links:
    - url: https://airflow.internal/dags/etl_orders
      title: Airflow DAG
      icon: airflow
spec:
  type: pipeline
  lifecycle: production
  owner: group:data-engineering
  system: data-platform
  dependsOn:
    - resource:kafka-topic-orders-raw
    - component:kafka-platform
  providesApis:
    - gold-orders-api

---
# Dataset entity
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
  name: gold-fact-orders
  description: "Gold layer orders fact table — daily partitioned"
  annotations:
    datahub.io/urn: "urn:li:dataset:(urn:li:dataPlatform:trino,gold.fact_orders,PROD)"
  tags:
    - gold-layer
    - iceberg
    - pii-free
spec:
  type: dataset
  owner: group:data-engineering
  system: data-platform
  dependsOn:
    - component:etl-orders

Kafka Topic Entity

apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
  name: kafka-topic-orders-raw
  description: "Raw orders events from order service — Avro schema"
  annotations:
    schema-registry-url: https://schema-registry.internal/subjects/orders-raw-value
spec:
  type: kafka-topic
  owner: group:platform-engineering
  system: kafka-platform

Software Templates (Golden Path)

New Airflow DAG Template

# backstage/templates/airflow-dag/template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: airflow-dag
  title: New Airflow DAG
  description: Scaffold a production-ready Airflow DAG with DQ checks, SLA callback, and idempotent tasks
  tags:
    - airflow
    - data-engineering
spec:
  owner: group:platform-engineering
  type: pipeline
  parameters:
    - title: DAG Configuration
      required:
        - dag_id
        - schedule
        - owner_team
        - slack_channel
      properties:
        dag_id:
          title: DAG ID
          type: string
          pattern: '^[a-z][a-z0-9_]*$'
          description: "Snake_case DAG identifier (e.g., etl_orders)"
        schedule:
          title: Schedule
          type: string
          description: "Cron expression (e.g., 0 2 * * *)"
        owner_team:
          title: Owner Team
          type: string
          enum: [data-engineering, analytics, platform-engineering]
        slack_channel:
          title: Failure Alert Channel
          type: string
          description: "#channel-name for failure alerts"
        source_kafka_topic:
          title: Source Kafka Topic (optional)
          type: string
        target_trino_table:
          title: Target Trino Table
          type: string
          description: "schema.table_name in Gold layer"

  steps:
    - id: fetch-template
      name: Fetch Template
      action: fetch:template
      input:
        url: ./skeleton
        values:
          dag_id: ${{ parameters.dag_id }}
          schedule: ${{ parameters.schedule }}
          owner_team: ${{ parameters.owner_team }}
          slack_channel: ${{ parameters.slack_channel }}
          source_topic: ${{ parameters.source_kafka_topic }}
          target_table: ${{ parameters.target_trino_table }}

    - id: create-pr
      name: Open Pull Request
      action: publish:github:pull-request
      input:
        repoUrl: github.com?repo=data-platform-dags&owner=myorg
        title: "feat: new DAG ${{ parameters.dag_id }}"
        branchName: "feat/dag-${{ parameters.dag_id }}"
        description: |
          Auto-generated by Internal Developer Platform
          Owner: ${{ parameters.owner_team }}
        sourcePath: ./
        targetPath: dags/${{ parameters.dag_id }}

    - id: register-catalog
      name: Register in Catalog
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps['create-pr'].output.repoContentsUrl }}
        catalogInfoPath: /dags/${{ parameters.dag_id }}/catalog-info.yaml

DAG Skeleton Template

# backstage/templates/airflow-dag/skeleton/dags/${{values.dag_id}}/dag.py
from airflow import DAG
from airflow.operators.python import PythonOperator
from airflow.utils.dates import days_ago
import pendulum

with DAG(
    dag_id="${{values.dag_id}}",
    schedule="${{values.schedule}}",
    start_date=pendulum.datetime(2024, 1, 1),
    catchup=False,
    default_args={
        "owner": "${{values.owner_team}}",
        "retries": 3,
        "retry_delay": pendulum.duration(minutes=5),
        "on_failure_callback": lambda ctx: send_slack_failure(
            ctx, channel="${{values.slack_channel}}"
        ),
    },
    tags=["${{values.owner_team}}", "generated"],
    sla_miss_callback=lambda dag, task_list, blocking_task_list, slas, blocking_tis:
        notify_sla_breach(dag, "${{values.slack_channel}}"),
) as dag:

    def extract(**kwargs):
        # TODO: implement extraction from ${{values.source_topic}}
        pass

    def transform(**kwargs):
        # TODO: implement transformation
        pass

    def load(**kwargs):
        # INSERT OVERWRITE for idempotency
        # TODO: implement load to ${{values.target_table}}
        pass

    t_extract = PythonOperator(task_id="extract", python_callable=extract)
    t_transform = PythonOperator(task_id="transform", python_callable=transform)
    t_load = PythonOperator(task_id="load", python_callable=load)

    t_extract >> t_transform >> t_load

Platform Scorecard (Production Readiness)

# platform_scorecard.py — evaluate production readiness of a data pipeline
from dataclasses import dataclass

@dataclass
class ScorecardCheck:
    name: str
    description: str
    weight: int   # 1-3 (3 = critical)
    fn: callable   # returns (passed: bool, details: str)

PIPELINE_SCORECARD = [
    ScorecardCheck("catalog_entry", "Component has catalog-info.yaml", 3,
        lambda dag_id: (check_catalog_entity_exists(dag_id), "")),
    ScorecardCheck("sla_defined", "SLA callback configured", 3,
        lambda dag_id: (check_sla_callback(dag_id), "")),
    ScorecardCheck("idempotent_loads", "Uses INSERT OVERWRITE or upsert", 3,
        lambda dag_id: (check_idempotent_pattern(dag_id), "")),
    ScorecardCheck("retries_configured", "Retries >= 2 with backoff", 2,
        lambda dag_id: (check_retry_config(dag_id), "")),
    ScorecardCheck("dq_gate", "Has data quality check task", 2,
        lambda dag_id: (check_has_dq_task(dag_id), "")),
    ScorecardCheck("on_failure_callback", "Has Slack/PagerDuty failure notification", 2,
        lambda dag_id: (check_failure_callback(dag_id), "")),
    ScorecardCheck("no_top_level_code", "No database calls at DAG parse time", 3,
        lambda dag_id: (check_no_top_level_calls(dag_id), "")),
    ScorecardCheck("runbook_linked", "Runbook URL in catalog-info.yaml annotations", 1,
        lambda dag_id: (check_runbook_annotation(dag_id), "")),
    ScorecardCheck("owner_group", "Owner is a team group, not an individual", 2,
        lambda dag_id: (check_group_owner(dag_id), "")),
    ScorecardCheck("documentation", "TechDocs or README present", 1,
        lambda dag_id: (check_docs_present(dag_id), "")),
]

def run_scorecard(dag_id: str) -> dict:
    total_weight = sum(c.weight for c in PIPELINE_SCORECARD)
    passed_weight = 0
    results = []

    for check in PIPELINE_SCORECARD:
        passed, details = check.fn(dag_id)
        if passed:
            passed_weight += check.weight
        results.append({
            "check": check.name,
            "description": check.description,
            "weight": check.weight,
            "passed": passed,
            "details": details,
        })

    score = round(passed_weight / total_weight * 100)
    return {
        "dag_id": dag_id,
        "score": score,
        "level": "gold" if score >= 90 else "silver" if score >= 70 else "bronze",
        "results": results,
        "failed_critical": [r for r in results if not r["passed"] and r["weight"] == 3],
    }

Self-Service Kafka Topic Provisioning

# FastAPI endpoint for self-service topic creation
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, validator
import subprocess, json

app = FastAPI(title="Platform Self-Service API")

class KafkaTopicRequest(BaseModel):
    name: str                    # prod.{domain}.{entity}.v{N}
    partitions: int
    retention_hours: int = 168
    owner_team: str
    purpose: str

    @validator("name")
    def validate_naming(cls, v):
        import re
        if not re.match(r'^(prod|staging|dev)\.[a-z]+\.[a-z_]+\.v\d+$', v):
            raise ValueError("Topic name must match: {env}.{domain}.{entity}.v{N}")
        return v

    @validator("partitions")
    def validate_partitions(cls, v):
        if v < 1 or v > 100:
            raise ValueError("Partitions must be between 1 and 100")
        return v

@app.post("/api/v1/kafka/topics")
async def create_topic(req: KafkaTopicRequest):
    # Check if topic already exists
    existing = subprocess.run(
        ["kafka-topics.sh", "--bootstrap-server", KAFKA_BOOTSTRAP,
         "--describe", "--topic", req.name],
        capture_output=True
    )
    if existing.returncode == 0:
        raise HTTPException(status_code=409, detail=f"Topic {req.name} already exists")

    # Create topic
    result = subprocess.run([
        "kafka-topics.sh", "--bootstrap-server", KAFKA_BOOTSTRAP,
        "--create", "--topic", req.name,
        "--partitions", str(req.partitions),
        "--replication-factor", "3",
        "--config", f"min.insync.replicas=2",
        "--config", f"retention.ms={req.retention_hours * 3600000}",
    ], capture_output=True, text=True)

    if result.returncode != 0:
        raise HTTPException(status_code=500, detail=result.stderr)

    # Register in Backstage catalog
    _register_topic_entity(req)

    return {"topic": req.name, "partitions": req.partitions, "status": "created"}

Anti-Patterns

  1. IDP as a ticket system — if the IDP generates a Jira ticket instead of actually provisioning the resource, engineers will go around it; automate the action, not the request.
  2. Golden path without an escape hatch — teams with unusual requirements get blocked if there's no way to deviate from the template; document the escape hatch process.
  3. Scorecard without consequences — a scorecard that doesn't block promotion to production is decorative; gate production promotion on "silver" level minimum.
  4. Templates that go stale — template code that doesn't get security/dependency updates becomes a liability; treat templates as first-class code with CI/CD and automated dependency updates.
  5. Catalog without ownership enforcement — stale catalog entries with departed engineers as owners create confusion; auto-flag components with no active owner for 30 days.

References

  • Backstage: backstage.io/docs/overview/what-is-backstage
  • Backstage Software Templates: backstage.io/docs/features/software-templates/
  • Port.io alternative: docs.getport.io/
  • Related skills: [[platform-engineering-data-platform-api]], [[dataops-airflow-production-readiness]], [[github-actions-dataops]]

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

AIOps autonomous incident response agent — LLM-driven diagnosis loop (Claude tool-use agent with kubectl/SQL/Prometheus tools), alert-to-action pipeline (PagerDuty webhook → agent trigger), automated RCA generation (failure taxonomy + log correlation), self-healing action executor with approval gate, incident severity classification, runbook automation (structured YAML runbooks executed by agent), escalation logic, incident timeline auto-generation, Slack integration for human-in-the-loop approvals

日本語の概要は準備中です。原文の説明を表示しています。

ivanshamaev/de-agent-skills222026年5月20日 更新

AIOps capacity planning agent — predictive resource forecasting (Prophet/linear regression on Prometheus metrics), Kubernetes HPA/VPA right-sizing recommendations, node capacity headroom calculator, Kafka partition and broker capacity model, Spark executor sizing from job history, data lake storage growth forecast (S3/GCS), cluster autoscaler simulation, automatic HPA threshold tuning, cost-per-job attribution, capacity planning report generator

日本語の概要は準備中です。原文の説明を表示しています。

ivanshamaev/de-agent-skills222026年5月20日 更新

AIOps infrastructure anomaly detection — statistical baseline (z-score/IQR/seasonal decomposition), Prometheus anomaly rules (predict_linear/stddev_over_time/MAD), ML-based detection (Isolation Forest/Prophet/LSTM autoencoder on metrics), metric correlation clustering, automated alert threshold tuning from historical data, Kubernetes resource anomaly detection, data pipeline anomaly signals (row count z-score/freshness drift/throughput drop), Python sklearn/Prophet integration, Grafana anomaly panel

日本語の概要は準備中です。原文の説明を表示しています。

ivanshamaev/de-agent-skills222026年5月20日 更新

AIOps observability copilot — natural language to PromQL/LogQL translation, alert explanation in plain English (what fired/why/impact), Grafana dashboard auto-generation from service topology, anomaly narrative generation from metric patterns, on-call context enrichment (related alerts/recent deploys/runbook links), log pattern clustering for noise reduction, SLO status explanation, automated weekly observability health digest

日本語の概要は準備中です。原文の説明を表示しています。

ivanshamaev/de-agent-skills222026年5月20日 更新

AIOps continuous platform optimization agent — autonomous optimization loop (observe→analyze→recommend→apply), Kubernetes resource rightsizing (VPA recommendation reader + apply), Kafka consumer lag auto-scale, Spark job configuration tuning from history, idle resource detection (unused deployments/PVCs/topics), compaction and VACUUM scheduling, auto-ANALYZE stale statistics, cost savings attribution, optimization audit trail, human approval gate for high-risk changes

日本語の概要は準備中です。原文の説明を表示しています。

ivanshamaev/de-agent-skills222026年5月20日 更新

AIOps autonomous query cost analyzer — Trino system.runtime.query_history cost SQL (CPU time/peak memory/bytes scanned), ClickHouse system.query_log top expensive queries, Spark UI cost attribution by user/job/DAG, BigQuery INFORMATION_SCHEMA.JOBS cost analysis, LLM-driven query rewrite recommendations (missing partition filters/broadcast hints/aggregation pushdown), cost anomaly detection (user over daily budget), automated query tagging, chargeback report by team/project

日本語の概要は準備中です。原文の説明を表示しています。

ivanshamaev/de-agent-skills222026年5月20日 更新

ivanshamaev のスキルをすべて見る

このスキルの問題を報告する