Policy Templates¶
AMDF generates policy templates for compile-time validation with KCL. These templates provide fast feedback during development with type-safe checks.
Quick Start¶
1. Generate with Policy Template¶
# Native Kubernetes resource
amdf generate-k8s Deployment
# Custom Resource Definition
amdf generate virtualservices.networking.istio.io
Generated structure:
library/
├── blueprints/
│ └── Deployment.k # Simplified interface
├── models/
│ └── k8s/apps_v1/ # Complete schema
├── policies/
│ └── DeploymentPolicy.k # Policy template
└── main.k # Example usage
2. Customize Policy Checks¶
Edit policies/DeploymentPolicy.k:
schema DeploymentPolicyMixin:
check:
# Uncomment checks you want to enforce.
# Unset optional fields are Undefined in KCL: use `!= Undefined` to
# require a field, or guard constraints with `== Undefined or ...`
# so they only apply when the field is set.
_replicas == Undefined or _replicas >= 2, "Minimum 2 replicas for HA"
all container in _template.spec.containers {
not container.image.endswith(":latest")
}, "Using :latest tag not allowed"
3. Apply Policy in Configuration¶
Edit main.k:
import blueprints.Deployment
import policies.DeploymentPolicy
# Create validated schema
schema ValidatedDeployment(Deployment.DeploymentBlueprint):
mixin [DeploymentPolicy.DeploymentPolicyMixin]
# Use it
app = ValidatedDeployment {
_metadataName = "nginx"
_replicas = 3
_selector = {matchLabels = {app = "nginx"}}
_template = {
spec = {
containers = [{
name = "nginx"
image = "nginx:1.21"
}]
}
}
}
items = [app]
4. Validate Configuration¶
KCL validates automatically when you compile:
If validation fails:
Error: EvaluationError
--> library/main.k:9:7
|
9 | app = ValidatedDeployment {
| ^ Instance check failed
|
--> library/policies/DeploymentPolicy.k:8:1
|
8 | }, "Using :latest tag not allowed"
| Check failed on the condition: Using :latest tag not allowed
Fix the issue and run again. No YAML generation needed for policy validation - KCL checks run at compile-time.
5. Generate YAML (After Validation Passes)¶
6. Apply to Cluster¶
Policy Templates¶
What They Are¶
Policy templates provide compile-time validation in KCL. Generated with common checks commented out, ready to enable based on your requirements.
Common Checks by Resource¶
Pod¶
# Security: Disallow privileged containers
# all container in _containers {
# not (container?.securityContext?.privileged == True)
# }, "Privileged containers not allowed"
# Security: Require non-root user
# all container in _containers {
# container?.securityContext?.runAsNonRoot == True
# }, "Containers must run as non-root"
# Best practice: Disallow latest tag
# all container in _containers {
# not container.image.endswith(":latest")
# }, "Using :latest tag not allowed"
# Resource limits
# all container in _containers {
# "memory" in (container?.resources?.limits or {})
# }, "Memory limits required"
Deployment¶
# Replicas validation
# _replicas == Undefined or _replicas >= 2, "Minimum 2 replicas for HA"
# Security: Disallow privileged containers
# all container in _template.spec.containers {
# not (container?.securityContext?.privileged == True)
# }, "Privileged containers not allowed"
# Best practice: Require resource limits
# all container in _template.spec.containers {
# "memory" in (container?.resources?.limits or {})
# }, "Memory limits required"
Service¶
# Type validation
# _type == Undefined or _type in ["ClusterIP", "NodePort", "LoadBalancer"],
# "Invalid service type"
# Port validation
# len(_ports or []) > 0, "At least one port required"
CRDs (Auto-generated from schema)¶
# Example: Istio VirtualService
# len(spec?.hosts or []) > 0, "hosts list required"
# len(spec?.gateways or []) > 0, "gateways list required"
# len(spec?.http or []) > 0, "http routes required"
Custom Checks¶
Add your own validation logic. Blueprints assign every field unconditionally, so
an unset optional field is Undefined, not absent. Two patterns cover this:
- Require a field:
field != Undefined - Constrain a field only when set:
field == Undefined or <condition>
schema DeploymentPolicyMixin:
check:
# Require a field
_namespace != Undefined, "namespace is required"
# Constrain only when the field is set
_replicas == Undefined or _replicas >= 2, "Minimum 2 replicas"
_namespace == Undefined or _namespace in ["prod", "staging"], "Invalid namespace"
# Guard collection access so it never fails on an unset value
"team" in (_labels or {}), "Team label required"
all container in _template.spec.containers {
container.image.startswith("myregistry.io/")
}, "Must use approved registry"
Conditional Checks¶
schema PodPolicyMixin:
check:
# Only enforce in production
_namespace != "prod" or all container in _containers {
"memory" in (container?.resources?.limits or {})
}, "Memory limits required in prod"
Opting Out of Validation¶
The policy template is always generated, but validation is opt-in: it applies
only when you use the Validated<Kind> schema (which mixes in the policy) and
uncomment the checks you want to enforce. To skip validation entirely, instance
the blueprint directly instead of the validated schema — the blueprint has no
checks of its own: