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 1Create requests
cat > /tmp/env-request.json <<'EOF'
{"service":"orders","environment":"preview","size":"small","ttl_hours":8,"owner":"payments"}
EOF
STEP 2Apply 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 3Define 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 connectionSelf-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 1printf '%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.