Golden Path의 정의와 철학, 옵셔널하되 매력적인 경로 설계, Terraform/Pulumi 기반 자동 인프라 프로비저닝, 그리고 80% 이상 자발적 채택률의 비결을 다룹니다.
**Golden Path(골든 패스)**는 조직의 모범 사례(Best Practice)를 자연스럽게 포함하는 표준화된 개발 경로입니다. Spotify에서 처음 도입한 이 개념은 "잘 통합된 코드와 역량의 템플릿화된 조합(Templated composition of well-integrated code and capabilities)"으로 정의됩니다.
핵심은 선택의 자유를 유지하면서도 올바른 선택을 가장 쉬운 선택으로 만드는 것입니다.
Golden Path를 이해하는 가장 좋은 비유는 "잘 포장된 길과 가드레일"입니다.
Golden Path 위를 걸으면 보안, 모니터링, CI/CD가 자동으로 구성됩니다. 이 길을 벗어나는 것도 가능하지만, 그 경우 모든 것을 직접 구성해야 합니다. 대부분의 개발자는 자연스럽게 편한 길을 선택합니다.
Golden Path는 "Golden Cage(황금 우리)"가 아닙니다. 강제는 반발을 낳고, 우회로를 만들어 냅니다. 잘 설계된 Golden Path는 강제 없이도 80% 이상의 개발자가 자발적으로 선택합니다.
Golden Path는 강제 사항이 아닌 선택 사항이어야 합니다. 단, 선택하지 않을 이유가 없을 만큼 매력적이어야 합니다.
매력적인 Golden Path의 조건:
| 조건 | 설명 | 예시 |
|---|---|---|
| 빠른 시작 | 30분 이내에 첫 배포 가능 | 템플릿으로 프로젝트 생성 후 즉시 배포 |
| 자동화 | 수작업 최소화 | CI/CD, 모니터링, 보안 스캔 자동 구성 |
| 문서화 | 모든 과정이 명확히 문서화 | 단계별 가이드, FAQ, 트러블슈팅 |
| 업데이트 용이 | 플랫폼 업데이트 시 자동 반영 | 공유 라이브러리, 기본 이미지 업데이트 |
모든 유스케이스를 커버하려고 하면 Golden Path가 복잡해집니다. 가장 흔한 80%의 유스케이스에 집중하고, 나머지 20%는 커스터마이징을 허용합니다.
초기에는 단순하게 시작하고, 필요에 따라 복잡성을 추가할 수 있어야 합니다. "eject" 패턴처럼 표준에서 벗어날 수 있는 명확한 경로를 제공합니다.
Golden Path를 사용하는 팀의 피드백을 수집하고, 이를 반영하여 지속적으로 개선합니다.
Golden Path의 시작점은 프로젝트 템플릿입니다. 조직에서 사용하는 주요 기술 스택별로 템플릿을 제공합니다.
templates:
backend:
- name: "spring-boot-service"
language: Java
framework: Spring Boot 3.4
includes:
- "Gradle 빌드 설정"
- "GitHub Actions CI/CD"
- "Dockerfile (멀티스테이지)"
- "Kubernetes 매니페스트"
- "ArgoCD Application"
- "Prometheus 메트릭 엔드포인트"
- "Structured Logging (JSON)"
- "Health Check 엔드포인트"
- "OpenAPI 스펙 자동 생성"
- "catalog-info.yaml"
- "TechDocs 템플릿"
- name: "go-grpc-service"
language: Go
framework: "gRPC + Connect"
includes:
- "Go 모듈 설정"
- "Buf 기반 protobuf 관리"
- "GitHub Actions CI/CD"
- "Dockerfile"
- "Kubernetes 매니페스트"
- "gRPC 리플렉션"
- "OpenTelemetry 트레이싱"
- name: "fastapi-service"
language: Python
framework: FastAPI
includes:
- "uv 기반 의존성 관리"
- "GitHub Actions CI/CD"
- "Dockerfile"
- "Kubernetes 매니페스트"
- "Pydantic 스키마 검증"
- "Alembic DB 마이그레이션"
frontend:
- name: "nextjs-app"
language: TypeScript
framework: "Next.js 16 (App Router)"
includes:
- "pnpm 기반 의존성 관리"
- "Tailwind CSS"
- "GitHub Actions CI/CD"
- "Dockerfile"
- "Lighthouse CI"가장 많이 사용되는 Spring Boot 템플릿의 내부를 살펴보겠습니다.
# 멀티스테이지 빌드
FROM eclipse-temurin:21-jdk AS builder
WORKDIR /app
COPY . .
RUN ./gradlew bootJar --no-daemon
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar
# 보안: root가 아닌 사용자로 실행
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-jar", "app.jar"]apiVersion: apps/v1
kind: Deployment
metadata:
name: ${{ values.serviceName }}
labels:
app: ${{ values.serviceName }}
backstage.io/kubernetes-id: ${{ values.serviceName }}
spec:
replicas: 2
selector:
matchLabels:
app: ${{ values.serviceName }}
template:
metadata:
labels:
app: ${{ values.serviceName }}
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/actuator/prometheus"
spec:
containers:
- name: ${{ values.serviceName }}
image: "ghcr.io/mycompany/${{ values.serviceName }}:latest"
ports:
- containerPort: 8080
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
env:
- name: SPRING_PROFILES_ACTIVE
value: "kubernetes"Golden Path의 핵심 가치 중 하나는 인프라를 자동으로 프로비저닝하는 것입니다. 개발자가 "PostgreSQL 데이터베이스가 필요합니다"라고 선택하면, 적절한 인프라가 자동으로 생성됩니다.
variable "service_name" {
description = "서비스 이름"
type = string
}
variable "environment" {
description = "배포 환경"
type = string
}
variable "instance_class" {
description = "RDS 인스턴스 클래스"
type = string
default = "db.t4g.medium"
}
resource "aws_db_instance" "main" {
identifier = "${var.service_name}-${var.environment}"
engine = "postgres"
engine_version = "16.4"
instance_class = var.instance_class
allocated_storage = 20
max_allocated_storage = 100
storage_encrypted = true
db_name = replace(var.service_name, "-", "_")
username = "app_user"
password = random_password.db_password.result
vpc_security_group_ids = [aws_security_group.db.id]
db_subnet_group_name = aws_db_subnet_group.main.name
backup_retention_period = var.environment == "production" ? 30 : 7
multi_az = var.environment == "production" ? true : false
tags = {
Service = var.service_name
Environment = var.environment
ManagedBy = "terraform"
CostCenter = var.service_name
}
}
resource "random_password" "db_password" {
length = 32
special = false
}
resource "aws_secretsmanager_secret" "db_credentials" {
name = "${var.service_name}/${var.environment}/db-credentials"
}
resource "aws_secretsmanager_secret_version" "db_credentials" {
secret_id = aws_secretsmanager_secret.db_credentials.id
secret_string = jsonencode({
host = aws_db_instance.main.address
port = aws_db_instance.main.port
database = aws_db_instance.main.db_name
username = aws_db_instance.main.username
password = random_password.db_password.result
})
}Backstage Scaffolder가 Terraform 모듈을 실행하도록 연결합니다.
steps:
# ... 이전 스텝 ...
- id: provision-database
name: "데이터베이스 프로비저닝"
if: ${{ parameters.database !== 'none' }}
action: mycompany:terraform:apply
input:
module: "rds-postgresql"
variables:
service_name: ${{ parameters.serviceName }}
environment: "dev"
instance_class: "db.t4g.micro"
workspace: "${{ parameters.serviceName }}-dev"
- id: inject-db-secret
name: "DB 시크릿 연결"
if: ${{ parameters.database !== 'none' }}
action: mycompany:kubernetes:create-external-secret
input:
namespace: ${{ parameters.serviceName }}
secretName: "db-credentials"
remoteRef:
key: "${{ parameters.serviceName }}/dev/db-credentials"인프라 프로비저닝은 환경별로 다른 스펙을 적용해야 합니다. dev 환경에는 최소 사양을, production에는 적절한 사양을 자동으로 선택하도록 템플릿을 설계하세요. 이렇게 하면 비용도 절약되고, 개발자가 환경별 차이를 신경 쓸 필요도 없습니다.
잘 설계된 Golden Path는 조직 내 80% 이상의 개발자가 자발적으로 선택합니다. 반면, 잘못 설계된 Golden Path는 20%도 채택하지 않습니다. 이 격차를 만드는 요인을 분석합니다.
1. 시간 절약이 즉각 체감되어야 합니다
가장 강력한 동기는 "이게 더 빠르다"는 경험입니다. 기존에 2일 걸리던 프로젝트 셋업이 30분으로 줄어들면, 다음 프로젝트에서도 당연히 Golden Path를 선택합니다.
2. 초기 사용자의 성공 사례가 전파되어야 합니다
파일럿 팀의 성공 경험을 사내에 적극 공유합니다. "checkout 팀은 Golden Path로 신규 서비스를 4시간 만에 프로덕션에 배포했습니다"와 같은 구체적인 사례가 효과적입니다.
3. 문서와 지원이 충분해야 합니다
Golden Path 사용 중 문제가 발생했을 때 빠르게 해결할 수 있어야 합니다. FAQ, 트러블슈팅 가이드, 그리고 전담 Slack 채널이 필수입니다.
4. 지속적으로 업데이트되어야 합니다
Golden Path가 구식이 되면 개발자들은 떠납니다. 보안 패치, 프레임워크 업데이트, 새로운 모범 사례를 정기적으로 반영해야 합니다.
metrics:
- name: "템플릿 사용률"
formula: "Scaffolder로 생성한 신규 서비스 / 전체 신규 서비스"
target: "80% 이상"
measurement: "월별"
- name: "Golden Path 이탈률"
formula: "Golden Path에서 eject한 서비스 / 전체 Golden Path 서비스"
target: "10% 이하"
measurement: "분기별"
- name: "첫 배포 소요 시간"
formula: "프로젝트 생성부터 첫 프로덕션 배포까지"
target: "4시간 이내"
measurement: "서비스 생성 시"
- name: "개발자 만족도"
formula: "Golden Path 관련 NPS"
target: "40 이상"
measurement: "분기별"Golden Path 설계에서 흔히 발생하는 반패턴과 그 대안을 정리합니다.
Golden Path를 사용하지 않으면 배포를 막거나, 코드 리뷰를 거부하는 등의 강제는 역효과를 냅니다. 개발자들은 우회로를 찾거나 플랫폼 팀에 대한 불만이 쌓입니다.
대안: 인센티브 기반 접근. Golden Path를 사용하면 더 빠른 보안 리뷰, 우선적인 인프라 지원 등의 혜택을 제공합니다.
마이크로서비스, 배치 작업, 프론트엔드, 라이브러리 등 모든 유형을 하나의 템플릿에 담으려는 시도는 복잡성만 증가시킵니다.
대안: 유형별 특화된 템플릿. 각 템플릿은 하나의 유스케이스에 최적화합니다.
한번 생성된 프로젝트가 Golden Path의 업데이트를 받을 수 없는 구조는 시간이 지나면 표류(drift)가 발생합니다.
대안: 공유 라이브러리, 기본 이미지, CI/CD 워크플로우 재사용 등을 통해 업데이트가 자동으로 전파되는 구조를 설계합니다.
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
# 조직 공통 워크플로우 재사용
uses: mycompany/.github/.github/workflows/java-ci.yaml@v3
with:
java-version: "21"
gradle-tasks: "build test"
secrets: inherit
security:
uses: mycompany/.github/.github/workflows/security-scan.yaml@v3
secrets: inherit
deploy:
if: github.ref == 'refs/heads/main'
needs: [build, security]
uses: mycompany/.github/.github/workflows/deploy-argocd.yaml@v3
with:
app-name: ${{ github.event.repository.name }}
environment: dev
secrets: inheritGolden Path의 업데이트 전파 메커니즘은 설계 초기부터 고려해야 합니다. 나중에 추가하려면 기존의 모든 프로젝트를 마이그레이션해야 하므로 비용이 크게 증가합니다.
이번 장에서는 Golden Path의 철학과 설계 원칙, 구현 방법을 다루었습니다.
다음 장에서는 셀프서비스 인프라를 다룹니다. 개발자가 플랫폼을 통해 직접 인프라를 요청하고 프로비저닝하는 메커니즘, GitOps 기반의 인프라 관리, 그리고 Crossplane을 활용한 Kubernetes 네이티브 인프라 추상화를 살펴보겠습니다.
이 글이 도움이 되셨나요?
셀프서비스의 핵심 원칙, GitOps 기반 인프라 요청, Crossplane을 활용한 Kubernetes 네이티브 인프라 추상화, 그리고 승인 워크플로우를 다룹니다.
Backstage 소프트웨어 카탈로그의 엔티티 모델, catalog-info.yaml 스키마, 메타데이터 표준화, 그리고 Scaffolder를 활용한 프로젝트 자동 생성을 다룹니다.
Platform as a Product 관점에서의 API 계층 설계, 추상화 수준 결정, 내부 API 버전닝, 인증과 인가, 감사 로깅, 그리고 CLI 도구 제공까지 다룹니다.