Kubernetes YAML Validation Workflow
This document outlines the comprehensive validation workflow for Kubernetes YAML resources.
Validation Stages
Stage 0: Resource Count (Deterministic)
Purpose: Count non-empty YAML documents before running validators.
Command:
python3 scripts/count_yaml_documents.py <file.yaml>Fallback when Python is unavailable (estimated count):
awk 'BEGIN{d=0;seen=0} /^[[:space:]]*---[[:space:]]*$/ {if(seen){d++;seen=0}; next} /^[[:space:]]*#/ {next} NF{seen=1} END{if(seen)d++; print d}' <file.yaml>Stage 1: Tool Check
Purpose: Determine which validation stages are runnable in the current environment.
Command:
bash scripts/setup_tools.shIf required tools are missing, continue with available tools and report skipped stages.
Stage 2: YAML Syntax Validation (yamllint)
Purpose: Catch YAML syntax errors and style issues before Kubernetes-specific validation.
Command:
yamllint -c assets/.yamllint <file.yaml>Common Issues Detected:
- Indentation errors (tabs vs spaces)
- Line length violations
- Trailing spaces
- Missing document start markers
- Duplicate keys
- Syntax errors
Stage 3 (CRD detection and docs lookup) is covered in the dedicated section below.
Stage 4: Kubernetes Schema Validation (kubeconform)
Purpose: Validate against Kubernetes schemas and detect structural issues.
Basic Command:
kubeconform -summary <file.yaml>With CRD Support (recommended):
kubeconform \
-schema-location default \
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
-strict \
-ignore-missing-schemas \
-summary \
-verbose \
<file.yaml>Options:
-strict: Reject resources with unknown fields (catches typos - recommended for production)-ignore-missing-schemas: Skip validation for CRDs without available schemas-kubernetes-version <version>: Validate against specific K8s version (e.g., 1.30.0)-output json: Output results as JSON
Common Issues Detected:
- Invalid apiVersion
- Missing required fields
- Invalid field types
- Unknown fields (in strict mode)
- Invalid enum values
Stage 5: Cluster Dry-Run (kubectl)
Purpose: Validate against the actual cluster configuration, admission controllers, and policies.
Client-Side Dry Run:
kubectl apply --dry-run=client --validate=false -f <file.yaml>- Best-effort fallback when server-side dry-run is unavailable
- May still fail if API discovery is unavailable (for example, no reachable cluster)
- Does not catch admission controller or policy issues
Server-Side Dry Run:
kubectl apply --dry-run=server -f <file.yaml>- Full validation including admission controllers
- Validates against cluster-specific constraints
- Requires cluster access
- Catches issues like:
- Resource quota violations
- Policy violations (PSP, OPA, Kyverno)
- Admission webhook rejections
- Namespace existence
- ConfigMap/Secret references
Diff Mode (for updates):
kubectl diff -f <file.yaml>Shows what would change if applied to the cluster.
CRD Detection and Documentation Lookup (Stage 3)
Step 1: Detect CRDs
Use the wrapper script (handles missing PyYAML automatically):
bash scripts/detect_crd_wrapper.sh <file.yaml>Output example:
{
"resources": [
{
"kind": "Certificate",
"apiVersion": "cert-manager.io/v1",
"group": "cert-manager.io",
"version": "v1",
"isCRD": true,
"name": "example-cert"
}
],
"parseErrors": [],
"summary": {
"totalDocuments": 1,
"parsedSuccessfully": 1,
"parseErrors": 0,
"crdsDetected": 1
}
}Step 2: Lookup CRD Documentation
For each detected CRD:
Use context7 MCP (preferred):
- Resolve library ID:
mcp__context7__resolve-library-idwith the CRD group/project name - Fetch documentation:
mcp__context7__query-docswith the library ID - Focus on the specific version if available
- Resolve library ID:
Fallback to Web Search:
- Search query:
"<kind>" "<group>" kubernetes CRD "<version>" documentation - Example:
"Certificate" "cert-manager.io" kubernetes CRD "v1" documentation - Look for official documentation sites
- Check for API references and examples
- Search query:
Step 3: Validate Against CRD Schema
Once documentation is found:
- Check required fields in spec
- Verify field types and formats
- Validate enum values
- Check for version-specific changes
Complete Validation Workflow
┌─────────────────────────────────────────────────────────────┐
│ 0. Count Documents │
│ Run: python3 scripts/count_yaml_documents.py <file.yaml> │
│ Record: documents + separators │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 1. Check Tools │
│ Run: bash scripts/setup_tools.sh │
│ Continue with available tools │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 2. YAML Syntax Check │
│ Run: yamllint -c assets/.yamllint <file.yaml> │
│ Fix: Indentation, trailing spaces, syntax errors │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 3. Detect CRDs │
│ Run: bash scripts/detect_crd_wrapper.sh <file.yaml> │
│ Parse: Extract kind, apiVersion, group │
└─────────────────────────────────────────────────────────────┘
↓
┌──────┴──────┐
│ │
[CRD?] [Standard Resource]
│ │
↓ ↓
┌──────────────────────┐ │
│ 4a. Lookup CRD Docs │ │
│ - context7 MCP │ │
│ - Web search │ │
│ - Version-aware │ │
└──────────────────────┘ │
│ │
└──────┬──────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 4. Schema Validation │
│ Run: kubeconform -summary <file.yaml> │
│ Fix: Required fields, types, unknown fields │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 5. Dry-Run (if cluster available) │
│ Run: kubectl apply --dry-run=server -f <file.yaml> │
│ Fix: Admission issues, quotas, policies │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 6. Generate Validation Report │
│ - Summarize all issues in table format │
│ - Show before/after code blocks for each issue │
│ - Do NOT modify files - report only │
└─────────────────────────────────────────────────────────────┘Error Handling
Tool Not Found
- Run
scripts/setup_tools.shto check tool availability - Provide installation instructions
- Skip optional validation stages if tools missing
Cluster Not Available
- Skip server-side dry-run
- Attempt client-side dry-run with
--dry-run=client --validate=false - If client-side still fails due discovery/openapi errors, skip dry-run and rely on kubeconform
- Warn user that dry-run coverage is limited or unavailable
CRD Documentation Not Found
- Document that CRD docs couldn't be found
- Attempt validation with kubeconform CRD schemas
- Suggest checking cluster for CRD definition:
kubectl get crd <crd-name> -o yaml
Multiple Resources in One File
- Validate each resource separately
- Track which resource has issues
- Provide line numbers for error locations
Best Practices for Validation
- Always validate in order: count → tool check → syntax → CRD detection → schema → dry-run
- Collect all issues: Don't stop at first error - gather everything before reporting
- For CRDs: Always look up documentation first
- Version awareness: Check K8s version compatibility
- Test with cluster: Server-side dry-run is the most reliable
- Show before/after: Display code blocks showing suggested fixes
- Provide context: Explain what each issue means and why the fix is needed
- Report only: Do NOT modify files - let user decide which fixes to apply
- Load best practices reference: When schema errors occur, load k8s_best_practices.md for context
Creating Validation Reports
Generate a comprehensive validation report with all findings. Do NOT modify files.
Report Components
Header with issue count
## Validation Report - 7 issues found (4 errors, 3 warnings)Issues Summary Table
| Severity | Stage | Location | Issue | Suggested Fix | |----------|-------|----------|-------|---------------| | Error | Syntax | file.yaml:8 | Wrong indentation | Use 2 spaces | | Error | Schema | file.yaml:21 | Wrong type | Change to integer | | Warning | Best Practice | file.yaml:30 | Missing labels | Add app label |Detailed Findings (for each issue)
- File:line reference
- Current code block
- Suggested fix code block
- Explanation of why it matters
Validation status by stage
- Show which stages passed/failed
- Note if any stages were skipped (e.g., no cluster access)
Next Steps
- List errors that must be fixed before deployment
- List warnings for best practices consideration
- Suggest re-running validation after fixes
Example Report Format
## Validation Report - 7 issues found
File: deployment.yaml
Resources Analyzed: 3 (Deployment, Service, Certificate)
| Stage | Status | Issues |
|-------|--------|--------|
| YAML Syntax | ❌ Failed | 2 errors |
| CRD Detection | ✅ Passed | 1 CRD found |
| Schema Validation | ❌ Failed | 2 errors |
| Dry-Run | ❌ Failed | 1 error |
### Issue 1: deployment.yaml:8 - Wrong indentation (Error)
Current:
```yaml
labels:Suggested Fix:
labels:Why: Kubernetes YAML requires 2-space indentation.
Issue 2: deployment.yaml:21 - Wrong field type (Error)
Current:
- containerPort: "80"Suggested Fix:
- containerPort: 80Why: containerPort must be an integer, not a string.
[... more issues ...]
Next Steps
- Fix the 4 errors listed above (deployment will fail without these)
- Consider addressing the 3 warnings for best practices
- Re-run validation to confirm all issues resolved
### Report Best Practices
- **Be specific:** List every issue with exact location
- **Show both current and suggested:** Always show before/after code blocks
- **Explain impact:** Help user understand why each issue matters
- **Group by file:** When multiple files are involved
- **Prioritize by severity:** Errors first, then warnings, then info
- **Provide file references:** Always include file:line for traceability
- **Clear next steps:** Tell user exactly what to do