Platform Engineering Patterns
Duration: 110 min
Platform Engineering builds internal developer platforms that enable teams to self-serve infrastructure and deployment capabilities. This module covers service catalogs, golden paths, and developer experience patterns.
Internal Developer Platforms (IDP)
An IDP abstracts infrastructure complexity and provides self-service capabilities:
- Service Catalog: Discoverable, pre-configured services
- Golden Paths: Opinionated, pre-configured deployment patterns
- Developer Portal: Single interface for infrastructure needs
- Guardrails: Built-in compliance and security policies
- Observability: Integrated monitoring and logging
Service Catalog
A service catalog lists available infrastructure components:
{
"services": [
{
"id": "web-service",
"name": "Web Service",
"description": "Deploy a containerized web application",
"category": "compute",
"template": "web-service-template",
"parameters": [
{
"name": "service_name",
"type": "string",
"description": "Name of the service",
"required": true
},
{
"name": "replicas",
"type": "integer",
"description": "Number of replicas",
"default": 3,
"min": 1,
"max": 10
},
{
"name": "cpu",
"type": "string",
"description": "CPU allocation",
"enum": ["256", "512", "1024"],
"default": "512"
}
],
"outputs": [
{
"name": "service_url",
"description": "URL to access the service"
}
]
},
{
"id": "database",
"name": "PostgreSQL Database",
"description": "Deploy a managed PostgreSQL database",
"category": "data",
"template": "postgres-template",
"parameters": [
{
"name": "database_name",
"type": "string",
"required": true
},
{
"name": "instance_class",
"type": "string",
"enum": ["db.t3.micro", "db.t3.small", "db.t3.medium"],
"default": "db.t3.micro"
}
]
}
]
}Golden Paths
Golden paths are opinionated, pre-configured deployment patterns:
# Golden path for web service deployment
apiVersion: platform.example.com/v1
kind: GoldenPath
metadata:
name: web-service-path
spec:
description: "Deploy a web service with best practices"
components:
- name: container-image
type: docker
config:
registry: ecr
buildContext: .
dockerfile: Dockerfile
- name: kubernetes-deployment
type: kubernetes
config:
replicas: 3
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
- name: service-mesh
type: istio
config:
enabled: true
retries: 3
timeout: 30s
- name: monitoring
type: prometheus
config:
enabled: true
scrapeInterval: 30s
- name: logging
type: fluentd
config:
enabled: true
logLevel: info
- name: security
type: network-policy
config:
ingressAllowed:
- from: ingress-controller
egressAllowed:
- to: external-api
- to: databaseDeveloper Portal
A developer portal provides a unified interface:
# Example developer portal API
from fastapi import FastAPI, HTTPException
from typing import List
app = FastAPI()
class ServiceRequest:
def __init__(self, service_id: str, parameters: dict):
self.service_id = service_id
self.parameters = parameters
@app.get("/catalog")
async def get_catalog():
"""List available services"""
return {
"services": [
{
"id": "web-service",
"name": "Web Service",
"description": "Deploy a web application"
},
{
"id": "database",
"name": "PostgreSQL Database",
"description": "Deploy a database"
}
]
}
@app.post("/services/{service_id}/provision")
async def provision_service(service_id: str, request: ServiceRequest):
"""Provision a service from the catalog"""
# Validate parameters
# Generate infrastructure code
# Apply infrastructure
# Return service details
return {
"service_id": service_id,
"status": "provisioning",
"request_id": "req-12345"
}
@app.get("/services/{service_id}/status")
async def get_service_status(service_id: str):
"""Get status of provisioned service"""
return {
"service_id": service_id,
"status": "ready",
"url": "https://my-service.example.com"
}
@app.get("/templates")
async def get_templates():
"""List available deployment templates"""
return {
"templates": [
{
"id": "web-service-template",
"name": "Web Service",
"description": "Standard web service template"
}
]
}Scaffolding and Templates
# Create project from template
platform scaffold web-service my-app
# Generated project structure
my-app/
├── src/
│ ├── main.py
│ └── requirements.txt
├── Dockerfile
├── k8s/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── configmap.yaml
├── terraform/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── .github/
│ └── workflows/
│ ├── build.yml
│ └── deploy.yml
└── README.mdBackstage Integration
Backstage is an open-source developer portal:
# backstage.io/catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-web-service
description: My web service
links:
- url: https://github.com/myorg/my-web-service
title: Repository
spec:
type: service
owner: platform-team
lifecycle: production
providesApis:
- my-api
consumesApis:
- auth-api
- database-api
dependsOn:
- resource:postgres-db
---
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
type: openapi
owner: platform-team
lifecycle: production
definition:
$text: ./openapi.yaml
---
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
name: postgres-db
spec:
type: database
owner: platform-team
system: my-systemSelf-Service Workflows
# Workflow for self-service deployment
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: deploy-service-
spec:
entrypoint: deploy
arguments:
parameters:
- name: service-name
- name: image-tag
- name: replicas
templates:
- name: deploy
steps:
- - name: validate
template: validate-input
- - name: build
template: build-image
- - name: deploy
template: deploy-to-k8s
- - name: verify
template: verify-deployment
- name: validate-input
script:
image: python:3.9
command: [python]
source: |
import sys
service_name = "{{workflow.parameters.service-name}}"
if not service_name:
sys.exit(1)
print("Validation passed")
- name: build-image
script:
image: docker:latest
command: [sh]
source: |
docker build -t {{workflow.parameters.service-name}}:{{workflow.parameters.image-tag}} .
docker push {{workflow.parameters.service-name}}:{{workflow.parameters.image-tag}}
- name: deploy-to-k8s
script:
image: bitnami/kubectl:latest
command: [kubectl]
args:
- set
- image
- deployment/{{workflow.parameters.service-name}}
- "{{workflow.parameters.service-name}}={{workflow.parameters.service-name}}:{{workflow.parameters.image-tag}}"
- name: verify-deployment
script:
image: bitnami/kubectl:latest
command: [kubectl]
args:
- rollout
- status
- deployment/{{workflow.parameters.service-name}}Platform Metrics
# Track platform adoption and usage
import prometheus_client
# Metrics
services_provisioned = prometheus_client.Counter(
'platform_services_provisioned_total',
'Total services provisioned',
['service_type']
)
provisioning_duration = prometheus_client.Histogram(
'platform_provisioning_duration_seconds',
'Time to provision service',
['service_type']
)
developer_satisfaction = prometheus_client.Gauge(
'platform_developer_satisfaction',
'Developer satisfaction score',
['team']
)
# Usage
services_provisioned.labels(service_type='web-service').inc()
provisioning_duration.labels(service_type='web-service').observe(45.2)
developer_satisfaction.labels(team='backend').set(8.5)Documentation and Runbooks
# Web Service Deployment Guide
## Prerequisites
- Docker installed
- kubectl configured
- Access to platform portal
## Quick Start
1. **Create service**
```bash
platform scaffold web-service my-app
cd my-appConfigure
Editplatform.yaml:service: name: my-app replicas: 3 cpu: 512m memory: 512MiDeploy
platform deploy
Troubleshooting
Service not starting
- Check logs:
platform logs my-app - Verify resources:
platform status my-app - Check health:
platform health my-app
High latency
- Scale up:
platform scale my-app --replicas 5 - Check metrics:
platform metrics my-app
---
<div class="quiz" data-correct="0">
<p class="font-semibold mb-3">❓ What is an Internal Developer Platform (IDP)?</p>
<div class="space-y-2">
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q7384629" value="0">
<span>A self-service platform that abstracts infrastructure complexity</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q7384629" value="1">
<span>A version control system</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q7384629" value="2">
<span>A monitoring tool</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q7384629" value="3">
<span>A container registry</span>
</label>
</div>
<button class="quiz-btn mt-3 px-4 py-2 bg-blue-600 text-white rounded text-sm font-medium hover:bg-blue-700">Check Answer</button>
<p class="quiz-result text-sm mt-2 hidden"></p>
</div>
<div class="quiz" data-correct="1">
<p class="font-semibold mb-3">❓ What is a service catalog in platform engineering?</p>
<div class="space-y-2">
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q8374629" value="0">
<span>A list of deployed applications</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q8374629" value="1">
<span>A discoverable list of pre-configured infrastructure services</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q8374629" value="2">
<span>A database of customer information</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q8374629" value="3">
<span>A version control repository</span>
</label>
</div>
<button class="quiz-btn mt-3 px-4 py-2 bg-blue-600 text-white rounded text-sm font-medium hover:bg-blue-700">Check Answer</button>
<p class="quiz-result text-sm mt-2 hidden"></p>
</div>
<div class="quiz" data-correct="0">
<p class="font-semibold mb-3">❓ What are golden paths?</p>
<div class="space-y-2">
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q9284736" value="0">
<span>Opinionated, pre-configured deployment patterns</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q9284736" value="1">
<span>Network routing paths</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q9284736" value="2">
<span>Database migration strategies</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q9284736" value="3">
<span>Security policies</span>
</label>
</div>
<button class="quiz-btn mt-3 px-4 py-2 bg-blue-600 text-white rounded text-sm font-medium hover:bg-blue-700">Check Answer</button>
<p class="quiz-result text-sm mt-2 hidden"></p>
</div>
<div class="quiz" data-correct="2">
<p class="font-semibold mb-3">❓ What is Backstage?</p>
<div class="space-y-2">
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q7463829" value="0">
<span>A container orchestration platform</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q7463829" value="1">
<span>A CI/CD tool</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q7463829" value="2">
<span>An open-source developer portal</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q7463829" value="3">
<span>A monitoring system</span>
</label>
</div>
<button class="quiz-btn mt-3 px-4 py-2 bg-blue-600 text-white rounded text-sm font-medium hover:bg-blue-700">Check Answer</button>
<p class="quiz-result text-sm mt-2 hidden"></p>
</div>
<div class="quiz" data-correct="1">
<p class="font-semibold mb-3">❓ What is the primary goal of platform engineering?</p>
<div class="space-y-2">
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q8374629" value="0">
<span>To replace developers with automation</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q8374629" value="1">
<span>To reduce cognitive load and enable developer self-service</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q8374629" value="2">
<span>To eliminate infrastructure teams</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="radio" name="q8374629" value="3">
<span>To standardize all applications</span>
</label>
</div>
<button class="quiz-btn mt-3 px-4 py-2 bg-blue-600 text-white rounded text-sm font-medium hover:bg-blue-700">Check Answer</button>
<p class="quiz-result text-sm mt-2 hidden"></p>
</div>