$npx -y skills add BagelHole/DevOps-Security-Agent-Skills --skill platform-engineeringBuild internal developer platforms (IDPs) with self-service infrastructure, golden paths, and developer portals using Backstage, Crossplane, and score.
| 1 | # Platform Engineering |
| 2 | |
| 3 | Platform engineering is the discipline of building and maintaining internal developer platforms (IDPs) that enable self-service capabilities for software engineering teams. The goal is to reduce cognitive load, standardize infrastructure provisioning, and accelerate delivery while maintaining governance and security guardrails. |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | ## 1. When to Use |
| 8 | |
| 9 | Adopt platform engineering practices when your organization experiences: |
| 10 | |
| 11 | - **Cognitive overload on dev teams** -- developers spend more time on infrastructure wiring than writing business logic. |
| 12 | - **Inconsistent environments** -- every team provisions infrastructure differently, causing drift and outages. |
| 13 | - **Slow onboarding** -- new engineers take weeks to get a working development environment. |
| 14 | - **Repeated toil** -- the same Terraform/Helm/CI boilerplate is copy-pasted across dozens of repos. |
| 15 | - **Compliance bottlenecks** -- security and ops reviews gate every deployment, slowing release cadence. |
| 16 | - **Scale inflection points** -- you have 5+ teams and shared infrastructure concerns (networking, observability, secrets). |
| 17 | |
| 18 | Platform engineering is NOT about replacing ops with a portal. It is about encoding organizational standards into reusable, self-service abstractions that dev teams consume through golden paths. |
| 19 | |
| 20 | --- |
| 21 | |
| 22 | ## 2. Backstage Setup |
| 23 | |
| 24 | [Backstage](https://backstage.io) is the leading open-source developer portal framework, originally created at Spotify. |
| 25 | |
| 26 | ### Installation |
| 27 | |
| 28 | ```bash |
| 29 | # Prerequisites: Node.js 18+, yarn 1.x |
| 30 | npx @backstage/create-app@latest |
| 31 | |
| 32 | # Follow the prompts -- name your app, e.g., "internal-platform" |
| 33 | cd internal-platform |
| 34 | |
| 35 | # Start the development server |
| 36 | yarn dev |
| 37 | ``` |
| 38 | |
| 39 | ### Production Docker Build |
| 40 | |
| 41 | ```dockerfile |
| 42 | # Dockerfile for Backstage production image |
| 43 | FROM node:18-bookworm-slim AS build |
| 44 | WORKDIR /app |
| 45 | |
| 46 | COPY package.json yarn.lock ./ |
| 47 | COPY packages/ packages/ |
| 48 | COPY plugins/ plugins/ |
| 49 | |
| 50 | RUN yarn install --frozen-lockfile |
| 51 | RUN yarn tsc |
| 52 | RUN yarn build:backend |
| 53 | |
| 54 | FROM node:18-bookworm-slim |
| 55 | WORKDIR /app |
| 56 | |
| 57 | COPY --from=build /app/packages/backend/dist/ ./ |
| 58 | COPY --from=build /app/node_modules/ ./node_modules/ |
| 59 | COPY app-config.yaml app-config.production.yaml ./ |
| 60 | |
| 61 | ENV NODE_ENV=production |
| 62 | CMD ["node", "packages/backend", "--config", "app-config.production.yaml"] |
| 63 | ``` |
| 64 | |
| 65 | ### Core app-config.yaml |
| 66 | |
| 67 | ```yaml |
| 68 | # app-config.yaml |
| 69 | app: |
| 70 | title: Internal Developer Platform |
| 71 | baseUrl: http://localhost:3000 |
| 72 | |
| 73 | organization: |
| 74 | name: MyOrg |
| 75 | |
| 76 | backend: |
| 77 | baseUrl: http://localhost:7007 |
| 78 | listen: |
| 79 | port: 7007 |
| 80 | database: |
| 81 | client: pg |
| 82 | connection: |
| 83 | host: ${POSTGRES_HOST} |
| 84 | port: ${POSTGRES_PORT} |
| 85 | user: ${POSTGRES_USER} |
| 86 | password: ${POSTGRES_PASSWORD} |
| 87 | |
| 88 | integrations: |
| 89 | github: |
| 90 | - host: github.com |
| 91 | token: ${GITHUB_TOKEN} |
| 92 | |
| 93 | catalog: |
| 94 | import: |
| 95 | entityFilename: catalog-info.yaml |
| 96 | pullRequestBranchName: backstage-integration |
| 97 | rules: |
| 98 | - allow: [Component, System, API, Resource, Location, Template] |
| 99 | locations: |
| 100 | - type: url |
| 101 | target: https://github.com/myorg/software-catalog/blob/main/catalog-info.yaml |
| 102 | - type: url |
| 103 | target: https://github.com/myorg/backstage-templates/blob/main/all-templates.yaml |
| 104 | ``` |
| 105 | |
| 106 | --- |
| 107 | |
| 108 | ## 3. Crossplane for Self-Service Infrastructure |
| 109 | |
| 110 | Crossplane extends Kubernetes to provision and manage cloud infrastructure through declarative YAML. |
| 111 | |
| 112 | ### Install Crossplane |
| 113 | |
| 114 | ```bash |
| 115 | # Add the Crossplane Helm repo |
| 116 | helm repo add crossplane-stable https://charts.crossplane.io/stable |
| 117 | helm repo update |
| 118 | |
| 119 | # Install Crossplane into its own namespace |
| 120 | helm install crossplane crossplane-stable/crossplane \ |
| 121 | --namespace crossplane-system \ |
| 122 | --create-namespace \ |
| 123 | --set args='{"--enable-composition-revisions"}' |
| 124 | |
| 125 | # Install the AWS provider |
| 126 | kubectl apply -f - <<EOF |
| 127 | apiVersion: pkg.crossplane.io/v1 |
| 128 | kind: Provider |
| 129 | metadata: |
| 130 | name: provider-aws |
| 131 | spec: |
| 132 | package: xpkg.upbound.io/upbound/provider-family-aws:v1.1.0 |
| 133 | EOF |
| 134 | |
| 135 | # Configure AWS credentials |
| 136 | kubectl create secret generic aws-creds \ |
| 137 | -n crossplane-system \ |
| 138 | --from-file=creds=./aws-credentials.txt |
| 139 | |
| 140 | kubectl apply -f - <<EOF |
| 141 | apiVersion: aws.upbound.io/v1beta1 |
| 142 | kind: ProviderConfig |
| 143 | metadata: |
| 144 | name: default |
| 145 | spec: |
| 146 | credentials: |
| 147 | source: Secret |
| 148 | secretRef: |
| 149 | namespace: crossplane-system |
| 150 | name: aws-creds |
| 151 | key: creds |
| 152 | EOF |
| 153 | ``` |
| 154 | |
| 155 | ### CompositeResourceDefinition (XRD) |
| 156 | |
| 157 | This defines a new platform API that developers consume without knowing the underlying cloud resources. |
| 158 | |
| 159 | ```yaml |
| 160 | # xrd-application-database.yaml |
| 161 | apiVersion: apiextensions.crossplane.io/v1 |
| 162 | kind: CompositeResourceDefinition |
| 163 | metadata: |
| 164 | name: xapplicationdatabases.platform.myorg.io |
| 165 | spec: |
| 166 | group: platform.myorg.io |
| 167 | names: |
| 168 | kind: XApplicationDatabase |
| 169 | plural: xapplicationdatabases |
| 170 | claimNames: |
| 171 | kind: ApplicationDatabase |
| 172 | plural: appli |