Skip to content

Lesson 3: TechDocs Architecture & Phase 7 Hands-On Lab Solutions

This module details Spotify Backstage's TechDocs (Docs-Like-Code) publishing pipeline and provides complete solutions for the Phase 7 Job-Essential Exercises.


πŸ“š TechDocs Architecture: The Docs-Like-Code Philosophy

Traditional enterprise documentation fails because it lives in static wikis (Confluence, Notion) disconnected from source code. When developers refactor an API, they forget to update the wiki, and documentation rots.

TechDocs enforces Docs-Like-Code: 1. Documentation lives as Markdown inside a /docs directory inside the service's own Git repository. 2. Every time a Pull Request merges to main, a CI/CD job compiles the markdown using mkdocs and uploads the static HTML bundle to an enterprise AWS S3 bucket. 3. Backstage fetches and displays the documentation natively inside the component's catalog page. Documentation stays synchronized with every code commit!

sequenceDiagram
    autonumber
    actor Dev as πŸ‘©β€πŸ’» Developer (Edits docs/api.md)
    participant Git as πŸ™ GitHub Enterprise
    participant CI as πŸ€– GitHub Actions (TechDocs Builder)
    participant S3 as πŸͺ£ AWS S3 (TechDocs Storage)
    participant BS as πŸ–₯️ Spotify Backstage UI

    Dev->>Git: git push origin main
    Git->>CI: Triggers .github/workflows/techdocs.yml
    CI->>CI: techdocs-cli generate (Runs MkDocs build)
    CI->>S3: techdocs-cli publish (Uploads to s3://corp-techdocs/default/component/orders/)
    Dev->>BS: Opens "Docs" tab on Order Service
    BS->>S3: Fetches HTML bundle
    BS-->>Dev: Renders interactive TechDocs with search! βœ…

πŸ› οΈ Lab 1: The Catalog Definition Challenge

Objective

Author an enterprise catalog-info.yaml declaring an OrderManagementService Component that exposes an OrderAPI, depends on an external CustomerDatabase Resource, and binds to an on-call team.

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: order-management-service
  description: "Processes customer orders and manages payment transitions"
  annotations:
    github.com/project-slug: "corp/order-management"
    backstage.io/techdocs-ref: "dir:."
    pagerduty.com/integration-key: "pd-order-mgmt-key"
    datadog.com/service-name: "order-management"
spec:
  type: service
  lifecycle: production
  owner: group:checkout-squad
  system: ecommerce-core
  providesApis:
    - order-api-v1
  dependsOn:
    - resource:default/customer-postgres-db
---
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
  name: order-api-v1
  description: "REST API for order creation and status checks"
spec:
  type: openapi
  lifecycle: production
  owner: group:checkout-squad
  system: ecommerce-core
  definition: |
    openapi: "3.0.0"
    info:
      title: Order API
      version: "1.0.0"
    paths:
      /orders:
        get:
          summary: List orders
          responses:
            '200':
              description: OK
---
apiVersion: backstage.io/v1alpha1
kind: Resource
metadata:
  name: customer-postgres-db
  description: "AWS RDS PostgreSQL Multi-AZ Cluster"
spec:
  type: database
  owner: group:platform-team
  system: ecommerce-core

πŸ› οΈ Lab 2: The Golden Path Scaffolder Challenge

Objective

Create an end-to-end Backstage Software Template (template.yaml) that prompts for a project name, renders a skeleton repository, creates a private GitHub repository, and commits an initial GitOps ArgoCD manifest.

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: python-microservice-template
  title: Production-Ready Python Service
  description: "Scaffold a Python service with Dockerfile, CI, and ArgoCD registration"
spec:
  owner: group:platform-team
  type: service

  parameters:
    - title: Microservice Metadata
      required: [app_name, owner_group]
      properties:
        app_name:
          type: string
          title: Service Identifier
          description: Lowercase alphanumeric name (e.g. inventory-service)
        owner_group:
          type: string
          title: Owning Squad
          ui:field: OwnerPicker

  steps:
    - id: template
      name: Render Template Files
      action: fetch:template
      input:
        url: ./skeleton
        values:
          app_name: ${{ parameters.app_name }}
          owner: ${{ parameters.owner_group }}

    - id: publish
      name: Publish to GitHub
      action: publish:github
      input:
        allowedHosts: ['github.com']
        description: 'Provisioned via Platform Golden Path'
        repoUrl: github.com?owner=my-enterprise-org&repo=${{ parameters.app_name }}
        defaultBranch: main
        repoVisibility: private

    - id: register
      name: Register in Backstage Catalog
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
        catalogInfoPath: '/catalog-info.yaml'

πŸ› οΈ Lab 3: The TechDocs Integration Challenge

Objective

Configure a microservice repository with a mkdocs.yml file and GitHub Actions workflow to build and publish TechDocs to an AWS S3 bucket.

1. mkdocs.yml in Microservice Root

site_name: Order Management Service Documentation
plugins:
  - techdocs-core
nav:
  - Overview: index.md
  - Architecture: architecture.md
  - API Reference: api.md

2. .github/workflows/techdocs.yml

name: Publish TechDocs to S3

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'
      - 'mkdocs.yml'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 18 }
      - uses: actions/setup-python@v5
        with: { python-version: '3.11' }

      - name: Install TechDocs CLI & MkDocs
        run: |
          pip install mkdocs-techdocs-core
          npm install -g @techdocs/cli

      - name: Generate TechDocs Static Site
        run: techdocs-cli generate --no-docker

      - name: Configure AWS Credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/TechDocsPublisherRole
          aws-region: us-east-1

      - name: Publish to S3 Bucket
        run: |
          techdocs-cli publish \
            --publisher-type awsS3 \
            --storage-name corp-backstage-techdocs-storage \
            --entity default/Component/order-management-service