Platform Engineering Fundamentals · Module 05 of 12

Self-service environments and provisioning

Expose infrastructure and environment capabilities through bounded self-service contracts with quotas, ownership, TTLs, idempotency and cleanup instead of handing every developer raw administrative access.

Learning objectives

By the end of this module, you should be able to:

  • Design a bounded environment request with policy and lifecycle fields.
  • Explain why idempotency, TTL and cleanup matter for self-service.
  • Separate developer intent from provider-specific implementation details.
Dependency note

Design now; implement the primitives later.

This module specifies the self-service provisioning contract. Modules 06–08 later show how Kubernetes, GitOps and policy can realize that contract. The ordering is deliberate: product boundary first, implementation second.

Self-service is not unrestricted access

A platform should expose a safe capability boundary: allowed sizes, environments, regions, ownership and policy. The consumer expresses intent; the platform enforces organizational constraints.

Lifecycle must be automatic

Disposable environments need TTL/cleanup. Long-lived resources need ownership, update and decommission paths. Without lifecycle automation, self-service creates faster sprawl.

Idempotency protects retries

Provisioning may be retried because clients disconnect or workflows restart. Repeating the same request should converge on the intended state rather than duplicate resources.

Forward dependency: provisioning is an interface, not a tool choice

A platform may implement the same environment request with Terraform/OpenTofu, Kubernetes controllers, cloud APIs or another orchestrator. The learner first defines lifecycle, quota, ownership and failure semantics; later modules map those semantics to concrete runtime and delivery mechanisms.

Worked example

Environment request

{"service":"orders","environment":"preview","size":"small","ttl_hours":8,"owner":"payments"}
  • The request expresses developer intent while the platform decides implementation.
  • Validation should reject unsupported sizes, missing ownership and excessive TTLs before provisioning.
Core lab · account-free

Lab 05 — Enforce a bounded environment request

Goal: Validate policy and lifecycle fields for a self-service preview environment.

Before you start

  • No cloud account required.
  • Core lab uses bash/Python 3 and local files only.
STEP 1

Create requests

cat > /tmp/env-request.json <<'EOF'
{"service":"orders","environment":"preview","size":"small","ttl_hours":8,"owner":"payments"}
EOF
STEP 2

Apply policy

python3 - <<'PY2'
import json,re
x=json.load(open('/tmp/env-request.json'))
assert re.fullmatch(r'[a-z][a-z0-9-]{1,30}',x['service'])
assert x['environment'] in {'preview','test'}
assert x['size'] in {'small','medium'}
assert 1 <= x['ttl_hours'] <= 24
assert x['owner']
print('request accepted')
PY2
STEP 3

Define idempotency key

Use service + environment + request identity to explain how a retried request avoids duplicate environments.

Verify

  • The valid request is accepted.
  • The policy has explicit allowed values and TTL.

Expected outcome

  • A bounded request contract suitable for portal/CLI/API use.

Diagnose / troubleshoot

  • If every implementation parameter is exposed, redesign around developer intent.
  • If cleanup requires a manual ticket, the lifecycle is not truly self-service.
Real-world connection

Self-service provisioning should accelerate developers while making ownership, policy and cleanup more consistent.

Real-tool practicum · optional but recommended

Optional tool lab — Terraform/OpenTofu module interface

Review a module input contract as one possible implementation behind the platform API.

Prerequisites

  • Use a disposable local lab or organization-approved sandbox.
  • Pin tool versions in real platform automation; do not blindly depend on latest.

Cost / risk

  • Core learning is account-free. Optional external/sandbox tools may consume local CPU/RAM; do not use production credentials or billable cloud resources.

Warnings

  • Do not point training automation at production clusters, repositories or cloud accounts.
  • A successful command is not proof of a good platform interface; validate the developer outcome and guardrails.
TOOL 1
printf '%s
' 'variable "service" { type = string }' 'variable "ttl_hours" { type = number }' > /tmp/platform-module.tf
cat /tmp/platform-module.tf
Avoid these traps

Common mistakes

  • Giving portal users raw cluster-admin/cloud-admin credentials.
  • Creating preview environments with no TTL or owner.
  • Exposing provider internals as the platform’s permanent public API.
Knowledge check

Can you connect the developer need to a platform contract?

Three concept checks plus one scenario check.

1What makes self-service safe?

Bounded inputs, policy, identity, ownership, observable status and lifecycle controls.

2Why are TTLs useful for preview environments?

They automate cleanup and reduce resource/cost sprawl.

3What is idempotent provisioning?

Repeating the same request converges on the same intended state instead of creating duplicates.

4Scenario: a portal lets any developer request “admin=true” for a cluster. What is wrong?

The interface exposes unrestricted privilege rather than a bounded capability with policy and least privilege.

My Learning

Record your progress for this module.

Progress is saved in this browser immediately. When you sign in to My Learning, it can also sync across devices.

Not started

Attempt the core lab and knowledge checks before marking the module complete.