validate.yaml (7208B)
1 name: Validate GitOps Manifests 2 3 on: 4 pull_request: 5 branches: ["*"] 6 paths: 7 - "apps/**" 8 - "clusters/**" 9 - "infrastructure_talos/**" 10 - "scripts/validate.sh" 11 push: 12 branches: ["main"] 13 paths: 14 - "apps/**" 15 - "clusters/**" 16 - "infrastructure_talos/**" 17 - "scripts/validate.sh" 18 workflow_dispatch: 19 20 permissions: 21 contents: read 22 23 jobs: 24 validate-manifests: 25 name: Validate Kubernetes Manifests 26 runs-on: ubuntu-latest 27 steps: 28 - name: Checkout 29 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 30 with: 31 persist-credentials: false 32 33 - name: Setup Flux CLI 34 uses: fluxcd/flux2/action@7d27a26665b34463b0ed5fb54fa06642375536f9 # main 35 36 - name: Setup tools 37 run: | 38 # Install yq 39 sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 40 sudo chmod +x /usr/local/bin/yq 41 42 # Install kustomize 43 curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash 44 sudo mv kustomize /usr/local/bin/ 45 46 # Install kubeconform 47 curl -LO https://github.com/yannh/kubeconform/releases/latest/download/kubeconform-linux-amd64.tar.gz 48 tar xzf kubeconform-linux-amd64.tar.gz 49 sudo mv kubeconform /usr/local/bin/ 50 51 # Verify installations 52 yq --version 53 kustomize version 54 kubeconform -v 55 56 - name: Run validation script 57 run: | 58 chmod +x scripts/validate.sh 59 ./scripts/validate.sh 60 continue-on-error: true 61 62 security-scan: 63 name: Security Scanning 64 runs-on: ubuntu-latest 65 permissions: 66 contents: read 67 security-events: write 68 steps: 69 - name: Checkout 70 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 71 with: 72 fetch-depth: 0 73 persist-credentials: false 74 75 - name: Run gitleaks 76 uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2 77 env: 78 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 79 80 - name: Setup tools for manifest extraction 81 run: | 82 # Install yq 83 sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 84 sudo chmod +x /usr/local/bin/yq 85 86 # Install kustomize 87 curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash 88 sudo mv kustomize /usr/local/bin/ 89 90 - name: Extract container images 91 id: extract-images 92 run: | 93 set +e 94 mkdir -p /tmp/manifests 95 96 # Build all kustomizations and extract images 97 find . -type f -name 'kustomization.yaml' | while read -r file; do 98 dir=$(dirname "$file") 99 echo "Building $dir" 100 kustomize build "$dir" --load-restrictor=LoadRestrictionsNone > /tmp/manifests/$(echo "$dir" | tr '/' '_').yaml 2>/dev/null || true 101 done 102 103 # Extract unique images 104 cat /tmp/manifests/*.yaml | yq eval 'select(.spec.template.spec.containers != null) | .spec.template.spec.containers[].image' - 2>/dev/null | sort -u > /tmp/images.txt || true 105 cat /tmp/manifests/*.yaml | yq eval 'select(.spec.template.spec.initContainers != null) | .spec.template.spec.initContainers[].image' - 2>/dev/null | sort -u >> /tmp/images.txt || true 106 107 # Extract images from HelmRelease values 108 find . -type f -name '*.yaml' -exec grep -l "kind: HelmRelease" {} \; | while read -r file; do 109 yq eval '.spec.values | .. | select(. == "*image*" or . == "*repository*") | select(type == "!!str")' "$file" 2>/dev/null || true 110 done >> /tmp/images.txt || true 111 112 sort -u /tmp/images.txt > /tmp/images_final.txt 113 114 echo "Found images:" 115 cat /tmp/images_final.txt 116 117 - name: Run Trivy vulnerability scanner 118 uses: aquasecurity/trivy-action@876cf04c63f65e9799bcf1043b584e72469c7143 # master 119 with: 120 scan-type: "config" 121 scan-ref: "." 122 format: "sarif" 123 output: "trivy-results.sarif" 124 severity: "CRITICAL,HIGH" 125 126 - name: Upload Trivy results to GitHub Security 127 uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 128 if: always() 129 with: 130 sarif_file: "trivy-results.sarif" 131 132 kubescape: 133 name: Kubescape Security Scan 134 runs-on: ubuntu-latest 135 permissions: 136 contents: read 137 security-events: write 138 steps: 139 - name: Checkout 140 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 141 with: 142 persist-credentials: false 143 144 - name: Setup tools 145 run: | 146 # Install kustomize 147 curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash 148 sudo mv kustomize /usr/local/bin/ 149 150 - name: Build manifests 151 run: | 152 mkdir -p manifests 153 find . -type f -name 'kustomization.yaml' | while read -r file; do 154 dir=$(dirname "$file") 155 echo "Building $dir" 156 kustomize build "$dir" --load-restrictor=LoadRestrictionsNone > manifests/$(echo "$dir" | tr '/' '_').yaml 2>/dev/null || true 157 done 158 ls -la manifests/ 159 160 - name: Run Kubescape 161 uses: kubescape/github-action@47d8e4561a2a1be8e22a4edfbd02c0b97f7335cb # main 162 continue-on-error: true 163 with: 164 files: "manifests/" 165 severityThreshold: high 166 format: sarif 167 verbose: true 168 outputFile: results.sarif 169 170 - name: Fix Kubescape SARIF artifact locations 171 if: always() 172 run: | 173 if [ -f results.sarif ]; then 174 jq ' 175 .runs[].results[] |= ( 176 if .locations then 177 .locations[] |= ( 178 if .physicalLocation then 179 .physicalLocation.artifactLocation.uri //= "unknown" 180 else 181 .physicalLocation = {"artifactLocation": {"uri": "unknown"}} 182 end 183 ) 184 else 185 .locations = [{"physicalLocation": {"artifactLocation": {"uri": "unknown"}}}] 186 end 187 ) 188 ' results.sarif > results-fixed.sarif && mv results-fixed.sarif results.sarif 189 fi 190 191 - name: Upload Kubescape results to GitHub Security 192 uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 193 if: always() 194 with: 195 sarif_file: "results.sarif" 196 197 lint: 198 name: Lint YAML Files 199 runs-on: ubuntu-latest 200 steps: 201 - name: Checkout 202 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 203 with: 204 persist-credentials: false 205 206 - name: YAML Lint 207 uses: ibiqlik/action-yamllint@2576378a8e339169678f9939646ee3ee325e845c # v3 208 continue-on-error: true 209 with: 210 config_file: .yamllint