Design golden paths that guide developers to the right patterns, tools, and workflows by making the best practices the easiest path. Covers developer experience measurement, friction mapping, toolchain standardization, and platform adoption metrics.
Golden paths are the standard, well-documented, automated workflows that enable developers to reliably build, test, deploy, and operate software on a platform. They matter when teams grow beyond a single project or when multiple teams share infrastructure, environments, and services. A golden path is not a checklist; it is a repeatable, self-serve process that reduces cognitive load, minimizes errors, and accelerates time-to-value. When a developer opens a new feature branch and runs make deploy, the system should: create a staging environment, run tests, promote the build through stages, notify stakeholders, and expose the service at a predictable URL — all with no manual intervention.
To start a new service, a developer runs a single command that bootstraps the full project structure, configures continuous integration, and registers the service in the platform.
$ make new-service
Enter service name: auth-service
Enter service type: microservice
Enter team: identity
Enter environment: staging
Creating service directory: auth-service/
Creating Dockerfile...
Creating go.mod...
Creating Makefile...
Creating .github/workflows/deploy.yml...
Creating config/development.yaml...
Creating config/staging.yaml...
Creating config/prod.yaml...
Registering service with platform API at https://platform.example.com/api/services
The Makefile includes targets for dev, build, test, deploy, and docs. The deploy target runs docker build, pushes to a registry, and calls the platform’s deployment API.
.PHONY: deploy
deploy: build
@echo "Deploying auth-service to staging..."
@curl -X POST https://platform.example.com/api/deployments \
-H "Content-Type: application/json" \
-d '{
"service": "auth-service",
"environment": "staging",
"image": "registry.example.com/auth-service:latest",
"version": "v1.2.0"
}'
The service is now discoverable via the developer portal. The Makefile is checked into the repository, and the deploy command is the canonical path from code to production.
When a developer pushes a feature branch, the platform automatically triggers a deployment to a temporary environment.
$ git checkout feature/user-login
$ git commit -m "Add login form and auth middleware"
$ git push origin feature/user-login
The platform listens for git push events and triggers a CI pipeline. The pipeline uses git describe to derive a version and a unique environment name.
git describe --tags --long --dirty
# → v1.2.0-5-ga1b2c3d
# Resulting environment: auth-service-feature-user-login-a1b2c3d
# URL: https://auth-service-feature-user-login-a1b2c3d.example.com
The environment is provisioned via kubectl and helm, with the following values.yaml generated automatically:
# .github/workflows/deploy.yml
env:
SERVICE_NAME: auth-service
ENVIRONMENT: feature-user-login
VERSION: v1.2.0-5-ga1b2c3d
BASE_URL: https://auth-service-feature-user-login-a1b2c3d.example.com
# Kubernetes deployment
image:
repository: registry.example.com/auth-service
tag: v1.2.0-5-ga1b2c3d
service:
type: LoadBalancer
port: 8080
targetPort: 8080
The deployment is tracked in the platform’s deployment registry. Each deployment includes:
deployment_idstart_time and end_timestatus (pending, in-progress, success, failed)log_url pointing to the CI logThe platform sends a notification to the developer via email and Slack:
✅ Deployment succeeded: auth-service (feature-user-login-a1b2c3d)
URL: https://auth-service-feature-user-login-a1b2c3d.example.com
Logs: https://ci.example.com/logs/2024-05-10-12345
Deployed by: git push origin feature/user-login
After validation in a feature environment, a developer promotes the deployment to production using a simple command.
$ make promote-to-prod
Enter deployment ID: 2024-05-10-12345
Enter reason: "User login form ready for review"
Promoting deployment 2024-05-10-12345 to production...
Sending promotion request to https://platform.example.com/api/deployments/2024-05-10-12345/promote
{
"reason": "User login form ready for review",
"promoted_by": "[email protected]",
"target_environment": "prod",
"rollback_on_failure": true
}
The platform applies the promotion asynchronously. The promote endpoint returns a 202 Accepted response with a Location header to the status endpoint.
HTTP/1.1 202 Accepted
Location: https://platform.example.com/api/deployments/2024-05-10-12345/status
Content-Type: application/json
{
"deployment_id": "2024-05-10-12345",
"status": "promoting",
"message": "Promotion started; waiting for rollout",
"progress": 0.2,
"expected_duration": "PT30M"
}
After the promotion, the platform updates the config/prod.yaml file and redeploys the service to production using the same deployment API.
The promotion can fail silently. If the deployment fails, the platform:
status to failedfailure_reason field with a human-readable messageExample failure:
{
"deployment_id": "2024-05-10-12345",
"status": "failed",
"failure_reason": "Database migration failed: Cannot apply migration '0012-add-user-indexes.sql'",
"logs": [
"2024-05-10T14:23:05Z: Starting migration...",
"2024-05-10T14:23:12Z: Running query: ALTER TABLE users ADD INDEX idx_email (email)",
"2024-05-10T14:23:15Z: ERROR: duplicate key value violates unique constraint \"idx_email\"",
"2024-05-10T14:23:15Z: Detail: Key (email)=([email protected]) already exists."
],
"rollback_requested": true
}
In this case, the platform automatically triggers a rollback, applying the previous version and marking the deployment as failed.
Once deployed, a service is monitored through a set of standardized metrics, logs, and health checks.
The platform exposes a health endpoint at /health, which returns a 200 OK if the service is ready.
GET /health HTTP/1.1
Host: auth-service.example.com
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "healthy",
"checks": {
"database": {
"status": "healthy",
"latency_ms": 12,
"details": "Connected to PostgreSQL 15.2"
},
"cache": {
"status": "healthy",
"latency_ms": 3,
"details": "Redis version 7.0.10, 98% hit rate"
},
"external_api": {
"status": "warning",
"latency_ms": 210,
"details": "External auth service returned 503"
}
},
"uptime_seconds": 47321,
"version": "v1.2.0"
}
The platform collects logs via journalctl and systemctl on each node.
# On each service node, logs are collected via:
$ journalctl -u auth-service --since "2024-05-10T14:00:00Z" --output json
{
"timestamp": "2024-05-10T14:23:05.123Z",
"service": "auth-service",
"level": "INFO",
"message": "User login request received",
"user_id": "u123",
"ip": "192.168.1.100"
}
The platform aggregates logs and provides a search interface with filters for service, level, timestamp, and message. A developer can open the logs for a specific deployment ID:
$ curl "https://logs.example.com/search?deployment_id=2024-05-10-12345&level=ERROR"
The search returns a list of log entries with context, including the deployment_id, service, timestamp, and message.
When a deployment fails, developers must diagnose the issue quickly. The platform provides a structured error format for deployment logs.
A failed deployment includes a failure_trace field that captures the execution flow and error context.
{
"deployment_id": "2024-05-10-12345",
"status": "failed",
"failure_reason": "Migration failed during rollout",
"failure_trace": [
{
"step": "build",
"status": "success",
"duration_ms": 3421,
"log": "Building Go binary..."
},
{
"step": "push_image",
"status": "success",
"duration_ms": 1845,
"log": "Pushed image to registry.example.com/auth-service:v1.2.0-5-ga1b2c3d"
},
{
"step": "apply_manifest",
"status": "failed",
"duration_ms": 12015,
"error": {
"type": "kubectl_apply_failed",
"message": "Error applying manifest: one or more pods failed to start",
"details": [
{
"pod": "auth-service-5f4b7c9d8n",
"status": "Pending",
"reason": "ImagePullBackOff",
"message": "Back-off pulling image \"registry.example.com/auth-service:v1.2.0-5-ga1b2c3d\""
},
{
"pod": "auth-service-5f4b7c9d8n",
"status": "Failed",
"reason": "CrashLoopBackOff",
"message": "Container failed startup: exit code 1"
}
]
}
},
{
"step": "run_migrations",
"status": "failed",
"duration_ms": 8123,
"error": {
"type": "db_migration",
"message": "Migration failed: Cannot apply migration '0012-add-user-indexes.sql'",
"details": [
"ERROR: duplicate key value violates unique constraint \"idx_email\"",
"DETAIL: Key (email)=([email protected]) already exists."
]
}
}
]
}
The failure_trace reveals that the deployment failed because the new image could not be pulled (ImagePullBackOff), and the application crashed on startup (CrashLoopBackOff). The database migration failed due to a duplicate key, which is likely caused by a data inconsistency.
Developers can now:
psql and the migrations directoryDockerfile for issues in the build processdeployment.yaml file for kubernetes configuration errorskubectl describe pod to see the full pod stateSeveral subtle issues often go unnoticed:
config/production.yaml: The platform assumes a file at config/prod.yaml, but developers sometimes forget to commit it. The service starts but uses config/staging.yaml in production, leading to unexpected behavior.version in Makefile: The deploy command relies on git describe to set the version, but if git describe is not run before make deploy, the version is stale.rollback_on_failure flag is set. A deployment can fail silently without rollback if the flag is omitted./health to return within 500ms, but a service with a slow database connection may return 504 Gateway Timeout if the database is slow.config/*.yaml, then from ENVIRONMENT variables, then from deployment metadata. Confusion arises when DATABASE_URL is set in staging.yaml but overridden by DATABASE_URL in prod.yaml, which is overwritten by a DATABASE_URL set in the deployment manifest.These patterns are not documented in a single place. The golden path is the central, shared understanding of how to work with the platform — a living guide that evolves as teams adopt it.
This page was rewritten on 18 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy