Skip to main content
DevOps Culture·8 min read

DevOps Onboarding — Get a New Engineer Production-Ready on Day 1

Get new engineers production-ready on day one with standardized dev environments, Devcontainers, automated setup scripts, golden path templates, internal documentation, and access provisioning automation.

DT

DevOps Engineer & Technical Writer

TL;DR — Quick Fix

Get a new engineer running code in under 30 minutes with a Devcontainer:

{

"name": "Platform Dev Environment",

"image": "ghcr.io/my-org/devcontainer:latest",

"features": {

"ghcr.io/devcontainers/features/aws-cli:1": {},

"ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {},

"ghcr.io/devcontainers/features/terraform:1": {},

"ghcr.io/devcontainers/features/docker-in-docker:2": {}

},

"postCreateCommand": "./scripts/setup-dev.sh",

"forwardPorts": [3000, 5432, 6379],

"customizations": {

"vscode": {

"extensions": [

"ms-kubernetes-tools.vscode-kubernetes-tools",

"hashicorp.terraform",

"redhat.vscode-yaml"

]

}

}

}

#!/bin/bash

# scripts/setup-dev.sh — runs automatically on container creation

set -euo pipefail

echo "Setting up development environment..."

npm ci

docker compose up -d postgres redis

sleep 5

npm run db:migrate

npm run db:seed

npm run test:smoke

echo "Setup complete. Run 'npm run dev' to start."

---

Architecture — Developer Onboarding Pipeline

DEVELOPER ONBOARDING PIPELINE — DAY 1 TO PRODUCTION-READY 0-30 min Access Provisioned GitHub, AWS, Slack automated via IDP 30-60 min Dev Env Running Devcontainer opens all tools pre-installed 1-2 hours First PR Merged Golden path template guided tutorial 2-4 hours Production Deploy Deployed to staging then production Devcontainers Reproducible environment All tools pre-configured Works locally + Codespaces Golden Path Templates Cookiecutter / Backstage CI/CD pre-configured Observability built in Internal Dev Portal Service catalog Runbooks + architecture API documentation Access Automation SCIM provisioning Role-based groups Auto-revoke on offboard TARGET: First production deploy in under 4 hours Industry average: 2-4 weeks | Top companies: same day

---

Step 1 — Standardized Dev Environments

{

"name": "Backend Service",

"build": {

"dockerfile": "Dockerfile.dev",

"context": ".."

},

"features": {

"ghcr.io/devcontainers/features/node:1": { "version": "20" },

"ghcr.io/devcontainers/features/aws-cli:1": {},

"ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {},

"ghcr.io/devcontainers/features/terraform:1": { "version": "1.7" },

"ghcr.io/devcontainers/features/github-cli:1": {}

},

"postCreateCommand": "make setup",

"postStartCommand": "make dev-services",

"forwardPorts": [3000, 5432, 6379, 8080],

"remoteEnv": {

"APP_ENV": "development",

"DATABASE_URL": "postgres://dev:dev@localhost:5432/app_dev"

}

}

Option B: Nix Flakes

{

inputs = {

nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

flake-utils.url = "github:numtide/flake-utils";

};

outputs = { self, nixpkgs, flake-utils }:

flake-utils.lib.eachDefaultSystem (system:

let pkgs = nixpkgs.legacyPackages.${system};

in {

devShells.default = pkgs.mkShell {

buildInputs = with pkgs; [

nodejs_20 go_1_22 python312

terraform kubectl helm awscli2

docker-compose jq yq

];

shellHook = ''

echo "Dev environment ready."

export KUBECONFIG=$PWD/.kube/config

'';

};

});

}

---

Step 2 — Automated Setup Scripts

# Makefile targets for onboarding

.PHONY: setup dev-services seed test-smoke

setup: ## First-time setup for new engineers

@echo "Installing dependencies..."

npm ci

@echo "Copying environment template..."

cp .env.example .env.local

@echo "Starting infrastructure..."

$(MAKE) dev-services

@echo "Running database migrations..."

npm run db:migrate

@echo "Seeding development data..."

npm run db:seed

@echo "Verifying setup..."

$(MAKE) test-smoke

@echo "Setup complete! Run 'make dev' to start."

dev-services: ## Start local infrastructure

docker compose up -d postgres redis localstack

@echo "Waiting for services..."

docker compose exec postgres pg_isready -U dev

seed: ## Seed database with test data

