--- name: gitops-audit description: Comprehensive GitOps compliance verification that detects configuration drift and policy violations through three audit types - (1) Cluster Drift (resources in cluster not tracked in git), (2) Spec Drift (differences between git manifests and cluster state), (3) Code Violations (hardcoded Kubernetes configs in application code). Automatically triggered when code review detects changes to *.yaml/*.yml in charts/, manifests/, k8s/, kubernetes/, deployment scripts, Helm charts, Kustomize files, or Kubernetes client library imports. Use manually for investigating cluster drift, auditing GitOps compliance, before production deployments, troubleshooting sync issues, or regular compliance checks. --- # GitOps Audit Skill ## Quick Start GitOps audit verifies that your cluster state matches your git state by running three checks: 1. **Cluster Drift**: Find resources in cluster that aren't in git 2. **Spec Drift**: Find differences between git manifests and live cluster state 3. **Code Violations**: Find hardcoded Kubernetes configs in application code **Run the audit:** ```bash /gitops-audit ``` **Expected flow:** 1. Skill detects GitOps repository location 2. Runs three audit checks in parallel 3. Generates comprehensive report with severity levels (CRITICAL, WARNING, INFO) 4. Provides remediation steps --- ## When to Load Additional References The core workflow below is sufficient for most audits. Load these references for detailed patterns and troubleshooting: **For detailed drift patterns and examples:** ``` Read `~/.claude/skills/gitops-audit/references/DRIFT-PATTERNS.md` ``` Use when: You need detailed examples of what each audit type detects, or want to understand specific drift patterns **For configuration and resource handling:** ``` Read `~/.claude/skills/gitops-audit/references/KUBERNETES-RESOURCES.md` ``` Use when: Setting up configuration, handling CRDs/operators, or understanding exclusion patterns **For troubleshooting and edge cases:** ``` Read `~/.claude/skills/gitops-audit/references/TROUBLESHOOTING.md` ``` Use when: Encountering issues, dealing with false positives, or handling special cases (HPA, operators, multi-cluster) --- ## Core Workflow ### Step 1: Detect GitOps Repository **Automatic detection methods:** - Check environment variable: `GITOPS_REPO_PATH` - Search common locations: `~/gitops-repo`, `~/projects/gitops`, `~/k8s-manifests` - Parse git remotes: `git remote -v | grep -E "(gitops|k8s|kubernetes|manifests)"` **Ask user if not found:** ``` GitOps repository not automatically detected. Please provide the path to your GitOps repository: - Local path: /path/to/gitops-repo - Or I can clone it: git@github.com:org/gitops-repo.git ``` **Detect repository structure:** - **Helm**: Check for `charts/` directory - **Kustomize**: Check for `kustomization.yaml` or `base/` directory - **Plain YAML**: Check for `manifests/` or `k8s/` directory --- ### Step 2: Run Cluster Drift Check **Objective:** Find resources in cluster that don't exist in git **Process:** ```bash # Get all resources in namespace RESOURCES=$(kubectl api-resources --verbs=list --namespaced -o name | \ xargs -n 1 kubectl get --show-kind --ignore-not-found -o name -n $NAMESPACE) # For each resource for RESOURCE in $RESOURCES; do KIND=$(echo $RESOURCE | cut -d'/' -f1) NAME=$(echo $RESOURCE | cut -d'/' -f2) # Search git for manifest FOUND=$(find $GITOPS_REPO -name "*.yaml" -o -name "*.yml" | \ xargs grep -l "kind: $KIND" | \ xargs grep -l "name: $NAME") if [ -z "$FOUND" ]; then echo "DRIFT: $RESOURCE not in git" fi done ``` **Report format:** ``` 🚨 CRITICAL: Resources in cluster NOT tracked in git Namespace: production - Deployment/debug-pod (created manually, age: 2 days) Action: Delete OR add manifest to gitops-repo/production/ - ConfigMap/temp-config (no manifest found, age: 5 hours) Action: Delete OR formalize in charts/app/config/ ``` --- ### Step 3: Run Spec Drift Analysis **Objective:** Find differences between git manifests and live cluster state **Process:** ```bash # Render manifest from git if [ "$TYPE" = "helm" ]; then RENDERED=$(helm template $CHART -f $VALUES_FILE) elif [ "$TYPE" = "kustomize" ]; then RENDERED=$(kustomize build $PATH) else RENDERED=$(cat $MANIFEST) fi # Get live resource LIVE=$(kubectl get $KIND $NAME -n $NAMESPACE -o yaml) # Diff them DIFF=$(kubectl diff -f <(echo "$RENDERED") 2>&1) if [ -n "$DIFF" ]; then echo "SPEC DRIFT: $KIND/$NAME" fi ``` **Report format:** ``` âš ī¸ WARNING: Spec drift detected (git ≠ cluster) Deployment/api-service (production): Git: replicas=3 Cluster: replicas=5 (DRIFT) Action: Reconcile via gitops-apply skill ConfigMap/app-config (staging): Git: LOG_LEVEL=info Cluster: LOG_LEVEL=debug (DRIFT) Action: Update git OR revert cluster ``` --- ### Step 4: Run Code Violations Scan **Objective:** Find hardcoded Kubernetes configs in application code **Process:** ```bash # Scan for inline YAML grep -r -E "(apiVersion|kind:.*Deployment|kind:.*Service)" \ --include="*.py" --include="*.go" --include="*.js" --include="*.ts" \ --include="*.sh" --exclude-dir=tests --exclude-dir=node_modules # Scan for kubectl commands grep -r -E "kubectl\s+(apply|create|delete|patch|edit)" \ --include="*.sh" --include="*.py" --include="*.js" --include="*.go" \ --exclude-dir=tests # Scan for hardcoded resource creation (Go) grep -r -E "(CreateDeployment|CreateService|client\.Create\()" \ --include="*.go" --exclude-dir=vendor # Scan for hardcoded resource creation (Python) grep -r -E "(create_namespaced_deployment|create_namespaced_service)" \ --include="*.py" ``` **Report format:** ``` ❌ CRITICAL: Hardcoded Kubernetes configs in application code scripts/deploy.sh:45 kubectl apply -f - <