Platform Onboarding

Effective platform onboarding accelerates new team adoption and ensures consistent platform usage. A well-designed onboarding process reduces friction, builds confidence, and establishes best practices from the start.

Understanding Platform Onboarding

Platform onboarding guides teams from first contact to productive platform usage.

The Onboarding Challenge

New teams face multiple barriers:

Without Structured Onboarding: ├── Unclear where to start ├── Missing access credentials ├── Unknown platform capabilities ├── No learning path ├── Inconsistent adoption ├── Repeated basic questions ├── Shadow IT alternatives └── Poor platform utilization

Result: Teams abandon the platform or use it incorrectly.

Structured Onboarding Benefits

Systematic approach accelerates adoption:

graph LR A[New Team] --> B[Onboarding Process] B --> C[Access Provisioned] B --> D[Training Completed] B --> E[First Service Deployed] B --> F[Best Practices Learned] C --> G[Productive Platform User] D --> G E --> G F --> G style B fill:#e1f5ff style G fill:#d4f1d4

Onboarding Stages

Effective onboarding follows a structured progression.

Stage 1: Initial Contact

First interaction with the platform team:

# onboarding-request.yaml apiVersion: platform.example.com/v1 kind: OnboardingRequest metadata: id: req-20240815-001 submitted: 2024-08-15T10:00:00Z spec: team: name: payments-team size: 8 manager: alice@example.com tech_lead: bob@example.com requirements: services: 3 databases: 2 environments: 3 estimated_traffic: medium timeline: desired_start: 2024-09-01 production_target: 2024-10-01 experience_level: kubernetes: intermediate cicd: beginner cloud: intermediate

Automated response workflow:

# Onboarding request handler from dataclasses import dataclass from datetime import datetime, timedelta from enum import Enum class OnboardingStage(Enum): REQUESTED = "requested" SCHEDULED = "scheduled" IN_PROGRESS = "in_progress" COMPLETED = "completed" @dataclass class OnboardingSession: team_name: str tech_lead: str scheduled_date: datetime duration_hours: int stage: OnboardingStage class OnboardingOrchestrator: def __init__(self): self.sessions = {} def process_request(self, request: dict) -> OnboardingSession: """Process new onboarding request""" # Create team workspace self.create_team_workspace(request['team']['name']) # Provision initial access self.provision_access(request['team']) # Schedule onboarding session session = self.schedule_session(request) # Send welcome email self.send_welcome_email(request['team'], session) # Create onboarding checklist self.create_checklist(request['team']['name']) return session def create_team_workspace(self, team_name: str): """Create dedicated team workspace""" return { 'github_org': f"example-org/{team_name}", 'kubernetes_namespace': f"{team_name}-dev", 'portal_access': f"https://portal.example.com/teams/{team_name}", 'documentation': f"https://docs.example.com/teams/{team_name}" } def provision_access(self, team: dict): """Provision initial access credentials""" members = [team['manager'], team['tech_lead']] for member in members: # Create platform account self.create_platform_account(member) # Add to team groups self.add_to_groups(member, team['name']) # Send credentials self.send_credentials(member) def schedule_session(self, request: dict) -> OnboardingSession: """Schedule onboarding session""" desired_date = datetime.fromisoformat( request['timeline']['desired_start'] ) # Find available slot session_date = self.find_available_slot(desired_date) session = OnboardingSession( team_name=request['team']['name'], tech_lead=request['team']['tech_lead'], scheduled_date=session_date, duration_hours=4, stage=OnboardingStage.SCHEDULED ) self.sessions[request['team']['name']] = session return session

Stage 2: Guided Training

Hands-on workshop with platform capabilities:

Onboarding Workshop Agenda (4 hours): Hour 1: Platform Overview ├── Platform architecture ├── Available services ├── Self-service capabilities ├── Support channels └── Q&A Hour 2: First Service Deployment ├── Choose service template ├── Configure with team specifics ├── Deploy to dev environment ├── Verify deployment └── Access logs and metrics Hour 3: CI/CD Pipeline ├── Understand pipeline stages ├── Add automated tests ├── Deploy to staging ├── Approval workflow └── Production deployment Hour 4: Operations & Monitoring ├── View service dashboards ├── Set up alerts ├── Access logs ├── Incident response basics └── Getting help

Interactive exercises:

# Exercise 1: Deploy first service platform create service \ --name hello-world \ --template python-web-service \ --team payments-team # Exercise 2: View deployment status platform status hello-world # Exercise 3: Check logs platform logs hello-world --follow # Exercise 4: Scale service platform scale hello-world --replicas 3 # Exercise 5: Create database platform create database \ --name hello-db \ --type postgres \ --service hello-world

Stage 3: First Production Deployment

Guided production deployment with checklist:

# Production Readiness Checklist ## Code Quality - [ ] Unit tests written (>80% coverage) - [ ] Integration tests written - [ ] Code review completed - [ ] Security scan passed - [ ] Dependencies up to date ## Infrastructure - [ ] Resource limits defined - [ ] Autoscaling configured - [ ] Database backups enabled - [ ] Disaster recovery plan documented ## Observability - [ ] Health checks implemented - [ ] Metrics exposed - [ ] Logging configured - [ ] Distributed tracing enabled - [ ] Dashboards created - [ ] Alerts configured ## Security - [ ] Secrets management configured - [ ] TLS certificates provisioned - [ ] Network policies applied - [ ] Authentication configured - [ ] Authorization rules defined ## Documentation - [ ] README updated - [ ] API documentation generated - [ ] Runbook created - [ ] Architecture diagram added - [ ] Service registered in catalog ## Operations - [ ] On-call rotation defined - [ ] Incident response plan documented - [ ] Rollback procedure tested - [ ] Load testing completed - [ ] Capacity planning done

Automated validation:

// Production readiness validator package platform import "fmt" type ReadinessCheck struct { Name string Category string Check func(service Service) (bool, string) Required bool } var productionChecks = []ReadinessCheck{ { Name: "health-endpoints", Category: "Observability", Required: true, Check: func(s Service) (bool, string) { if s.HasEndpoint("/health/live") && s.HasEndpoint("/health/ready") { return true, "Health endpoints configured" } return false, "Missing /health/live or /health/ready endpoint" }, }, { Name: "metrics-endpoint", Category: "Observability", Required: true, Check: func(s Service) (bool, string) { if s.HasEndpoint("/metrics") { return true, "Metrics endpoint configured" } return false, "Missing /metrics endpoint" }, }, { Name: "resource-limits", Category: "Infrastructure", Required: true, Check: func(s Service) (bool, string) { if s.HasResourceLimits() { return true, "Resource limits configured" } return false, "Missing CPU/memory limits" }, }, { Name: "test-coverage", Category: "Code Quality", Required: true, Check: func(s Service) (bool, string) { coverage := s.GetTestCoverage() if coverage >= 80.0 { return true, fmt.Sprintf("Test coverage: %.1f%%", coverage) } return false, fmt.Sprintf("Test coverage too low: %.1f%% (required: 80%%)", coverage) }, }, { Name: "backup-enabled", Category: "Infrastructure", Required: true, Check: func(s Service) (bool, string) { if s.HasDatabase() && s.Database.BackupsEnabled { return true, "Database backups enabled" } if !s.HasDatabase() { return true, "No database required" } return false, "Database backups not enabled" }, }, } func ValidateProductionReadiness(service Service) ReadinessReport { report := ReadinessReport{ Service: service.Name, Ready: true, Checks: make([]CheckResult, 0), } for _, check := range productionChecks { passed, message := check.Check(service) result := CheckResult{ Name: check.Name, Category: check.Category, Passed: passed, Message: message, Required: check.Required, } report.Checks = append(report.Checks, result) if check.Required && !passed { report.Ready = false } } return report }

Onboarding Automation

Automate repetitive onboarding tasks to scale efficiently.

Self-Service Onboarding Portal

Web interface for onboarding initiation:

// Onboarding portal component interface OnboardingForm { teamName: string; teamSize: number; techLead: string; estimatedServices: number; targetDate: Date; } interface OnboardingProgress { stage: string; completedSteps: string[]; nextSteps: string[]; blockers: string[]; } class OnboardingPortal { async submitRequest(form: OnboardingForm): Promise<string> { // Validate form const validation = this.validateForm(form); if (!validation.valid) { throw new Error(validation.errors.join(', ')); } // Create onboarding request const request = await fetch('/api/v1/onboarding', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(form) }); const { requestId } = await request.json(); // Trigger automated provisioning await this.triggerProvisioning(requestId); // Schedule onboarding session await this.scheduleSession(requestId, form.targetDate); // Send notifications await this.notifyStakeholders(requestId, form); return requestId; } async getProgress(requestId: string): Promise<OnboardingProgress> { const response = await fetch(`/api/v1/onboarding/${requestId}`); return response.json(); } async triggerProvisioning(requestId: string): Promise<void> { // Provision team resources automatically await Promise.all([ this.provisionGitHubOrg(requestId), this.provisionKubernetesNamespace(requestId), this.provisionPortalAccess(requestId), this.createDocumentationSpace(requestId) ]); } }

