Module 11 of 13 · DevOps & Platform Engineering · Intermediate

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

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: database

Developer 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.md

Backstage 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-system

Self-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-app
  1. Configure
    Edit platform.yaml:

    service:
      name: my-app
      replicas: 3
      cpu: 512m
      memory: 512Mi
  2. Deploy

    platform deploy

Troubleshooting

Service not starting

High latency


---

<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>
← Previous Continue interactively → Next →

Related Courses