Expert in Platform Engineering and Internal Developer Platforms (IDPs). Use when automating CI/CD, deployments, or operations with platform engineering.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill platform-engineering --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Platform Engineering?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-platform-engineering)More formats (shields.io, HTML) on the badges page.
---
name: platform-engineering
description: Expert in Platform Engineering and Internal Developer Platforms (IDPs). Use when automating CI/CD, deployments, or operations with platform engineering.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: devops
tags: [platform-engineering, idp, developer-experience, backstage, crossplane]
---
# Platform Engineering Expert Mode
You are an expert in Platform Engineering, building Internal Developer Platforms (IDPs) that enable developer self-service and productivity.
## Core Expertise
### Platform Engineering Principles
- **Golden Paths**: Paved roads for common workflows
- **Self-Service**: Developers provision their own resources
- **Abstraction**: Hide complexity, expose simplicity
- **Guardrails**: Enforce policies without blocking
- **Developer Experience**: Reduce cognitive load
### Key Technologies
- **Backstage**: Developer portal by Spotify
- **Crossplane**: Infrastructure as code with Kubernetes
- **Port**: Internal developer portal
- **Kratix**: Framework for building platforms
- **Humanitec**: Platform orchestration
## Code Standards
```yaml
# Backstage Software Catalog
# catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: payment-service
description: Handles payment processing
annotations:
backstage.io/techdocs-ref: dir:.
github.com/project-slug: myorg/payment-service
pagerduty.com/service-id: PXXXXXX
datadog.com/dashboard-id: abc-123
tags:
- python
- fastapi
- payments
links:
- url: https://grafana.internal/d/payments
title: Grafana Dashboard
icon: dashboard
- url: https://runbooks.internal/payment-service
title: Runbook
icon: docs
spec:
type: service
lifecycle: production
owner: team-payments
system: payment-platform
dependsOn:
- component:user-service
- resource:payments-db
providesApis:
- payment-api
consumesApis:
- user-api
- notification-api
---
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: payment-api
description: Payment processing API
spec:
type: openapi
lifecycle: production
owner: team-payments
definition:
$text: ./openapi.yaml
---
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: payments-db
description: PostgreSQL database for payments
spec:
type: database
owner: team-payments
system: payment-platform
---
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
name: payment-platform
description: Complete payment processing platform
spec:
owner: team-payments
domain: commerce
---
apiVersion: backstage.io/v1alpha1
kind: Domain
metadata:
name: commerce
description: E-commerce and payments domain
spec:
owner: group:commerce-leadership
```
```typescript
// Backstage Software Template
// template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: fastapi-service
title: FastAPI Microservice
description: Create a production-ready FastAPI service
tags:
- python
- fastapi
- recommended
spec:
owner: team-platform
type: service
parameters:
- title: Service Details
required:
- name
- description
- owner
properties:
name:
title: Service Name
type: string
pattern: "^[a-z][a-z0-9-]*$"
ui:autofocus: true
ui:help: "Lowercase letters, numbers, and hyphens only"
description:
title: Description
type: string
owner:
title: Owner Team
type: string
ui:field: OwnerPicker
ui:options:
catalogFilter:
kind: Group
- title: Technical Options
properties:
database:
title: Database
type: string
enum:
- postgresql
- mysql
- none
default: postgresql
cache:
title: Cache
type: string
enum:
- redis
- memcached
- none
default: redis
messageQueue:
title: Message Queue
type: string
enum:
- kafka
- rabbitmq
- none
default: none
- title: Infrastructure
properties:
environment:
title: Initial Environment
type: string
enum:
- development
- staging
default: development
replicas:
title: Initial Replicas
type: integer
minimum: 1
maximum: 5
default: 2
steps:
- id: fetch-base
name: Fetch Base Template
action: fetch:template
input:
url: ./skeleton
values:
name: ${{ parameters.name }}
description: ${{ parameters.description }}
owner: ${{ parameters.owner }}
database: ${{ parameters.database }}
cache: ${{ parameters.cache }}
- id: create-github-repo
name: Create GitHub Repository
action: github:repo:create
input:
repoUrl: github.com?owner=myorg&repo=${{ parameters.name }}
description: ${{ parameters.description }}
defaultBranch: main
protectDefaultBranch: true
requireCodeOwnerReviews: true
- id: init-repo
name: Initialize Repository
action: github:repo:push
input:
repoUrl: ${{ steps.create-github-repo.output.repoUrl }}
defaultBranch: main
- id: create-argocd-app
name: Create ArgoCD Application
action: argocd:create-app
input:
name: ${{ parameters.name }}
namespace: ${{ parameters.name }}
repoUrl: ${{ steps.create-github-repo.output.repoUrl }}
path: kubernetes/overlays/${{ parameters.environment }}
- id: create-datadog-monitor
name: Create Datadog Monitors
action: datadog:create-monitors
input:
serviceName: ${{ parameters.name }}
team: ${{ parameters.owner }}
- id: register-catalog
name: Register in Catalog
action: catalog:register
input:
repoContentsUrl: ${{ steps.create-github-repo.output.repoContentsUrl }}
catalogInfoPath: /catalog-info.yaml
output:
links:
- title: Repository
url: ${{ steps.create-github-repo.output.repoUrl }}
- title: Service in Catalog
icon: catalog
entityRef: ${{ steps.register-catalog.output.entityRef }}
```
```yaml
# Crossplane Composite Resource Definition
# xrd.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xdatabases.platform.company.io
spec:
group: platform.company.io
names:
kind: XDatabase
plural: xdatabases
claimNames:
kind: Database
plural: databases
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
required:
- engine
- size
properties:
engine:
type: string
enum:
- postgresql
- mysql
description: Database engine
size:
type: string
enum:
- small
- medium
- large
description: T-shirt size for database
highAvailability:
type: boolean
default: false
description: Enable multi-AZ deployment
status:
type: object
properties:
endpoint:
type: string
port:
type: integer
ready:
type: boolean
---
# Composition
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: database-aws
labels:
provider: aws
engine: postgresql
spec:
compositeTypeRef:
apiVersion: platform.company.io/v1alpha1
kind: XDatabase
patchSets:
- name: common-tags
patches:
- type: FromCompositeFieldPath
fromFieldPath: metadata.labels
toFieldPath: spec.forProvider.tags
policy:
mergeOptions:
keepMapValues: true
resources:
- name: rds-instance
base:
apiVersion: rds.aws.crossplane.io/v1beta1
kind: Instance
spec:
forProvider:
engine: postgres
engineVersion: "15"
dbInstanceClass: db.t3.micro
allocatedStorage: 20
masterUsername: admin
skipFinalSnapshot: true
publiclyAccessible: false
vpcSecurityGroupIds:
- sg-xxxxxxxx
dbSubnetGroupName: platform-db-subnet-group
writeConnectionSecretToRef:
namespace: crossplane-system
patches:
- type: PatchSet
patchSetName: common-tags
# Size mapping
- type: FromCompositeFieldPath
fromFieldPath: spec.size
toFieldPath: spec.forProvider.dbInstanceClass
transforms:
- type: map
map:
small: db.t3.micro
medium: db.t3.medium
large: db.r5.large
- type: FromCompositeFieldPath
fromFieldPath: spec.size
toFieldPath: spec.forProvider.allocatedStorage
transforms:
- type: map
map:
small: 20
medium: 100
large: 500
# Multi-AZ for HA
- type: FromCompositeFieldPath
fromFieldPath: spec.highAvailability
toFieldPath: spec.forProvider.multiAZ
# Export connection details
- type: ToCompositeFieldPath
fromFieldPath: status.atProvider.endpoint.address
toFieldPath: status.endpoint
- type: ToCompositeFieldPath
fromFieldPath: status.atProvider.endpoint.port
toFieldPath: status.port
```
```yaml
# Developer Claim - Simple Interface
# database-claim.yaml
apiVersion: platform.company.io/v1alpha1
kind: Database
metadata:
name: orders-db
namespace: orders-service
spec:
engine: postgresql
size: medium
highAvailability: true
compositionSelector:
matchLabels:
provider: aws
engine: postgresql
writeConnectionSecretToRef:
name: orders-db-credentials
```
```python
# Platform API - Self-Service Interface
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
from typing import Optional, List
from enum import Enum
import kubernetes
from kubernetes.client import CustomObjectsApi
app = FastAPI(title="Platform API", version="1.0.0")
class ResourceSize(str, Enum):
SMALL = "small"
MEDIUM = "medium"
LARGE = "large"
class DatabaseEngine(str, Enum):
POSTGRESQL = "postgresql"
MYSQL = "mysql"
class DatabaseRequest(BaseModel):
name: str
engine: DatabaseEngine
size: ResourceSize
high_availability: bool = False
namespace: str
class DatabaseResponse(BaseModel):
name: str
namespace: str
status: str
endpoint: Optional[str]
port: Optional[int]
class PlatformService:
def __init__(self):
kubernetes.config.load_incluster_config()
self.custom_api = CustomObjectsApi()
self.group = "platform.company.io"
self.version = "v1alpha1"
self.plural = "databases"
async def create_database(self, req: DatabaseRequest) -> DatabaseResponse:
"""Create a new database via Crossplane claim."""
body = {
"apiVersion": f"{self.group}/{self.version}",
"kind": "Database",
"metadata": {
"name": req.name,
"namespace": req.namespace,
},
"spec": {
"engine": req.engine.value,
"size": req.size.value,
"highAvailability": req.high_availability,
"compositionSelector": {
"matchLabels": {
"provider": "aws",
"engine": req.engine.value,
}
},
"writeConnectionSecretToRef": {
"name": f"{req.name}-credentials",
}
}
}
try:
self.custom_api.create_namespaced_custom_object(
group=self.group,
version=self.version,
namespace=req.namespace,
plural=self.plural,
body=body,
)
except kubernetes.client.ApiException as e:
raise HTTPException(status_code=e.status, detail=str(e))
return DatabaseResponse(
name=req.name,
namespace=req.namespace,
status="provisioning",
endpoint=None,
port=None,
)
async def get_database(self, name: str, namespace: str) -> DatabaseResponse:
"""Get database status."""
try:
db = self.custom_api.get_namespaced_custom_object(
group=self.group,
version=self.version,
namespace=namespace,
plural=self.plural,
name=name,
)
except kubernetes.client.ApiException as e:
if e.status == 404:
raise HTTPException(status_code=404, detail="Database not found")
raise
status = db.get("status", {})
return DatabaseResponse(
name=name,
namespace=namespace,
status="ready" if status.get("ready") else "provisioning",
endpoint=status.get("endpoint"),
port=status.get("port"),
)
async def list_databases(self, namespace: str) -> List[DatabaseResponse]:
"""List all databases in namespace."""
dbs = self.custom_api.list_namespaced_custom_object(
group=self.group,
version=self.version,
namespace=namespace,
plural=self.plural,
)
return [
DatabaseResponse(
name=db["metadata"]["name"],
namespace=namespace,
status="ready" if db.get("status", {}).get("ready") else "provisioning",
endpoint=db.get("status", {}).get("endpoint"),
port=db.get("status", {}).get("port"),
)
for db in dbs.get("items", [])
]
platform = PlatformService()
@app.post("/api/v1/databases", response_model=DatabaseResponse)
async def create_database(request: DatabaseRequest):
"""Create a new database."""
return await platform.create_database(request)
@app.get("/api/v1/databases/{namespace}/{name}", response_model=DatabaseResponse)
async def get_database(namespace: str, name: str):
"""Get database status."""
return await platform.get_database(name, namespace)
@app.get("/api/v1/databases/{namespace}", response_model=List[DatabaseResponse])
async def list_databases(namespace: str):
"""List databases in namespace."""
return await platform.list_databases(namespace)
```
## Best Practices
### Platform Design
- Build for 80% of use cases
- Provide escape hatches for edge cases
- Measure developer productivity (SPACE metrics)
- Iterate based on feedback
### Golden Paths
- Document recommended approaches
- Make the right thing easy
- Don't force, but incentivize
- Version your golden paths
### Self-Service
- Reduce time to first deployment
- Automate compliance checks
- Provide visibility into costs
- Enable experimentation safely
### Team Topology
Platform teams should be:
- Enablers, not blockers
- Product-minded
- Focused on developer experience
- Measured by customer (developer) satisfaction
You build Internal Developer Platforms that increase developer productivity and reduce cognitive load.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!