Interactive Tutorials

Guided walkthroughs integrated into portal:

# tutorial-first-deployment.yaml apiVersion: platform.example.com/v1 kind: Tutorial metadata: name: first-deployment title: Deploy Your First Service duration: 15 minutes spec: prerequisites: - Platform account created - CLI installed - Authentication configured steps: - id: choose-template title: Choose a Service Template instruction: | Select a template that matches your service type. For this tutorial, we'll use the Python web service template. command: platform templates list validation: type: user_selection expected: python-web-service - id: create-service title: Create Service instruction: | Create a new service using the template. Replace 'my-service' with your service name. command: | platform create service \ --name my-service \ --template python-web-service \ --team {team_name} validation: type: command_success verify: platform status my-service - id: deploy-dev title: Deploy to Development instruction: | Deploy the service to the development environment. This will trigger the CI/CD pipeline. command: | cd my-service git add . git commit -m "Initial commit" git push origin main validation: type: deployment_success environment: development timeout: 5m - id: verify-deployment title: Verify Deployment instruction: | Check that your service is running correctly. The health check should return a 200 status. command: platform logs my-service --tail 50 expected_output: contains: "application_started" validation: type: health_check endpoint: https://my-service.dev.example.com/health - id: view-metrics title: View Metrics instruction: | Open the monitoring dashboard to see your service metrics. action: type: open_url url: https://portal.example.com/services/my-service/metrics validation: type: user_confirmation completion: message: | Congratulations! You've deployed your first service to the platform. Next steps: - Add custom business logic - Write tests - Deploy to staging - Configure monitoring alerts next_tutorials: - adding-tests - staging-deployment - production-readiness

Onboarding Metrics

Measure onboarding effectiveness to identify improvements.

Key Metrics

Track onboarding success:

# Onboarding metrics from dataclasses import dataclass from datetime import datetime, timedelta @dataclass class OnboardingMetrics: team_name: str start_date: datetime first_deployment_date: datetime production_date: datetime training_completed: bool satisfaction_score: float support_tickets: int def calculate_onboarding_kpis(metrics: list[OnboardingMetrics]) -> dict: """Calculate onboarding KPIs""" total_teams = len(metrics) # Time to first deployment time_to_deploy = [ (m.first_deployment_date - m.start_date).days for m in metrics if m.first_deployment_date ] avg_time_to_deploy = sum(time_to_deploy) / len(time_to_deploy) # Time to production time_to_prod = [ (m.production_date - m.start_date).days for m in metrics if m.production_date ] avg_time_to_prod = sum(time_to_prod) / len(time_to_prod) # Training completion rate training_rate = sum(1 for m in metrics if m.training_completed) / total_teams # Average satisfaction avg_satisfaction = sum(m.satisfaction_score for m in metrics) / total_teams # Support burden avg_support_tickets = sum(m.support_tickets for m in metrics) / total_teams return { 'total_teams_onboarded': total_teams, 'avg_days_to_first_deployment': avg_time_to_deploy, 'avg_days_to_production': avg_time_to_prod, 'training_completion_rate': f"{training_rate * 100:.1f}%", 'avg_satisfaction_score': f"{avg_satisfaction:.1f}/5.0", 'avg_support_tickets_per_team': avg_support_tickets }

Onboarding funnel analysis:

graph TD A[100 Teams Requested] --> B[95 Teams Scheduled] B --> C[90 Teams Trained] C --> D[85 Teams First Deploy] D --> E[75 Teams in Production] A --> F[5 Teams Cancelled] B --> G[5 Teams No-Show] C --> H[5 Teams Abandoned] D --> I[10 Teams Blocked] style E fill:#d4f1d4 style F fill:#ffcccc style G fill:#ffcccc style H fill:#ffcccc style I fill:#fff4cc

Continuous Onboarding Support

Onboarding extends beyond initial training.

Office Hours

Regular support sessions:

Weekly Platform Office Hours: ├── When: Tuesdays & Thursdays, 2-4 PM ├── Format: Drop-in video call ├── Staffing: 2 platform engineers ├── Topics: │ ├── Troubleshooting │ ├── Best practices │ ├── Feature demos │ └── Feedback collection └── Recording: Published for async viewing

Graduated Support Model

Support intensity decreases over time:

gantt title Support Intensity Over Time dateFormat YYYY-MM-DD section Week 1-2 Daily check-ins :2024-09-01, 14d section Week 3-4 3x per week check-ins :2024-09-15, 14d section Week 5-8 Weekly check-ins :2024-09-29, 28d section Week 9+ As-needed support :2024-10-27, 60d

Key Takeaways