multi-user access: fix template memory default, add storage quota, add CONTRIBUTING.md [ci skip]
- Template: bump default memory from 128Mi to 256Mi (matches deploy-app skill guidance) - ResourceQuota: add requests.storage (20Gi) and persistentvolumeclaims (5) defaults - CONTRIBUTING.md: agent-friendly contributor guide for namespace-owners
This commit is contained in:
parent
8dccf4f5ef
commit
b3c9c45a17
3 changed files with 139 additions and 10 deletions
125
CONTRIBUTING.md
Normal file
125
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
# Contributing to the Infrastructure Repo
|
||||
|
||||
This guide covers the namespace-owner workflow for deploying apps on the cluster. For admin operations, see `AGENTS.md`.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. You are listed in `k8s_users` (Vault KV `secret/platform`) with `role: "namespace-owner"`
|
||||
2. Your namespace exists (auto-created by the vault stack)
|
||||
3. You have Vault CLI access: `vault login -method=oidc`
|
||||
4. You have cluster access: `kubectl get namespaces` (uses OIDC via kubelogin)
|
||||
|
||||
## Deploy Your App (5 Steps)
|
||||
|
||||
### 1. Copy the Template
|
||||
|
||||
```bash
|
||||
cp -r stacks/_template stacks/myapp
|
||||
mv stacks/myapp/main.tf.example stacks/myapp/main.tf
|
||||
```
|
||||
|
||||
### 2. Customize `main.tf`
|
||||
|
||||
Replace all `<placeholders>`:
|
||||
|
||||
| Placeholder | Example |
|
||||
|-------------|---------|
|
||||
| `<your-namespace>` | `anca` |
|
||||
| `<app-name>` | `my-webapp` |
|
||||
| `<dockerhub-user>/<app-name>:<tag>` | `jdoe/my-webapp:abc12345` |
|
||||
|
||||
Set resources explicitly on every container:
|
||||
|
||||
```hcl
|
||||
resources {
|
||||
requests = { cpu = "10m", memory = "256Mi" }
|
||||
limits = { memory = "256Mi" }
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Store Secrets in Vault
|
||||
|
||||
```bash
|
||||
vault login -method=oidc
|
||||
vault kv put secret/<your-username>/myapp DB_PASSWORD=xxx API_KEY=yyy
|
||||
```
|
||||
|
||||
Your Vault path is `secret/<your-username>/*` — full CRUD access there only.
|
||||
|
||||
### 4. Submit a PR
|
||||
|
||||
```bash
|
||||
git checkout -b feat/myapp
|
||||
git add stacks/myapp/
|
||||
git commit -m "add myapp stack"
|
||||
git push -u origin feat/myapp
|
||||
```
|
||||
|
||||
Open a PR. Admin reviews and runs `terragrunt apply`.
|
||||
|
||||
### 5. Set Up CI/CD (Optional)
|
||||
|
||||
For automated deploys on push, create `.woodpecker/deploy.yml` in your app repo:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- name: deploy
|
||||
image: bitnami/kubectl:latest
|
||||
commands:
|
||||
- kubectl set image deployment/<app-name> <app-name>=<image>:${CI_COMMIT_SHA:0:8} -n <namespace>
|
||||
```
|
||||
|
||||
## Resource Constraints
|
||||
|
||||
Your namespace has hard limits enforced by ResourceQuota:
|
||||
|
||||
| Resource | Default |
|
||||
|----------|---------|
|
||||
| CPU requests | 2 cores |
|
||||
| Memory requests | 4Gi |
|
||||
| Memory limits | 8Gi |
|
||||
| Pods | 20 |
|
||||
| Storage | 20Gi |
|
||||
| PVCs | 5 |
|
||||
|
||||
- Pods run at **tier-4-aux** priority — they never preempt platform services.
|
||||
- Kyverno injects default limits (256Mi) for containers without explicit resources.
|
||||
- Always set explicit `resources {}` to avoid surprises.
|
||||
|
||||
## Vault Secret Paths
|
||||
|
||||
| Path | Access |
|
||||
|------|--------|
|
||||
| `secret/<your-username>/*` | Full CRUD (your secrets) |
|
||||
| `kubernetes/creds/<namespace>-deployer` | Read (dynamic K8s deploy tokens) |
|
||||
| `transit/encrypt/sops-state-<namespace>` | Encrypt (state encryption) |
|
||||
| `transit/decrypt/sops-state-<namespace>` | Decrypt (state encryption) |
|
||||
|
||||
## What NOT to Do
|
||||
|
||||
- **No kubectl mutations**: Never `kubectl apply/edit/patch/delete` for persistent changes. Read-only kubectl is fine for debugging.
|
||||
- **No secrets in code**: Use Vault KV or Sealed Secrets. Never commit plaintext secrets.
|
||||
- **No `:latest` tags**: The pull-through cache serves stale `:latest` manifests. Use 8-char git SHA tags (e.g., `abc12345`).
|
||||
- **No resources outside your namespace**: RBAC prevents it. Don't try.
|
||||
- **No `terragrunt apply`**: Admin-only. Submit a PR instead.
|
||||
- **No unbounded resource specs**: Always set `resources {}` with explicit CPU/memory.
|
||||
|
||||
## AI Agent Instructions
|
||||
|
||||
If you're an AI agent helping a namespace-owner:
|
||||
|
||||
1. Read this file and `AGENTS.md` before making changes
|
||||
2. Check `stacks/_template/` for the canonical starting point
|
||||
3. Always set explicit `resources {}` (256Mi memory minimum)
|
||||
4. Store secrets at `secret/<username>/<app>` in Vault
|
||||
5. Never run `terragrunt apply` — create a PR for admin review
|
||||
6. Use versioned image tags, never `:latest`
|
||||
7. Interactive setup: `curl -fsSL https://k8s-portal.viktorbarzin.me/setup/script?os=mac`
|
||||
8. Agent bootstrap doc: `curl -fsSL https://k8s-portal.viktorbarzin.me/agent`
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Onboarding guide](https://k8s-portal.viktorbarzin.me/onboarding)
|
||||
- [Agent bootstrap doc](https://k8s-portal.viktorbarzin.me/agent)
|
||||
- Template: `stacks/_template/main.tf.example`
|
||||
- Full agent instructions: `AGENTS.md`
|
||||
|
|
@ -55,8 +55,8 @@ resource "kubernetes_deployment" "app" {
|
|||
container_port = 8080 # Change to your app's port
|
||||
}
|
||||
resources {
|
||||
requests = { cpu = "10m", memory = "128Mi" }
|
||||
limits = { memory = "128Mi" }
|
||||
requests = { cpu = "10m", memory = "256Mi" }
|
||||
limits = { memory = "256Mi" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ variable "k8s_users" {
|
|||
namespaces = optional(list(string), []) # for namespace-owners
|
||||
domains = optional(list(string), []) # subdomains for user apps
|
||||
quota = optional(object({
|
||||
cpu_requests = optional(string, "2")
|
||||
memory_requests = optional(string, "4Gi")
|
||||
memory_limits = optional(string, "8Gi")
|
||||
pods = optional(string, "20")
|
||||
cpu_requests = optional(string, "2")
|
||||
memory_requests = optional(string, "4Gi")
|
||||
memory_limits = optional(string, "8Gi")
|
||||
pods = optional(string, "20")
|
||||
storage_requests = optional(string, "20Gi")
|
||||
persistentvolumeclaims = optional(string, "5")
|
||||
}), {})
|
||||
}))
|
||||
default = {}
|
||||
|
|
@ -223,10 +225,12 @@ resource "kubernetes_resource_quota" "user_namespace_quota" {
|
|||
|
||||
spec {
|
||||
hard = {
|
||||
"requests.cpu" = each.value.quota.cpu_requests
|
||||
"requests.memory" = each.value.quota.memory_requests
|
||||
"limits.memory" = each.value.quota.memory_limits
|
||||
"pods" = each.value.quota.pods
|
||||
"requests.cpu" = each.value.quota.cpu_requests
|
||||
"requests.memory" = each.value.quota.memory_requests
|
||||
"limits.memory" = each.value.quota.memory_limits
|
||||
"pods" = each.value.quota.pods
|
||||
"requests.storage" = each.value.quota.storage_requests
|
||||
"persistentvolumeclaims" = each.value.quota.persistentvolumeclaims
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue