551 lines
13 KiB
Markdown
551 lines
13 KiB
Markdown
|
|
# 黄金路径模板示例
|
|||
|
|
|
|||
|
|
基于Backstage Software Templates的黄金路径实现参考。
|
|||
|
|
|
|||
|
|
## 黄金路径设计原则
|
|||
|
|
|
|||
|
|
### 核心理念
|
|||
|
|
- **降低认知负荷**:封装复杂性,暴露简单接口
|
|||
|
|
- **默认安全**:安全配置内置,合规自动满足
|
|||
|
|
- **自助服务**:开发者无需等待审批即可启动
|
|||
|
|
- **透明可学**:生成代码可读可改,作为教学工具
|
|||
|
|
|
|||
|
|
### 模板分层架构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
开发者输入 (元数据)
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌───────────────────┐
|
|||
|
|
│ 软件模板 │ ← Backstage Scaffolder
|
|||
|
|
│ (YAML定义) │
|
|||
|
|
└─────────┬─────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌───────────────────┐
|
|||
|
|
│ 骨架代码 │ ← 标准化项目结构
|
|||
|
|
│ (Skeleton) │
|
|||
|
|
└─────────┬─────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌───────────────────┐
|
|||
|
|
│ IaC模块 │ ← Terraform/Helm封装
|
|||
|
|
│ (基础设施) │
|
|||
|
|
└─────────┬─────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌───────────────────┐
|
|||
|
|
│ GitOps配置 │ ← ArgoCD/Flux部署
|
|||
|
|
│ (CD流水线) │
|
|||
|
|
└───────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 模板示例一:后端微服务
|
|||
|
|
|
|||
|
|
### template.yaml
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: scaffolder.backstage.io/v1beta3
|
|||
|
|
kind: Template
|
|||
|
|
metadata:
|
|||
|
|
name: backend-service-go
|
|||
|
|
title: Go 后端微服务
|
|||
|
|
description: |
|
|||
|
|
创建一个生产就绪的Go微服务,包含:
|
|||
|
|
- Gin框架 + 标准项目结构
|
|||
|
|
- OpenTelemetry可观测性
|
|||
|
|
- Docker + Kubernetes部署
|
|||
|
|
- GitHub Actions CI/CD
|
|||
|
|
- SLSA L3合规
|
|||
|
|
tags:
|
|||
|
|
- go
|
|||
|
|
- backend
|
|||
|
|
- microservice
|
|||
|
|
- recommended
|
|||
|
|
spec:
|
|||
|
|
owner: platform-team
|
|||
|
|
type: service
|
|||
|
|
|
|||
|
|
parameters:
|
|||
|
|
- title: 服务基本信息
|
|||
|
|
required:
|
|||
|
|
- name
|
|||
|
|
- owner
|
|||
|
|
- description
|
|||
|
|
properties:
|
|||
|
|
name:
|
|||
|
|
title: 服务名称
|
|||
|
|
type: string
|
|||
|
|
description: 唯一的服务标识符 (小写字母、数字、连字符)
|
|||
|
|
pattern: '^[a-z0-9-]+$'
|
|||
|
|
ui:autofocus: true
|
|||
|
|
owner:
|
|||
|
|
title: 负责团队
|
|||
|
|
type: string
|
|||
|
|
ui:field: OwnerPicker
|
|||
|
|
ui:options:
|
|||
|
|
catalogFilter:
|
|||
|
|
kind: Group
|
|||
|
|
description:
|
|||
|
|
title: 服务描述
|
|||
|
|
type: string
|
|||
|
|
description: 简短描述服务用途
|
|||
|
|
|
|||
|
|
- title: 技术配置
|
|||
|
|
properties:
|
|||
|
|
database:
|
|||
|
|
title: 数据库
|
|||
|
|
type: string
|
|||
|
|
enum:
|
|||
|
|
- none
|
|||
|
|
- postgresql
|
|||
|
|
- mysql
|
|||
|
|
default: none
|
|||
|
|
description: 选择需要的数据库类型
|
|||
|
|
cache:
|
|||
|
|
title: 缓存
|
|||
|
|
type: boolean
|
|||
|
|
default: false
|
|||
|
|
description: 是否需要Redis缓存
|
|||
|
|
messageQueue:
|
|||
|
|
title: 消息队列
|
|||
|
|
type: string
|
|||
|
|
enum:
|
|||
|
|
- none
|
|||
|
|
- kafka
|
|||
|
|
- sqs
|
|||
|
|
default: none
|
|||
|
|
|
|||
|
|
- title: 部署配置
|
|||
|
|
properties:
|
|||
|
|
environment:
|
|||
|
|
title: 初始环境
|
|||
|
|
type: array
|
|||
|
|
items:
|
|||
|
|
type: string
|
|||
|
|
enum:
|
|||
|
|
- development
|
|||
|
|
- staging
|
|||
|
|
- production
|
|||
|
|
default:
|
|||
|
|
- development
|
|||
|
|
- staging
|
|||
|
|
region:
|
|||
|
|
title: 部署区域
|
|||
|
|
type: string
|
|||
|
|
enum:
|
|||
|
|
- ap-northeast-1
|
|||
|
|
- us-east-1
|
|||
|
|
- eu-west-1
|
|||
|
|
default: ap-northeast-1
|
|||
|
|
|
|||
|
|
steps:
|
|||
|
|
# Step 1: 生成代码骨架
|
|||
|
|
- id: fetch-skeleton
|
|||
|
|
name: 获取代码骨架
|
|||
|
|
action: fetch:template
|
|||
|
|
input:
|
|||
|
|
url: ./skeleton
|
|||
|
|
values:
|
|||
|
|
name: ${{ parameters.name }}
|
|||
|
|
owner: ${{ parameters.owner }}
|
|||
|
|
description: ${{ parameters.description }}
|
|||
|
|
database: ${{ parameters.database }}
|
|||
|
|
cache: ${{ parameters.cache }}
|
|||
|
|
messageQueue: ${{ parameters.messageQueue }}
|
|||
|
|
|
|||
|
|
# Step 2: 生成基础设施代码
|
|||
|
|
- id: generate-infra
|
|||
|
|
name: 生成基础设施配置
|
|||
|
|
action: fetch:template
|
|||
|
|
input:
|
|||
|
|
url: ./infra-template
|
|||
|
|
targetPath: ./infra
|
|||
|
|
values:
|
|||
|
|
name: ${{ parameters.name }}
|
|||
|
|
environments: ${{ parameters.environment }}
|
|||
|
|
region: ${{ parameters.region }}
|
|||
|
|
database: ${{ parameters.database }}
|
|||
|
|
cache: ${{ parameters.cache }}
|
|||
|
|
|
|||
|
|
# Step 3: 创建代码仓库
|
|||
|
|
- id: publish-github
|
|||
|
|
name: 创建GitHub仓库
|
|||
|
|
action: publish:github
|
|||
|
|
input:
|
|||
|
|
allowedHosts: ['github.com']
|
|||
|
|
repoUrl: github.com?owner=our-org&repo=${{ parameters.name }}
|
|||
|
|
description: ${{ parameters.description }}
|
|||
|
|
defaultBranch: main
|
|||
|
|
protectDefaultBranch: true
|
|||
|
|
requireCodeOwnerReviews: true
|
|||
|
|
requiredStatusChecks:
|
|||
|
|
- ci/build
|
|||
|
|
- ci/test
|
|||
|
|
- security/scan
|
|||
|
|
|
|||
|
|
# Step 4: 注册到软件目录
|
|||
|
|
- id: register-catalog
|
|||
|
|
name: 注册到软件目录
|
|||
|
|
action: catalog:register
|
|||
|
|
input:
|
|||
|
|
repoContentsUrl: ${{ steps['publish-github'].output.repoContentsUrl }}
|
|||
|
|
catalogInfoPath: /catalog-info.yaml
|
|||
|
|
|
|||
|
|
# Step 5: 创建ArgoCD应用
|
|||
|
|
- id: create-argocd-app
|
|||
|
|
name: 配置GitOps部署
|
|||
|
|
action: argocd:create-resources
|
|||
|
|
input:
|
|||
|
|
appName: ${{ parameters.name }}
|
|||
|
|
projectName: default
|
|||
|
|
repoUrl: ${{ steps['publish-github'].output.remoteUrl }}
|
|||
|
|
path: ./infra/k8s
|
|||
|
|
|
|||
|
|
output:
|
|||
|
|
links:
|
|||
|
|
- title: 代码仓库
|
|||
|
|
url: ${{ steps['publish-github'].output.remoteUrl }}
|
|||
|
|
- title: 软件目录
|
|||
|
|
icon: catalog
|
|||
|
|
entityRef: ${{ steps['register-catalog'].output.entityRef }}
|
|||
|
|
- title: CI流水线
|
|||
|
|
url: ${{ steps['publish-github'].output.remoteUrl }}/actions
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 骨架代码结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
skeleton/
|
|||
|
|
├── cmd/
|
|||
|
|
│ └── server/
|
|||
|
|
│ └── main.go
|
|||
|
|
├── internal/
|
|||
|
|
│ ├── handler/
|
|||
|
|
│ │ └── health.go
|
|||
|
|
│ ├── middleware/
|
|||
|
|
│ │ ├── logging.go
|
|||
|
|
│ │ └── tracing.go
|
|||
|
|
│ ├── repository/
|
|||
|
|
│ └── service/
|
|||
|
|
├── pkg/
|
|||
|
|
│ └── config/
|
|||
|
|
│ └── config.go
|
|||
|
|
├── api/
|
|||
|
|
│ └── openapi.yaml
|
|||
|
|
├── .github/
|
|||
|
|
│ └── workflows/
|
|||
|
|
│ ├── ci.yaml
|
|||
|
|
│ └── release.yaml
|
|||
|
|
├── Dockerfile
|
|||
|
|
├── Makefile
|
|||
|
|
├── go.mod
|
|||
|
|
├── catalog-info.yaml
|
|||
|
|
└── README.md
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 模板示例二:前端应用
|
|||
|
|
|
|||
|
|
### template.yaml
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: scaffolder.backstage.io/v1beta3
|
|||
|
|
kind: Template
|
|||
|
|
metadata:
|
|||
|
|
name: frontend-nextjs
|
|||
|
|
title: Next.js 前端应用
|
|||
|
|
description: |
|
|||
|
|
创建一个现代化的Next.js前端应用,包含:
|
|||
|
|
- Next.js 14 App Router
|
|||
|
|
- TypeScript + Tailwind CSS
|
|||
|
|
- shadcn/ui组件库
|
|||
|
|
- 国际化(i18n)支持
|
|||
|
|
- Vercel/容器化部署
|
|||
|
|
tags:
|
|||
|
|
- nextjs
|
|||
|
|
- frontend
|
|||
|
|
- typescript
|
|||
|
|
- recommended
|
|||
|
|
spec:
|
|||
|
|
owner: platform-team
|
|||
|
|
type: website
|
|||
|
|
|
|||
|
|
parameters:
|
|||
|
|
- title: 应用基本信息
|
|||
|
|
required:
|
|||
|
|
- name
|
|||
|
|
- owner
|
|||
|
|
properties:
|
|||
|
|
name:
|
|||
|
|
title: 应用名称
|
|||
|
|
type: string
|
|||
|
|
pattern: '^[a-z0-9-]+$'
|
|||
|
|
owner:
|
|||
|
|
title: 负责团队
|
|||
|
|
type: string
|
|||
|
|
ui:field: OwnerPicker
|
|||
|
|
|
|||
|
|
- title: 功能配置
|
|||
|
|
properties:
|
|||
|
|
authentication:
|
|||
|
|
title: 认证方案
|
|||
|
|
type: string
|
|||
|
|
enum:
|
|||
|
|
- none
|
|||
|
|
- nextauth
|
|||
|
|
- auth0
|
|||
|
|
- custom
|
|||
|
|
default: none
|
|||
|
|
i18n:
|
|||
|
|
title: 国际化
|
|||
|
|
type: boolean
|
|||
|
|
default: false
|
|||
|
|
analytics:
|
|||
|
|
title: 分析集成
|
|||
|
|
type: string
|
|||
|
|
enum:
|
|||
|
|
- none
|
|||
|
|
- google-analytics
|
|||
|
|
- posthog
|
|||
|
|
- mixpanel
|
|||
|
|
default: none
|
|||
|
|
|
|||
|
|
- title: 部署方式
|
|||
|
|
properties:
|
|||
|
|
deployTarget:
|
|||
|
|
title: 部署目标
|
|||
|
|
type: string
|
|||
|
|
enum:
|
|||
|
|
- vercel
|
|||
|
|
- kubernetes
|
|||
|
|
- cloudflare-pages
|
|||
|
|
default: vercel
|
|||
|
|
|
|||
|
|
steps:
|
|||
|
|
- id: fetch-skeleton
|
|||
|
|
name: 获取代码骨架
|
|||
|
|
action: fetch:template
|
|||
|
|
input:
|
|||
|
|
url: ./skeleton-nextjs
|
|||
|
|
values:
|
|||
|
|
name: ${{ parameters.name }}
|
|||
|
|
authentication: ${{ parameters.authentication }}
|
|||
|
|
i18n: ${{ parameters.i18n }}
|
|||
|
|
analytics: ${{ parameters.analytics }}
|
|||
|
|
|
|||
|
|
- id: install-shadcn
|
|||
|
|
name: 配置shadcn/ui
|
|||
|
|
action: run:command
|
|||
|
|
input:
|
|||
|
|
command: npx shadcn-ui@latest init -y
|
|||
|
|
|
|||
|
|
- id: publish-github
|
|||
|
|
name: 创建GitHub仓库
|
|||
|
|
action: publish:github
|
|||
|
|
input:
|
|||
|
|
repoUrl: github.com?owner=our-org&repo=${{ parameters.name }}
|
|||
|
|
|
|||
|
|
- id: register-catalog
|
|||
|
|
name: 注册到软件目录
|
|||
|
|
action: catalog:register
|
|||
|
|
input:
|
|||
|
|
repoContentsUrl: ${{ steps['publish-github'].output.repoContentsUrl }}
|
|||
|
|
catalogInfoPath: /catalog-info.yaml
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 模板示例三:数据管道
|
|||
|
|
|
|||
|
|
### template.yaml
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: scaffolder.backstage.io/v1beta3
|
|||
|
|
kind: Template
|
|||
|
|
metadata:
|
|||
|
|
name: data-pipeline
|
|||
|
|
title: 数据处理管道
|
|||
|
|
description: |
|
|||
|
|
创建一个数据处理管道,包含:
|
|||
|
|
- Python + Pandas/PySpark
|
|||
|
|
- Airflow DAG定义
|
|||
|
|
- dbt数据转换
|
|||
|
|
- 数据质量检查(Great Expectations)
|
|||
|
|
tags:
|
|||
|
|
- data
|
|||
|
|
- python
|
|||
|
|
- airflow
|
|||
|
|
- etl
|
|||
|
|
spec:
|
|||
|
|
owner: data-platform-team
|
|||
|
|
type: pipeline
|
|||
|
|
|
|||
|
|
parameters:
|
|||
|
|
- title: 管道基本信息
|
|||
|
|
required:
|
|||
|
|
- name
|
|||
|
|
- owner
|
|||
|
|
- schedule
|
|||
|
|
properties:
|
|||
|
|
name:
|
|||
|
|
title: 管道名称
|
|||
|
|
type: string
|
|||
|
|
owner:
|
|||
|
|
title: 负责团队
|
|||
|
|
type: string
|
|||
|
|
ui:field: OwnerPicker
|
|||
|
|
schedule:
|
|||
|
|
title: 调度频率
|
|||
|
|
type: string
|
|||
|
|
enum:
|
|||
|
|
- '@hourly'
|
|||
|
|
- '@daily'
|
|||
|
|
- '@weekly'
|
|||
|
|
- custom
|
|||
|
|
default: '@daily'
|
|||
|
|
|
|||
|
|
- title: 数据源配置
|
|||
|
|
properties:
|
|||
|
|
sources:
|
|||
|
|
title: 数据源
|
|||
|
|
type: array
|
|||
|
|
items:
|
|||
|
|
type: object
|
|||
|
|
properties:
|
|||
|
|
type:
|
|||
|
|
type: string
|
|||
|
|
enum:
|
|||
|
|
- postgresql
|
|||
|
|
- mysql
|
|||
|
|
- s3
|
|||
|
|
- bigquery
|
|||
|
|
- api
|
|||
|
|
connection:
|
|||
|
|
type: string
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## IaC模块封装示例
|
|||
|
|
|
|||
|
|
### 简化的Terraform模块接口
|
|||
|
|
|
|||
|
|
```hcl
|
|||
|
|
# 开发者只需提供这些参数
|
|||
|
|
module "backend_service" {
|
|||
|
|
source = "git::https://github.com/our-org/terraform-modules//backend-service"
|
|||
|
|
|
|||
|
|
# 必填参数
|
|||
|
|
name = "order-service"
|
|||
|
|
environment = "production"
|
|||
|
|
owner = "commerce-team"
|
|||
|
|
|
|||
|
|
# 可选参数 (有合理默认值)
|
|||
|
|
replicas = 3
|
|||
|
|
cpu = "500m"
|
|||
|
|
memory = "1Gi"
|
|||
|
|
|
|||
|
|
# 数据库配置
|
|||
|
|
database = {
|
|||
|
|
type = "postgresql"
|
|||
|
|
size = "large" # small/medium/large,平台团队定义具体规格
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 缓存配置
|
|||
|
|
cache = {
|
|||
|
|
enabled = true
|
|||
|
|
size = "medium"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 模块内部封装的复杂性
|
|||
|
|
|
|||
|
|
```hcl
|
|||
|
|
# 开发者不需要关心的内部实现
|
|||
|
|
# terraform-modules/backend-service/main.tf
|
|||
|
|
|
|||
|
|
locals {
|
|||
|
|
# 平台团队定义的规格映射
|
|||
|
|
db_sizes = {
|
|||
|
|
small = { instance_class = "db.t3.micro", storage = 20 }
|
|||
|
|
medium = { instance_class = "db.t3.small", storage = 50 }
|
|||
|
|
large = { instance_class = "db.r5.large", storage = 100 }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
resource "aws_security_group" "db" {
|
|||
|
|
# 安全组配置 - 默认最小权限
|
|||
|
|
ingress {
|
|||
|
|
from_port = 5432
|
|||
|
|
to_port = 5432
|
|||
|
|
cidr_blocks = [data.aws_vpc.main.cidr_block]
|
|||
|
|
}
|
|||
|
|
# ... 更多安全配置
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
resource "aws_db_instance" "main" {
|
|||
|
|
# 数据库实例配置
|
|||
|
|
instance_class = local.db_sizes[var.database.size].instance_class
|
|||
|
|
allocated_storage = local.db_sizes[var.database.size].storage
|
|||
|
|
|
|||
|
|
# 默认启用的安全配置
|
|||
|
|
storage_encrypted = true
|
|||
|
|
deletion_protection = var.environment == "production"
|
|||
|
|
backup_retention_period = 7
|
|||
|
|
|
|||
|
|
# 默认启用的监控
|
|||
|
|
performance_insights_enabled = true
|
|||
|
|
monitoring_interval = 60
|
|||
|
|
|
|||
|
|
# ... 更多配置
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
resource "aws_kms_key" "db_encryption" {
|
|||
|
|
# 自动创建的加密密钥
|
|||
|
|
description = "KMS key for ${var.name} database encryption"
|
|||
|
|
deletion_window_in_days = 30
|
|||
|
|
enable_key_rotation = true
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 模板质量检查清单
|
|||
|
|
|
|||
|
|
创建新模板前,确认满足以下要求:
|
|||
|
|
|
|||
|
|
### 可用性
|
|||
|
|
- [ ] 参数名称清晰易懂
|
|||
|
|
- [ ] 提供合理的默认值
|
|||
|
|
- [ ] 必填项最小化
|
|||
|
|
- [ ] 有完整的描述信息
|
|||
|
|
|
|||
|
|
### 安全性
|
|||
|
|
- [ ] 默认启用加密
|
|||
|
|
- [ ] 默认最小权限
|
|||
|
|
- [ ] 集成安全扫描
|
|||
|
|
- [ ] 无硬编码密钥
|
|||
|
|
|
|||
|
|
### 可观测性
|
|||
|
|
- [ ] 集成日志收集
|
|||
|
|
- [ ] 集成指标采集
|
|||
|
|
- [ ] 集成分布式追踪
|
|||
|
|
- [ ] 健康检查端点
|
|||
|
|
|
|||
|
|
### 可维护性
|
|||
|
|
- [ ] 生成代码可读
|
|||
|
|
- [ ] 包含README文档
|
|||
|
|
- [ ] 遵循团队规范
|
|||
|
|
- [ ] 版本化模板
|
|||
|
|
|
|||
|
|
### 合规性
|
|||
|
|
- [ ] 满足SLSA要求
|
|||
|
|
- [ ] 自动生成SBOM
|
|||
|
|
- [ ] 符合组织策略
|
|||
|
|
- [ ] 资源标签完整
|