npm run db:seed -- --profile=development

test-smoke: ## Quick smoke test

npm run test:smoke

@echo "All smoke tests passed!"

---

Step 3 — Golden Path Templates

# backstage-template.yaml — New service template

apiVersion: scaffolder.backstage.io/v1beta3

kind: Template

metadata:

name: microservice-template

title: Create a New Microservice

description: Production-ready microservice with CI/CD and monitoring

spec:

owner: platform-team

type: service

parameters:

- title: Service Details

required: [name, team, language]

properties:

name:

title: Service Name

type: string

pattern: "^[a-z][a-z0-9-]*$"

team:

title: Owning Team

type: string

enum: [payments, orders, platform, data]

language:

title: Language

type: string

enum: [typescript, go, python]

steps:

- id: fetch-template

name: Fetch Template

action: fetch:template

input:

url: ./skeleton/${{ parameters.language }}

values:

name: ${{ parameters.name }}

team: ${{ parameters.team }}

- id: create-repo

name: Create GitHub Repo

action: publish:github

input:

repoUrl: github.com?owner=my-org&repo=${{ parameters.name }}

defaultBranch: main

- id: register-catalog

name: Register in Backstage

action: catalog:register

input:

repoContentsUrl: ${{ steps['create-repo'].output.repoContentsUrl }}

catalogInfoPath: /catalog-info.yaml

---

Step 4 — Access Provisioning Automation

# terraform/modules/engineer-access/main.tf

variable "engineer" {

type = object({

email = string

team = string

role = string

})

}

resource "github_team_membership" "engineer" {

team_id = data.github_team.team[var.engineer.team].id

username = split("@", var.engineer.email)[0]

role = var.engineer.role == "lead" ? "maintainer" : "member"

}

resource "aws_ssoadmin_account_assignment" "engineer" {

instance_arn = data.aws_ssoadmin_instances.main.arns[0]

permission_set_arn = local.permission_sets[var.engineer.role]

principal_id = aws_identitystore_user.engineer.user_id

principal_type = "USER"

target_id = local.account_ids[var.engineer.team]

target_type = "AWS_ACCOUNT"

}

---

Step 5 — Onboarding Checklist

## Day 1 Onboarding Checklist

Automated (completes in < 30 min)

  • [ ] GitHub org access granted
  • [ ] AWS SSO account created
  • [ ] Slack channels joined
  • [ ] PagerDuty account created (shadow rotation first)
  • [ ] 1Password vault access
  • [ ] VPN credentials provisioned

Self-Service (guided, < 2 hours)

  • [ ] Clone main repository
  • [ ] Open in Devcontainer (or run nix develop)
  • [ ] Run make setup — verify all tests pass
  • [ ] Complete Hello World tutorial (first PR)
  • [ ] Deploy to staging environment
  • [ ] Read architecture overview in dev portal

First Week Goals

  • [ ] Complete one real ticket (pair with buddy)
  • [ ] Shadow on-call rotation
  • [ ] Read post-mortem from last month
  • [ ] Add yourself to team service ownership
  • [ ] Attend team standup and retro

---

Frequently Asked Questions

How long should onboarding take for a senior engineer?

Target is first production deploy within 4 hours, first real feature shipped within the first week. Senior engineers should be fully autonomous by week 2. If onboarding takes longer than a day for basic setup, your developer experience needs improvement.

Devcontainers vs Nix — which should we use?

Devcontainers for teams using VS Code or GitHub Codespaces where the primary language is JavaScript/TypeScript or Python. Nix for multi-language environments or teams with diverse editor preferences. You can combine both — use Nix inside a Devcontainer for maximum reproducibility.

How do we handle secrets in the onboarding flow?

Never put real secrets in setup scripts. Use local-only mock credentials (LocalStack for AWS, Docker Compose for databases), or integrate with a secrets manager that provisions per-developer credentials. Use .env.local files that are gitignored.

Should new engineers get production access on day one?

Read-only production access (logs, metrics, dashboards) on day one is fine and helpful. Write access (deployments, database modifications) should wait until the engineer has merged at least one PR and completed the staging deploy tutorial.

How do we measure onboarding effectiveness?

Track these metrics: (1) Time to first commit, (2) Time to first production deploy, (3) Number of onboarding questions in Slack, (4) New engineer satisfaction survey at 30 days, (5) Time to be added to on-call rotation.

---