chore: bump almalinux9 image tags (#188)
Bump almalinux9 image tags to 20260606 Reviewed-on: #188 Co-authored-by: Ben Vincent <ben@unkin.net> Co-committed-by: Ben Vincent <ben@unkin.net>
This commit was merged in pull request #188.
This commit is contained in:
@@ -0,0 +1,273 @@
|
|||||||
|
---
|
||||||
|
description: Pull master, read open issues, pick one, branch, implement, test, commit, PR, and comment.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Solve a Gitea Issue
|
||||||
|
|
||||||
|
## Current repo state
|
||||||
|
|
||||||
|
```!
|
||||||
|
git status --short
|
||||||
|
echo "Current branch: $(git branch --show-current)"
|
||||||
|
echo "Remote: $(git remote get-url origin 2>/dev/null || echo 'none')"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Open issues (with full body)
|
||||||
|
|
||||||
|
```!
|
||||||
|
echo "Fetching open issues..."
|
||||||
|
issue_ids=$(tea issues list --output simple 2>/dev/null | awk 'NF && $1 ~ /^[0-9]+$/ {print $1}')
|
||||||
|
if [ -z "$issue_ids" ]; then
|
||||||
|
echo "No open issues found (or tea is not logged in)."
|
||||||
|
else
|
||||||
|
for id in $issue_ids; do
|
||||||
|
echo ""
|
||||||
|
echo "══════════════════════════════════════"
|
||||||
|
tea issues view "$id" --fields index,title,body 2>/dev/null \
|
||||||
|
|| tea issue "$id" 2>/dev/null \
|
||||||
|
|| echo " (could not read issue #$id)"
|
||||||
|
echo "══════════════════════════════════════"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Your task
|
||||||
|
|
||||||
|
Follow these steps **in order**. Do not skip steps.
|
||||||
|
|
||||||
|
### 1 — Choose an issue
|
||||||
|
|
||||||
|
Present the issues above to the user as a numbered list (index, one-line title). Ask which one to work on. Wait for the answer before continuing.
|
||||||
|
|
||||||
|
### 2 — Sync master
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout master
|
||||||
|
git pull
|
||||||
|
```
|
||||||
|
|
||||||
|
Confirm you are on master and up to date.
|
||||||
|
|
||||||
|
### 3 — Create a branch
|
||||||
|
|
||||||
|
Name the branch `benvin/issue-<N>-<short-slug>` where `<short-slug>` is 2–4 kebab-case words from the issue title.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout -b benvin/issue-<N>-<slug>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4 — Read the issue in full
|
||||||
|
|
||||||
|
Re-read the full issue body shown above. If any part is ambiguous, state your interpretation before coding.
|
||||||
|
|
||||||
|
**If you discover other problems while working:** do NOT solve them inline. Create a new Gitea issue with `tea issues create --title "..." --description "..."` and stay focused on the assigned issue.
|
||||||
|
|
||||||
|
### 5 — Implement the solution
|
||||||
|
|
||||||
|
Make the code changes needed to resolve the issue. Follow the conventions already in the repo:
|
||||||
|
- `main.py` route handlers each contain a single function call; logic lives in submodules.
|
||||||
|
- No comments unless the WHY is non-obvious.
|
||||||
|
- No new files unless the issue or architecture requires it.
|
||||||
|
- Security: no command injection, XSS, SQL injection, or secrets in code.
|
||||||
|
- **For performance improvements:** implement at the most generic call site possible so the fix applies to all current and future implementations, not just the one being tested.
|
||||||
|
|
||||||
|
### 6 — Update tests
|
||||||
|
|
||||||
|
Add or update tests that cover the new behaviour. Tests live in `tests/`. Check existing test structure before writing new ones — mirror the style and fixture patterns already in use.
|
||||||
|
|
||||||
|
### 7 — Update README
|
||||||
|
|
||||||
|
If the feature introduces new config keys, endpoints, or user-facing behaviour, document it in `README.md`. Keep additions concise — follow the existing section style.
|
||||||
|
|
||||||
|
### 8 — Run the full test suite
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make test
|
||||||
|
```
|
||||||
|
|
||||||
|
All tests must pass. If any fail, fix them before proceeding. Do not skip or suppress failing tests.
|
||||||
|
|
||||||
|
### 9 — Live Docker test (new package type only)
|
||||||
|
|
||||||
|
**Skip this step if the issue does not add a new remote package type.**
|
||||||
|
|
||||||
|
If the issue adds a new package type (e.g. `deb`, `conda`, `cargo`, `rubygems`, or any type not already in `remotes.yaml`), do the following before committing.
|
||||||
|
|
||||||
|
#### 9a — Add a real test remote to remotes.yaml
|
||||||
|
|
||||||
|
Append a valid, publicly accessible remote of the new type to `remotes.yaml`. Use a real upstream URL and patterns that cover both an immutable file (versioned artifact) and a mutable file (index/metadata). Add a comment explaining which URLs to use for manual testing.
|
||||||
|
|
||||||
|
#### 9b — Start the stack
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make docker-up
|
||||||
|
```
|
||||||
|
|
||||||
|
Wait until `curl -s http://localhost:8000/health` returns `{"status":"healthy"}`.
|
||||||
|
|
||||||
|
#### 9c — Test a mutable file (first fetch — cache miss)
|
||||||
|
|
||||||
|
Download the index or metadata file for the new remote. Confirm:
|
||||||
|
- HTTP 200
|
||||||
|
- `X-Artifact-Source: remote` header (or equivalent log line confirming a cache miss)
|
||||||
|
- Content looks correct (not empty, not an error page)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -sv "http://localhost:8000/api/v1/remote/<new-remote>/<mutable-path>" 2>&1 | grep -E "< HTTP|X-Artifact"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 9d — Test a mutable file (second fetch — cache hit)
|
||||||
|
|
||||||
|
Repeat the exact same request. Confirm:
|
||||||
|
- HTTP 200
|
||||||
|
- `X-Artifact-Source: cache`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -sv "http://localhost:8000/api/v1/remote/<new-remote>/<mutable-path>" 2>&1 | grep -E "< HTTP|X-Artifact"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 9e — Test an immutable file (first fetch — cache miss)
|
||||||
|
|
||||||
|
Download a versioned/immutable artifact. Confirm HTTP 200 and a cache-miss log line.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -sv "http://localhost:8000/api/v1/remote/<new-remote>/<immutable-path>" 2>&1 | grep -E "< HTTP|X-Artifact"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 9f — Test an immutable file (second fetch — cache hit)
|
||||||
|
|
||||||
|
Repeat. Confirm `X-Artifact-Source: cache`.
|
||||||
|
|
||||||
|
#### 9g — Check container logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make docker-logs
|
||||||
|
```
|
||||||
|
|
||||||
|
Scan for:
|
||||||
|
- `Cache MISS` on first fetches, `Cache HIT` on second fetches
|
||||||
|
- `Cache ADD SUCCESS` with correct sizes
|
||||||
|
- No unhandled exceptions or ERROR lines
|
||||||
|
|
||||||
|
#### 9h — Exercise package-type tooling against the proxy
|
||||||
|
|
||||||
|
Use the native tooling for this package type to verify end-to-end behaviour. Examples:
|
||||||
|
|
||||||
|
| Package type | Command |
|
||||||
|
|---|---|
|
||||||
|
| `pypi` | `uv run --index-url http://localhost:8000/api/v1/remote/<remote>/simple <tool>` |
|
||||||
|
| `npm` | `npm install --registry http://localhost:8000/api/v1/remote/<remote>/ <pkg>` |
|
||||||
|
| `helm` | `helm repo add test http://localhost:8000/api/v1/remote/<remote> && helm search repo test && helm template test/<chart>` |
|
||||||
|
| `alpine` | `apk fetch --repository http://localhost:8000/api/v1/remote/<remote>/<branch>/<arch> <pkg>` |
|
||||||
|
| `rpm` | `dnf install --repofrompath ... <pkg>` or `repoquery` |
|
||||||
|
| `generic` | `curl` / `wget` as appropriate |
|
||||||
|
|
||||||
|
Confirm the tool resolves and downloads correctly through the proxy.
|
||||||
|
|
||||||
|
#### 9i — Tear down
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make docker-down
|
||||||
|
```
|
||||||
|
|
||||||
|
Fix any failures found during 9b–9h before moving on.
|
||||||
|
|
||||||
|
### 9.5 — Performance issues: measure before/after and gate the PR
|
||||||
|
|
||||||
|
**Skip this step if the issue is not a performance improvement.**
|
||||||
|
|
||||||
|
For performance issues, a PR is only warranted if there is a measurable gain. Use the Docker stack to compare before and after.
|
||||||
|
|
||||||
|
#### 9.5a — Baseline measurement (before)
|
||||||
|
|
||||||
|
Start the stack with the **unmodified** code (temporarily revert your change):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make docker-up
|
||||||
|
```
|
||||||
|
|
||||||
|
Warm or clear the cache as appropriate, then measure the relevant metric — e.g. concurrent request latency during a slow operation, response time for a specific endpoint, or throughput. Record the numbers.
|
||||||
|
|
||||||
|
#### 9.5b — Apply your change and rebuild
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make docker-up # rebuilds the image
|
||||||
|
```
|
||||||
|
|
||||||
|
Repeat exactly the same measurement. Record the numbers.
|
||||||
|
|
||||||
|
#### 9.5c — Decide
|
||||||
|
|
||||||
|
If the improvement is not clearly measurable, **do not open a PR**. Instead:
|
||||||
|
1. Update the issue with your findings.
|
||||||
|
2. Note any conditions under which the improvement would be observable.
|
||||||
|
3. Skip steps 11–14.
|
||||||
|
|
||||||
|
If the improvement is clear, proceed with the commit and PR. Include the before/after numbers in the PR description and the issue comment.
|
||||||
|
|
||||||
|
#### 9.5d — Tear down
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make docker-down
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10 — Build the wheel (smoke check)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uv build --wheel
|
||||||
|
```
|
||||||
|
|
||||||
|
Confirm the build succeeds.
|
||||||
|
|
||||||
|
### 11 — Stage and commit
|
||||||
|
|
||||||
|
Stage only the files you changed. Do not use `git add -A` or `git add .` — list files explicitly. Run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add <file1> <file2> ...
|
||||||
|
git commit
|
||||||
|
```
|
||||||
|
|
||||||
|
The commit message must:
|
||||||
|
- Start with a conventional-commit prefix (`feat:`, `fix:`, `refactor:`, `chore:`, etc.)
|
||||||
|
- Summarise the change in ≤ 72 characters on the first line
|
||||||
|
- Optionally include a short body explaining *why* (not *what*)
|
||||||
|
|
||||||
|
If the pre-commit hook auto-fixes files, re-stage the fixed files and commit again.
|
||||||
|
|
||||||
|
### 12 — Push the branch
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git push origin <branch-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 13 — Open a pull request
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea pulls create \
|
||||||
|
--base master \
|
||||||
|
--head <branch-name> \
|
||||||
|
--title "<same as commit subject>" \
|
||||||
|
--description "Closes #<N>\n\n## Summary\n<bullet points>\n\n## Test plan\n<what was verified>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 14 — Comment on the issue
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea comment <N> "<resolution comment>"
|
||||||
|
```
|
||||||
|
|
||||||
|
The comment must cover:
|
||||||
|
- **How it was resolved** — what changed and why
|
||||||
|
- **Issues encountered** — any non-obvious problems hit during implementation
|
||||||
|
- **Potential future improvements** — what could be done next
|
||||||
|
|
||||||
|
### 15 — Return to master
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout master
|
||||||
|
```
|
||||||
|
|
||||||
|
Report the PR URL and a one-sentence summary to the user.
|
||||||
@@ -3,7 +3,7 @@ when:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: kubeconform
|
- name: kubeconform
|
||||||
image: git.unkin.net/unkin/almalinux9-kubetest:20260319
|
image: git.unkin.net/unkin/almalinux9-kubetest:20260606
|
||||||
commands:
|
commands:
|
||||||
- make kubeconform
|
- make kubeconform
|
||||||
backend_options:
|
backend_options:
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ when:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: pre-commit
|
- name: pre-commit
|
||||||
image: git.unkin.net/unkin/almalinux9-base:20260308
|
image: git.unkin.net/unkin/almalinux9-base:20260606
|
||||||
commands:
|
commands:
|
||||||
- uvx pre-commit run --all-files
|
- uvx pre-commit run --all-files
|
||||||
backend_options:
|
backend_options:
|
||||||
|
|||||||
@@ -0,0 +1,261 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This is an **ArgoCD GitOps repository** that manages Kubernetes applications for the `au-syd1` cluster using a Kustomize + Helm pattern. Applications are deployed via ArgoCD ApplicationSets that watch directory patterns in this repo.
|
||||||
|
|
||||||
|
The migration pattern for this repo is: **Terragrunt/Terraform → ArgoCD** (see `migration.md` for full guide).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Essential Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build and render manifests for a path (outputs to manifests/<path>/)
|
||||||
|
make build apps/overlays/au-syd1/<app-name>
|
||||||
|
make build clusters/au-syd1/bootstrap
|
||||||
|
|
||||||
|
# Validate all apps and clusters with kubeconform
|
||||||
|
make kubeconform
|
||||||
|
|
||||||
|
# Clean generated manifests
|
||||||
|
make clean
|
||||||
|
|
||||||
|
# Quick build + inspect without persisting output
|
||||||
|
kustomize build --enable-helm apps/overlays/au-syd1/<app-name>
|
||||||
|
|
||||||
|
# Check all resource kinds produced by an overlay
|
||||||
|
kustomize build --enable-helm apps/overlays/au-syd1/<app-name> | grep "^kind:" | sort | uniq -c
|
||||||
|
|
||||||
|
# Run pre-commit checks against all files
|
||||||
|
uvx pre-commit run --all-files
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
argocd-apps/
|
||||||
|
├── argocd/
|
||||||
|
│ ├── applicationsets/ # ArgoCD ApplicationSet definitions (platform.yaml, storage.yaml)
|
||||||
|
│ └── projects/ # ArgoCD AppProject definitions (platform.yaml, storage.yaml)
|
||||||
|
├── apps/
|
||||||
|
│ ├── base/ # Base Kustomize resources per app (no cluster-specific config)
|
||||||
|
│ │ └── <app-name>/
|
||||||
|
│ │ ├── kustomization.yaml
|
||||||
|
│ │ ├── namespace.yaml
|
||||||
|
│ │ ├── vaultauth.yaml # (if Vault-managed secrets)
|
||||||
|
│ │ └── vaultstaticsecret.yaml
|
||||||
|
│ └── overlays/
|
||||||
|
│ └── au-syd1/ # Cluster-specific overlays
|
||||||
|
│ └── <app-name>/
|
||||||
|
│ ├── kustomization.yaml # references base + helmCharts
|
||||||
|
│ └── values.yaml # Helm values for this cluster
|
||||||
|
├── clusters/
|
||||||
|
│ └── au-syd1/
|
||||||
|
│ ├── apps/ # Entry point: references apps/base (ArgoCD app-of-apps)
|
||||||
|
│ └── bootstrap/ # ArgoCD install + initial Application manifest
|
||||||
|
├── ci/
|
||||||
|
│ ├── validate-apps.sh # kubeconform over apps/overlays/*/kustomization.yaml
|
||||||
|
│ ├── validate-clusters.sh # kubeconform over clusters/*/kustomization.yaml
|
||||||
|
│ └── validate-no-secrets.sh # pre-commit hook: blocks plain Kubernetes Secrets
|
||||||
|
└── sources/ # Reference sources (Terraform configs, upstream charts, etc.)
|
||||||
|
└── terraform-k8s/ # Original Terraform configs — reference when migrating
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Adding a New Application
|
||||||
|
|
||||||
|
Follow these 10 steps (detailed in `migration.md`):
|
||||||
|
|
||||||
|
### 1. Create base resources
|
||||||
|
```
|
||||||
|
apps/base/<app-name>/
|
||||||
|
├── kustomization.yaml
|
||||||
|
├── namespace.yaml
|
||||||
|
├── vaultauth.yaml # if needed
|
||||||
|
└── vaultstaticsecret.yaml # if needed
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Create cluster overlay
|
||||||
|
```
|
||||||
|
apps/overlays/au-syd1/<app-name>/
|
||||||
|
├── kustomization.yaml
|
||||||
|
└── values.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
**Overlay kustomization.yaml pattern:**
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
|
||||||
|
resources:
|
||||||
|
- ../../../base/<app-name>
|
||||||
|
|
||||||
|
helmCharts:
|
||||||
|
- name: <chart-name>
|
||||||
|
repo: <helm-repo-url>
|
||||||
|
version: "<version>"
|
||||||
|
releaseName: <release-name>
|
||||||
|
namespace: <namespace>
|
||||||
|
valuesFile: values.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Register in ApplicationSet
|
||||||
|
Add a directory entry to `argocd/applicationsets/platform.yaml` (or `storage.yaml` for `csi-*` apps):
|
||||||
|
```yaml
|
||||||
|
- path: apps/overlays/*/<app-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Update AppProject
|
||||||
|
In `argocd/projects/platform.yaml` (or `storage.yaml`):
|
||||||
|
- Add the Helm repo URL to `sourceRepos`
|
||||||
|
- Add the namespace to `destinations`
|
||||||
|
- Add any required cluster-scoped resource types to `clusterResourceWhitelist`
|
||||||
|
|
||||||
|
### 5. Validate
|
||||||
|
```bash
|
||||||
|
kustomize build --enable-helm apps/overlays/au-syd1/<app-name>
|
||||||
|
make kubeconform
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Secret Management
|
||||||
|
|
||||||
|
**Plain Kubernetes `Secret` objects are blocked** by the pre-commit hook. Use Vault Operator CRDs instead:
|
||||||
|
|
||||||
|
### VaultAuth template
|
||||||
|
```yaml
|
||||||
|
apiVersion: secrets.hashicorp.com/v1beta1
|
||||||
|
kind: VaultAuth
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
namespace: <namespace>
|
||||||
|
spec:
|
||||||
|
method: kubernetes
|
||||||
|
mount: k8s/au/syd1
|
||||||
|
vaultConnectionRef: vso-system/default
|
||||||
|
allowedNamespaces:
|
||||||
|
- <namespace>
|
||||||
|
kubernetes:
|
||||||
|
role: <role>
|
||||||
|
serviceAccount: <service-account>
|
||||||
|
audiences:
|
||||||
|
- vault
|
||||||
|
tokenExpirationSeconds: 600
|
||||||
|
```
|
||||||
|
|
||||||
|
### VaultStaticSecret template
|
||||||
|
```yaml
|
||||||
|
apiVersion: secrets.hashicorp.com/v1beta1
|
||||||
|
kind: VaultStaticSecret
|
||||||
|
metadata:
|
||||||
|
name: <secret-name>
|
||||||
|
namespace: <namespace>
|
||||||
|
spec:
|
||||||
|
vaultAuthRef: default
|
||||||
|
mount: kv
|
||||||
|
type: kv-v2
|
||||||
|
path: kubernetes/namespace/<namespace>/default/<secret-name>
|
||||||
|
refreshAfter: 5m
|
||||||
|
destination:
|
||||||
|
name: <k8s-secret-name>
|
||||||
|
create: true
|
||||||
|
overwrite: true
|
||||||
|
hmacSecretData: true
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## YAML Conventions
|
||||||
|
|
||||||
|
- **2-space indentation** (enforced by yamllint)
|
||||||
|
- All files must end with a newline (`end-of-file-fixer`)
|
||||||
|
- No trailing whitespace
|
||||||
|
- YAML linting uses relaxed rules with `line-length: disable` (long base64/URLs are fine)
|
||||||
|
- yamllint ignores `chart` directories (vendored Helm charts)
|
||||||
|
- `---` document separator at top of every YAML file
|
||||||
|
- Multiple documents in one file are allowed (e.g., `vaultstaticsecret.yaml` often contains multiple secrets)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Kubernetes Labels Pattern
|
||||||
|
|
||||||
|
Use standard `app.kubernetes.io/*` labels consistently:
|
||||||
|
```yaml
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: <component>
|
||||||
|
app.kubernetes.io/instance: <release-name>
|
||||||
|
app.kubernetes.io/name: <app-name>
|
||||||
|
app.kubernetes.io/version: <version>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resource Naming Conventions
|
||||||
|
|
||||||
|
Files in `apps/base/<app-name>/` follow the pattern:
|
||||||
|
```
|
||||||
|
<kind>_<name>.yaml
|
||||||
|
```
|
||||||
|
Examples:
|
||||||
|
- `deployment_puppetserver-master.yaml`
|
||||||
|
- `cronjob_g10k-code.yaml`
|
||||||
|
- `configmap_puppetboard-config.yaml`
|
||||||
|
- `horizontalpodautoscaler_puppetserver-compilers-autoscaler.yaml`
|
||||||
|
- `service_puppet-headless.yaml`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Helm Chart Vendoring
|
||||||
|
|
||||||
|
Some overlays vendor Helm charts locally under `apps/overlays/au-syd1/<app-name>/charts/<chart-name>/`. When a chart is vendored, the overlay's `kustomization.yaml` references the local path. When not vendored, it references the OCI or HTTP repo directly.
|
||||||
|
|
||||||
|
Current Kubernetes target version: **1.33.7** (used by kubeconform in CI).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Boundaries
|
||||||
|
|
||||||
|
| Project | ApplicationSet | App pattern |
|
||||||
|
|------------|---------------------------|--------------------------|
|
||||||
|
| `platform` | `argocd/applicationsets/platform.yaml` | Named apps (cert-manager, puppet, woodpecker, etc.) |
|
||||||
|
| `storage` | `argocd/applicationsets/storage.yaml` | `csi-*` apps |
|
||||||
|
|
||||||
|
The `clusters/au-syd1/apps/` entry-point is deployed as a standalone ArgoCD `Application` (not an ApplicationSet) called `au-syd1-apps`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CI / Pre-commit Hooks
|
||||||
|
|
||||||
|
Runs on every PR via Woodpecker CI (`.woodpecker/`):
|
||||||
|
|
||||||
|
| Check | Tool | Trigger |
|
||||||
|
|---|---|---|
|
||||||
|
| YAML lint + general file checks | `pre-commit` (yamllint + pre-commit-hooks) | PR |
|
||||||
|
| No plain Secrets | `ci/validate-no-secrets.sh` | PR (staged files) |
|
||||||
|
| Kubernetes manifest validation | `kubeconform` via `make kubeconform` | PR |
|
||||||
|
|
||||||
|
kubeconform skips: `CustomResourceDefinition`, `GpuDevicePlugin` (for apps validation).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Git Workflow
|
||||||
|
|
||||||
|
- Branch naming: `benvin/<app-name>` (user prefix)
|
||||||
|
- **Never `git add .`** — add only relevant files explicitly
|
||||||
|
- If pre-commit modifies files, `git add -u` then `git commit --amend --no-edit`
|
||||||
|
- Use `git push --force-with-lease` after amending
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Policies
|
||||||
|
|
||||||
|
- `reloader.stakater.com/auto: "true"` annotation triggers rolling restarts on ConfigMap/Secret changes
|
||||||
|
- Security contexts follow least-privilege: `drop: [all]` then add only required capabilities
|
||||||
|
- `fsGroup: 999` on pod security context for Puppet workloads
|
||||||
|
- `runAsUser: 0` is used only for init containers that need to set file permissions, then regular containers run as non-root
|
||||||
@@ -28,7 +28,7 @@ spec:
|
|||||||
imagePullSecrets: null
|
imagePullSecrets: null
|
||||||
containers:
|
containers:
|
||||||
- name: g10k-code
|
- name: g10k-code
|
||||||
image: git.unkin.net/unkin/almalinux9-g10k:20260308
|
image: git.unkin.net/unkin/almalinux9-g10k:20260606
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ spec:
|
|||||||
cpu: 20m
|
cpu: 20m
|
||||||
memory: 32Mi
|
memory: 32Mi
|
||||||
- name: cert-generator
|
- name: cert-generator
|
||||||
image: git.unkin.net/unkin/almalinux9-base:20260308
|
image: git.unkin.net/unkin/almalinux9-base:20260606
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ spec:
|
|||||||
name: puppet-puppet-volume
|
name: puppet-puppet-volume
|
||||||
|
|
||||||
- name: setup-shared-bins
|
- name: setup-shared-bins
|
||||||
image: git.unkin.net/unkin/almalinux9-base:20260308
|
image: git.unkin.net/unkin/almalinux9-base:20260606
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
|
|||||||
+145
@@ -0,0 +1,145 @@
|
|||||||
|
# Migration Guide: Terragrunt to ArgoCD
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
- Examine existing Terraform configuration in `sources/terraform-k8s/config/<app-name>/`
|
||||||
|
- Identify Helm charts, values, storage classes, secrets, and other resources
|
||||||
|
|
||||||
|
## Migration Steps
|
||||||
|
|
||||||
|
### 1. Branch Creation
|
||||||
|
- Change back to main branch: `git checkout main`
|
||||||
|
- Create new branch: `git checkout -b benvin/<app-name>`
|
||||||
|
|
||||||
|
### 2. Create Base Application Structure
|
||||||
|
- Create directory: `apps/base/<app-name>/`
|
||||||
|
- Create `apps/base/<app-name>/kustomization.yaml` with resources:
|
||||||
|
- `namespace.yaml`
|
||||||
|
- `vaultauth.yaml` (if needed)
|
||||||
|
- `vaultstaticsecret.yaml` (if needed)
|
||||||
|
- Additional resources as required (storageclass.yaml, etc.)
|
||||||
|
|
||||||
|
### 3. Create Namespace
|
||||||
|
- Create `apps/base/<app-name>/namespace.yaml` with app namespace
|
||||||
|
|
||||||
|
### 4. Create Vault Integration (if needed)
|
||||||
|
- Create `apps/base/<app-name>/vaultauth.yaml` from Terraform `vault_auth.yaml`
|
||||||
|
- Convert snake_case to camelCase for Kubernetes
|
||||||
|
- Map Terraform fields to VaultAuth spec
|
||||||
|
- Create `apps/base/<app-name>/vaultstaticsecret.yaml` from `vault_static_secret.yaml`
|
||||||
|
- Convert to VaultStaticSecret spec format
|
||||||
|
|
||||||
|
### 5. Create Additional Resources
|
||||||
|
- Create any additional resources (StorageClass, etc.) from Terraform config
|
||||||
|
- Maintain exact parameter parity with Terraform
|
||||||
|
|
||||||
|
### 6. Create Overlay Structure
|
||||||
|
- Create directory: `apps/overlays/au-syd1/<app-name>/`
|
||||||
|
- Create `apps/overlays/au-syd1/<app-name>/kustomization.yaml`:
|
||||||
|
- Reference base: `../../../base/<app-name>`
|
||||||
|
- Add helmCharts section with repo, version, valuesFile
|
||||||
|
- Create `apps/overlays/au-syd1/<app-name>/values.yaml` from Terraform helm_release values
|
||||||
|
|
||||||
|
### 7. Update Project Configuration
|
||||||
|
- Add Helm repository to appropriate project in `argocd/projects/`
|
||||||
|
- Add namespace to project destinations (if needed)
|
||||||
|
- Add required cluster resource permissions
|
||||||
|
|
||||||
|
### 8. Update ApplicationSet
|
||||||
|
- Add directory pattern to appropriate ApplicationSet in `argocd/applicationsets/`
|
||||||
|
- Use existing patterns like `apps/overlays/*/csi-*` or `apps/overlays/*/<app-name>`
|
||||||
|
|
||||||
|
### 9. Validation
|
||||||
|
- Run `kustomize build --enable-helm apps/overlays/au-syd1/<app-name>` to generate all resources
|
||||||
|
- Check resource types: `kustomize build --enable-helm apps/overlays/au-syd1/<app-name> | grep "^kind:" | sort | uniq -c`
|
||||||
|
- Verify all resource types are permitted in the target project's `clusterResourceWhitelist` and `namespaceResourceWhitelist`
|
||||||
|
- Run `make kubeconform` to validate all resources
|
||||||
|
- Fix any validation errors
|
||||||
|
|
||||||
|
### 10. Git Workflow
|
||||||
|
- Add only created/modified files: `git add apps/base/<app-name>/ apps/overlays/au-syd1/<app-name>/ argocd/projects/<project>.yaml argocd/applicationsets/<project>.yaml`
|
||||||
|
- **Never use `git add .`**
|
||||||
|
- Create commit with descriptive message following existing patterns
|
||||||
|
- Push branch: `git push -u origin benvin/<app-name>`
|
||||||
|
|
||||||
|
## Project Organization
|
||||||
|
|
||||||
|
### Platform Project
|
||||||
|
- Core infrastructure and system components
|
||||||
|
- Examples: cert-manager, external-dns, cnpg-system, reflector-system, etc.
|
||||||
|
|
||||||
|
### Storage Project
|
||||||
|
- Storage-related components
|
||||||
|
- Pattern: `csi-*` applications
|
||||||
|
- Examples: csi-cephfs, csi-cephrbd
|
||||||
|
|
||||||
|
### Application-Specific Projects
|
||||||
|
- Create new projects for logical groupings as needed
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Helm Chart Integration
|
||||||
|
```yaml
|
||||||
|
helmCharts:
|
||||||
|
- name: <chart-name>
|
||||||
|
repo: <helm-repo-url>
|
||||||
|
version: "<version>"
|
||||||
|
releaseName: <release-name>
|
||||||
|
namespace: <namespace>
|
||||||
|
valuesFile: values.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### VaultAuth Template
|
||||||
|
```yaml
|
||||||
|
apiVersion: secrets.hashicorp.com/v1beta1
|
||||||
|
kind: VaultAuth
|
||||||
|
metadata:
|
||||||
|
name: <auth-name>
|
||||||
|
namespace: <namespace>
|
||||||
|
spec:
|
||||||
|
method: kubernetes
|
||||||
|
mount: k8s/au/syd1
|
||||||
|
vaultConnectionRef: vso-system/default
|
||||||
|
allowedNamespaces:
|
||||||
|
- <namespace>
|
||||||
|
kubernetes:
|
||||||
|
role: <role>
|
||||||
|
serviceAccount: <service-account>
|
||||||
|
audiences:
|
||||||
|
- vault
|
||||||
|
tokenExpirationSeconds: 600
|
||||||
|
```
|
||||||
|
|
||||||
|
### VaultStaticSecret Template
|
||||||
|
```yaml
|
||||||
|
apiVersion: secrets.hashicorp.com/v1beta1
|
||||||
|
kind: VaultStaticSecret
|
||||||
|
metadata:
|
||||||
|
name: <secret-name>
|
||||||
|
namespace: <namespace>
|
||||||
|
spec:
|
||||||
|
vaultAuthRef: <auth-ref>
|
||||||
|
mount: kv
|
||||||
|
type: kv-v2
|
||||||
|
path: <vault-path>
|
||||||
|
refreshAfter: 5m
|
||||||
|
destination:
|
||||||
|
name: <k8s-secret-name>
|
||||||
|
create: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Pre-commit Hook Issues
|
||||||
|
- If hooks modify files, add changes: `git add -u`
|
||||||
|
- Amend commit if safe: `git commit --amend --no-edit`
|
||||||
|
- Use `git push --force-with-lease` for amended commits
|
||||||
|
|
||||||
|
### Validation Failures
|
||||||
|
- Check Helm chart compatibility with Kubernetes version
|
||||||
|
- Verify all required fields are present in resources
|
||||||
|
- Ensure proper YAML formatting
|
||||||
|
|
||||||
|
### Missing Permissions
|
||||||
|
- Add required cluster resources to project clusterResourceWhitelist
|
||||||
|
- Add namespaces to project destinations
|
||||||
|
- Verify Helm repository is in project sourceRepos
|
||||||
Reference in New Issue
Block a user