Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
319 changes: 315 additions & 4 deletions docs/resources/node_policy.md

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions docs/resources/workload_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ resource "devzero_workload_policy" "cost_saving" {

enable_pmax_protection = true # guard against spike-induced OOMKills
pmax_ratio_threshold = 3 # raise requests when peak is 3× the recommendation

emergency_response = {
oom_enabled = true
oom_memory_multiplier = 1.5
cpu_throttling_enabled = true
cpu_throttling_threshold = 0.20
cpu_throttling_multiplier = 1.25
}
}
```

Expand All @@ -83,6 +91,7 @@ resource "devzero_workload_policy" "cost_saving" {
- `description` (String) Free-form description of the policy to help others understand its intent and scope.
- `detection_triggers` (List of String) Detection triggers for when to apply the workload policy. Valid values: `pod_creation`, `pod_update`, `pod_evict`.The `pod_creation` trigger is used to apply the workload policy when a pod is created.The `pod_update` trigger is used to apply the workload policy when a pod is updated.The `pod_evict` trigger is used to apply the workload policy when a pod is evicted.
- `drift_delta_percent` (Number) Percentage drift from baseline that triggers VPA refresh
- `emergency_response` (Attributes) Emergency response configuration for OOM and CPU throttle events (see [below for nested schema](#nestedatt--emergency_response))
- `enable_in_place_vertical_scaling` (Boolean) When true, vertical recommendations are applied in place (without recreating pods) where the cluster supports it. Default: false.
- `enable_pmax_protection` (Boolean) When true, the recommender raises requests to cover observed peak usage when the peak-to-recommendation ratio exceeds `pmax_ratio_threshold`. Default: false.
- `gpu_vertical_scaling` (Attributes) GPU vertical scaling options (see [below for nested schema](#nestedatt--gpu_vertical_scaling))
Expand Down Expand Up @@ -139,6 +148,20 @@ Optional:
- `target_percentile` (Number) Target percentile for resource sizing (e.g., 0.75 = P75).


<a id="nestedatt--emergency_response"></a>
### Nested Schema for `emergency_response`

Optional:

- `cpu_throttling_enabled` (Boolean) React to CPU throttling by increasing CPU request
- `cpu_throttling_multiplier` (Number) Multiplier applied to CPU request on throttle reaction
- `cpu_throttling_threshold` (Number) Throttle ratio threshold that triggers a reaction (0-1)
- `oom_cooldown_seconds` (Number) Seconds to wait between OOM reactions
- `oom_enabled` (Boolean) React to OOM kills by increasing memory
- `oom_max_reactions` (Number) Maximum number of OOM reactions before giving up
- `oom_memory_multiplier` (Number) Multiplier applied to memory on OOM


<a id="nestedatt--gpu_vertical_scaling"></a>
### Nested Schema for `gpu_vertical_scaling`

Expand Down
122 changes: 120 additions & 2 deletions docs/resources/workload_rule.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,44 @@ resource "devzero_workload_rule" "manual" {
cpu_throttling_multiplier = 1.25
}

live_migration_enabled = false
use_in_place_vertical_scaling = false
# JVM heap sizing (only applies when the workload is detected as running a JVM)
jvm_heap_rule = {
enabled = true
target_percentile = 0.95
headroom_multiplier = 1.2
non_heap_overhead_percent = 0.15
min_heap_bytes = 268435456 # 256Mi
max_heap_bytes = 4294967296 # 4Gi
prefer_container_support = false
}
jvm_cpu_startup_floor_millicores = 250 # override the 75m default while the JVM warms up

# Hand the ScaledObject lifecycle to KEDA instead of generating an HPA
keda_scaled_object = {
min_replica_count = 1
max_replica_count = 20
cooldown_period = 300

triggers = [
{
type = "prometheus"
metadata = {
serverAddress = "http://prometheus.monitoring.svc.cluster.local:9090"
query = "rate(http_requests_total{job=\"my-api\"}[5m])"
threshold = "100"
}
}
]

fallback = {
failure_threshold = 3
replicas = 2
}
}

live_migration_enabled = false
use_in_place_vertical_scaling = false
allow_in_place_memory_limit_decrease = false
}

# Per-container rules
Expand Down Expand Up @@ -133,6 +169,7 @@ resource "devzero_workload_rule" "per_container" {
### Optional

- `action_triggers` (List of String) When to apply recommendations. Valid values: 'on_detection', 'on_schedule'
- `allow_in_place_memory_limit_decrease` (Boolean) Opt-in: allow an in-place resize to lower a container's memory limit. Only consulted when `use_in_place_vertical_scaling` is true; a decrease still additionally requires a cluster new enough to accept one. Default false because shrinking a live container's memory limit can OOM-kill it.
- `auto_generate` (Boolean) When true the engine generates all rule fields automatically; manual field overrides are ignored
- `containers` (Attributes List) Per-container resource rule configurations. When empty, workload-level rules apply to all containers. (see [below for nested schema](#nestedatt--containers))
- `cpu_rule` (Attributes) CPU vertical scaling rule configuration (see [below for nested schema](#nestedatt--cpu_rule))
Expand All @@ -143,6 +180,9 @@ resource "devzero_workload_rule" "per_container" {
- `emergency_response` (Attributes) Emergency response configuration for OOM and CPU throttle events (see [below for nested schema](#nestedatt--emergency_response))
- `gpu_rule` (Attributes) GPU vertical scaling rule configuration (see [below for nested schema](#nestedatt--gpu_rule))
- `hpa_rule` (Attributes) Horizontal (replica) scaling rule configuration (see [below for nested schema](#nestedatt--hpa_rule))
- `jvm_cpu_startup_floor_millicores` (Number) Per-rule override of the JVM CPU startup floor in millicores. Unset inherits the policy/system default (75m); explicit `0` disables the floor for this rule. Always-on for detected JVMs, independent of `jvm_heap_rule.enabled`.
- `jvm_heap_rule` (Attributes) JVM heap optimization overrides for this rule (see [below for nested schema](#nestedatt--jvm_heap_rule))
- `keda_scaled_object` (Attributes) KEDA ScaledObject template authored by the user. When set, the in-cluster operator owns the ScaledObject lifecycle (create/update/delete) instead of generating its own HPA. (see [below for nested schema](#nestedatt--keda_scaled_object))
- `live_migration_enabled` (Boolean) Allow live pod migration when applying recommendations
- `lookback_period_seconds` (Number) Per-rule override of the metrics lookback window in seconds. Unset inherits the team default (7 days). Minimum 3600 (1h), maximum 2592000 (30d); higher tiers may be capped server-side.
- `memory_rule` (Attributes) Memory vertical scaling rule configuration (see [below for nested schema](#nestedatt--memory_rule))
Expand Down Expand Up @@ -370,6 +410,84 @@ Optional:



<a id="nestedatt--jvm_heap_rule"></a>
### Nested Schema for `jvm_heap_rule`

Optional:

- `enabled` (Boolean) Enable JVM heap optimization
- `headroom_multiplier` (Number) Multiplier applied to the target heap usage to derive the recommended max heap
- `max_heap_bytes` (Number) Maximum recommended max heap size in bytes
- `min_heap_bytes` (Number) Minimum recommended max heap size in bytes
- `non_heap_overhead_bytes` (Number) Non-heap memory overhead in bytes, added on top of non_heap_overhead_percent
- `non_heap_overhead_percent` (Number) Non-heap memory overhead as a percentage of heap size
- `prefer_container_support` (Boolean) Prefer the JVM's own container-aware ergonomics (-XX:+UseContainerSupport) over an explicit -Xmx
- `target_percentile` (Number) Percentile of heap usage data used as the recommendation target (0-1)


<a id="nestedatt--keda_scaled_object"></a>
### Nested Schema for `keda_scaled_object`

Optional:

- `advanced` (Attributes) Advanced KEDA ScaledObject settings (see [below for nested schema](#nestedatt--keda_scaled_object--advanced))
- `cooldown_period` (Number) Seconds to wait after the last trigger reported active before scaling down to idle/min replicas
- `fallback` (Attributes) Replica fallback configuration when the scaler's metrics are unavailable (see [below for nested schema](#nestedatt--keda_scaled_object--fallback))
- `idle_replica_count` (Number) Number of replicas to scale down to when idle
- `initial_cooldown_period` (Number) Cooldown period applied only on initial ScaledObject creation
- `max_replica_count` (Number) Maximum number of replicas
- `min_replica_count` (Number) Minimum number of replicas
- `polling_interval` (Number) Seconds between checks of the trigger sources
- `triggers` (Attributes List) KEDA scale triggers (see [below for nested schema](#nestedatt--keda_scaled_object--triggers))

<a id="nestedatt--keda_scaled_object--advanced"></a>
### Nested Schema for `keda_scaled_object.advanced`

Optional:

- `advanced_behavior_json` (String) Opaque JSON-encoded Kubernetes `HorizontalPodAutoscalerBehavior`, carried through verbatim so this provider never has to re-model Kubernetes autoscaling types.
- `restore_to_original_replica_count` (Boolean) Restore the original replica count when the ScaledObject is deleted


<a id="nestedatt--keda_scaled_object--fallback"></a>
### Nested Schema for `keda_scaled_object.fallback`

Optional:

- `behavior` (String) Fallback strategy
- `failure_threshold` (Number) Number of consecutive metric failures before activating fallback
- `replicas` (Number) Number of replicas to fall back to when metrics are unavailable


<a id="nestedatt--keda_scaled_object--triggers"></a>
### Nested Schema for `keda_scaled_object.triggers`

Required:

- `type` (String) KEDA scaler type. Example: 'prometheus', 'cpu', 'kafka'

Optional:

- `authentication_ref` (Attributes) Reference to a KEDA TriggerAuthentication/ClusterTriggerAuthentication (see [below for nested schema](#nestedatt--keda_scaled_object--triggers--authentication_ref))
- `metadata` (Map of String) Scaler-specific metadata, as required by the chosen KEDA scaler type
- `metric_type` (String) Metric target type. One of: 'Value', 'AverageValue', 'Utilization'
- `name` (String) Trigger name
- `use_cached_metrics` (Boolean) Use KEDA's cached metrics for this trigger

<a id="nestedatt--keda_scaled_object--triggers--authentication_ref"></a>
### Nested Schema for `keda_scaled_object.triggers.authentication_ref`

Required:

- `name` (String) Name of the referenced authentication resource

Optional:

- `kind` (String) Kind of the referenced authentication resource. One of: 'TriggerAuthentication', 'ClusterTriggerAuthentication'




<a id="nestedatt--memory_rule"></a>
### Nested Schema for `memory_rule`

Expand Down
154 changes: 150 additions & 4 deletions examples/resources/devzero_node_policy/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ resource "devzero_node_policy" "aws_comprehensive" {
ami_selector_terms = [
{
alias = "al2023@latest"
},
{
# Resolve the AMI ID from an SSM public parameter instead of an alias
ssm_parameter = "/aws/service/eks/optimized-ami/1.29/amazon-linux-2/recommended/image_id"
}
]

Expand Down Expand Up @@ -153,11 +157,13 @@ resource "devzero_node_policy" "aws_comprehensive" {
block_device_mappings = [
{
device_name = "/dev/xvda"
root_volume = true
ebs = {
volume_size = "100Gi"
volume_type = "gp3"
encrypted = true
delete_on_termination = true
volume_size = "100Gi"
volume_type = "gp3"
encrypted = true
delete_on_termination = true
volume_initialization_rate = 100 # MiB/s to pre-warm the volume from its snapshot
}
}
]
Expand Down Expand Up @@ -260,3 +266,143 @@ resource "devzero_node_policy" "azure_example" {
}
}
}

# GCP example
resource "devzero_node_policy" "gcp_example" {
name = "gcp-production"
description = "Production-ready GCP node policy"
node_pool_name = "production-pool"
node_class_name = "production-class"
weight = 10

# GCP-only: select nodes by custom machine shape tokens
instance_shapes = {
match_expressions = [{
key = "instanceShapes"
operator = "In"
values = ["custom"]
}]
}

architectures = {
match_expressions = [{
key = "architectures"
operator = "In"
values = ["amd64"]
}]
}

capacity_types = {
match_expressions = [{
key = "capacityTypes"
operator = "In"
values = ["spot", "on-demand"]
}]
}

labels = {
"dedicated" = "karpenter"
}

disruption = {
consolidate_after = "5m"
consolidation_policy = "WhenEmptyOrUnderutilized"
expire_after = "168h" # 7 days
}

# GCP-specific configuration
gcp = {
service_account = "karpenter@my-project.iam.gserviceaccount.com"

image_selector_terms = [
{
alias = "ubuntu-2204-lts"
}
]
image_family = "ubuntu"

labels = {
"environment" = "production"
}
network_tags = ["allow-ssh", "allow-health-checks"]

disks = [
{
size_gib = 100
category = "pd-ssd"
boot = true
}
]

kubelet = {
max_pods = 110
}
}
}

# OCI example
resource "devzero_node_policy" "oci_example" {
name = "oci-production"
description = "Production-ready OCI node policy"
node_pool_name = "production-pool"
node_class_name = "production-class"
weight = 10

architectures = {
match_expressions = [{
key = "architectures"
operator = "In"
values = ["amd64"]
}]
}

disruption = {
consolidate_after = "5m"
consolidation_policy = "WhenEmptyOrUnderutilized"
expire_after = "168h" # 7 days
}

# OCI-specific configuration
oci = {
vcn_id = "ocid1.vcn.oc1..aaaaaaaaexample"

image_selector = [
{
name = "Oracle-Linux-8.9-2024.05.15-0"
}
]
image_family = "oracle-linux-8"

subnet_selector = [
{
name = "production-subnet"
}
]
security_group_selector = [
{
name = "production-node-sg"
}
]

free_form_tags = {
"Environment" = "production"
}

boot_config = {
boot_volume_size_in_gbs = 100
boot_volume_vpus_per_gb = 10
}

launch_options = {
boot_volume_type = "PARAVIRTUALIZED"
is_consistent_volume_naming_enabled = true
}

block_devices = [
{
size_in_gbs = 50
vpus_per_gb = 10
}
]
}
}
8 changes: 8 additions & 0 deletions examples/resources/devzero_workload_policy/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,12 @@ resource "devzero_workload_policy" "cost_saving" {

enable_pmax_protection = true # guard against spike-induced OOMKills
pmax_ratio_threshold = 3 # raise requests when peak is 3× the recommendation

emergency_response = {
oom_enabled = true
oom_memory_multiplier = 1.5
cpu_throttling_enabled = true
cpu_throttling_threshold = 0.20
cpu_throttling_multiplier = 1.25
}
}
Loading
Loading