#!/bin/bash # Phase 2 Remaining Apps — Per-app PVC imports (portainer → dev-tools → loki → minio-logging → forgejo) # Same procedure as grafana pilot; follow the pattern set -e cd "$(dirname "$0")/.." echo "=== Phase 2 Remaining Apps ===" echo "Execute per-app cycles: portainer → dev-tools → loki → minio-logging → forgejo" echo "" # Helper function for per-app import import_app_pvc() { local app=$1 local namespace=$2 local pvc_name=$3 echo "--- Importing $app PVC ---" echo "" # Annotate echo "Step a) Annotate PVC with helm.sh/resource-policy=keep:" kubectl annotate pvc "$pvc_name" -n "$namespace" helm.sh/resource-policy=keep --overwrite echo "" # Capture live spec echo "Step b) Capture live PVC spec:" kubectl get pvc "$pvc_name" -n "$namespace" -o yaml > "/tmp/${app}-pvc-live.yaml" echo "Saved to /tmp/${app}-pvc-live.yaml" echo "" PV_NAME=$(kubectl get pvc "$pvc_name" -n "$namespace" -o jsonpath='{.spec.volumeName}') echo "Bound PV: $PV_NAME" echo "MANUAL: Update terraform/${app}.tf with correct volumeName '$PV_NAME'" read -p "Press Enter once terraform/${app}.tf is updated: " _ || true echo "" # Import echo "Step d) Import to Terraform state:" terraform import "kubernetes_persistent_volume_claim.${app}" "${namespace}/${pvc_name}" || { echo "ERROR: import failed for $app" return 1 } echo "" # Plan echo "Step d cont.) Verify zero diff:" PLAN_OUTPUT=$(terraform plan 2>&1) echo "$PLAN_OUTPUT" if ! echo "$PLAN_OUTPUT" | grep -q "0 to add, 0 to change, 0 to destroy"; then echo "ERROR: Plan is not clean for $app" return 1 fi echo "✓ Plan is clean" echo "" # Baseline Longhorn health echo "Step f.1) Baseline Longhorn replica health:" kubectl get longhorn-volume -n longhorn-system "$PV_NAME" -o json 2>/dev/null | jq '.status.replicaStatus' 2>/dev/null || echo " (unavailable)" read -p "Press Enter to continue: " _ || true echo "" # Update values echo "Step e) Update values to use existingClaim (if supported) or keep identical:" echo "MANUAL: Verify terraform/${app}.tf resource block matches live PVC spec exactly" echo " Update chart values (k8s/ directory) to point to existing PVC or keep identical" read -p "Press Enter once values updated: " _ || true echo "" # helmfile diff echo "Step e.2) Helmfile diff:" cd "$(dirname "$0")/../.." helmfile -f helmfile.yaml.gotmpl -l name="$app" diff 2>&1 | head -50 || echo " (helmfile diff unavailable)" cd "$(dirname "$0")/../terraform" echo "" read -p "Confirm no destructive ops. Press Enter to continue: " _ || true echo "" # helmfile apply echo "Step e.3) Helmfile apply:" cd "$(dirname "$0")/../.." helmfile -f helmfile.yaml.gotmpl -l name="$app" apply || echo " (helmfile apply unavailable)" cd "$(dirname "$0")/../terraform" echo "" # Post-apply Longhorn health echo "Step f.2) Post-apply Longhorn health:" kubectl get longhorn-volume -n longhorn-system "$PV_NAME" -o json 2>/dev/null | jq '.status.replicaStatus' 2>/dev/null || echo " (unavailable)" echo "Confirm matches baseline." read -p "Press Enter if health is good: " _ || true echo "" # Final plan echo "Step d) Final terraform plan:" PLAN_OUTPUT=$(terraform plan 2>&1) echo "$PLAN_OUTPUT" if ! echo "$PLAN_OUTPUT" | grep -q "0 to add, 0 to change, 0 to destroy"; then echo "ERROR: Plan is not clean after helmfile apply for $app" return 1 fi echo "✓ Plan is clean" echo "" echo "=== $app Complete ===" echo "" } # Execute per-app imports in sequence (ascending risk) import_app_pvc "portainer" "dashboard" "portainer" || { echo "FAILED at portainer"; exit 1; } import_app_pvc "dev_tools" "dev-tools" "dev-tools-pvc" || { echo "FAILED at dev-tools"; exit 1; } import_app_pvc "loki" "logging" "loki" || { echo "FAILED at loki"; exit 1; } import_app_pvc "minio_logging" "logging" "minio" || { echo "FAILED at minio-logging"; exit 1; } import_app_pvc "forgejo_shared_storage" "cicd" "forgejo-shared-storage" || { echo "FAILED at forgejo"; exit 1; } echo "=== Phase 2 Remaining Apps: Complete ===" echo "All safe apps imported successfully." echo "" echo "Next steps:" echo " 1. Conditional apps (pending Phase 0 ambiguity resolution):" echo " - minio (storage) — if standalone chart is authoritative" echo " - kmsvc-redis — if helmfile release is authoritative and architecture is standalone" echo " - forgejo-runner PVCs — if Helm chart is authoritative" echo " 2. Never import: ddb-cluster, prometheus, kafka-cluster, authentik-postgresql, llm namespace" echo " 3. Commit all new terraform/*.tf files to git and create PR"