WAF-PERF-020 โ Auto-Scaling Configured & Tested
Description
All stateless compute workloads handling variable or unpredictable traffic MUST have auto-scaling configured with appropriate minimum, desired, and maximum capacity thresholds. Auto-scaling policies MUST be based on meaningful metrics (CPU utilization, request latency, queue depth, or custom application metrics), not just time-based schedules. Auto-scaling configurations MUST be tested under realistic load conditions before production deployment and re-validated after significant architectural changes.
Rationale
| Risk | Description |
|---|---|
Risk |
Stateless workloads without autoscaling fail under load spikes or waste resources in troughs. |
Risk |
Missing scaling policies force manual intervention and extend downtime. |
Requirements
-
All stateless compute workloads handling variable or unpredictable traffic MUST have auto-scaling configured with appropriate minimum, desired, and maximum capacity thresholds.
-
Auto-scaling policies MUST be based on meaningful metrics (CPU utilization, request latency, queue depth, or custom application metrics), not just time-based schedules.
-
Auto-scaling configurations MUST be tested under realistic load conditions before production deployment and re-validated after significant architectural changes.
Implementation Guidance
-
Document the requirement in a version-controlled policy or standard.
-
Assign ownership and establish a review cadence (e.g., quarterly).
-
Implement the required configuration as code in Terraform or equivalent IaC.
Maturity Levels
| Level | Name | Criteria |
|---|---|---|
L1 |
Ad hoc โ control not consistently applied |
* Manual evidence exists for some workloads, but coverage is unknown. |
L2 |
Standardised โ policy defined and communicated |
* A version-controlled policy, ADR, or standard describes the requirement. |
L3 |
Integrated โ automated validation in CI/CD |
* Terraform checks run automatically on pull requests and report results. |
L4 |
Auditable โ metrics and exceptions tracked |
* Control coverage, failures, and approved exceptions are reported quarterly. |
L5 |
Optimised โ continuous improvement based on data |
* Control effectiveness is measured and iteratively improved. |
Checks
waf-perf-020.tf.aws.autoscaling-group-policy
Engine: terraform | Provider: aws | Automated: Yes
AWS Auto Scaling Groups must have scaling policies defined
AWS Auto Scaling Groups must have at minimum one scaling policy defined. Groups without scaling policies rely on manual scaling only and cannot respond to traffic changes automatically.
Scope: resource โ aws_autoscaling_group
Assertions:
* min_size greater than or equal 1 โ Auto Scaling Group min_size must be at least 1 to prevent cold starts in synchronous workloads.
* max_size greater than or equal 1 โ Auto Scaling Group max_size must be at least 2 to enable actual scaling.
* health_check_type not empty โ Auto Scaling Group must have health_check_type configured (EC2 or ELB).
Remediation: Add scaling policies to the Auto Scaling Group. At minimum, add target tracking scaling based on ALBRequestCountPerTarget or CPU utilization. Set min_size >= 1, max_size >= 2. Configure health checks to use ELB type for web applications.
resource "aws_autoscaling_group" "app" {
name = "asg-payment-api"
min_size = 2
max_size = 10
desired_capacity = 2
health_check_type = "ELB"
target_group_arns = [aws_lb_target_group.app.arn]
vpc_zone_identifier = var.private_subnet_ids
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
tag {
key = "workload"
value = "payment-api"
propagate_at_launch = true
}
}
resource "aws_autoscaling_policy" "scale_out" {
name = "payment-api-target-tracking"
autoscaling_group_name = aws_autoscaling_group.app.name
policy_type = "TargetTrackingScaling"
target_tracking_configuration {
predefined_metric_specification {
predefined_metric_type = "ALBRequestCountPerTarget"
resource_label = "${aws_lb.app.arn_suffix}/${aws_lb_target_group.app.arn_suffix}"
}
target_value = 1000.0
}
}
resource "aws_autoscaling_group" "app" {
name = "asg-payment-api"
min_size = 1
max_size = 1 # max == min, no scaling possible โ WAF-PERF-020 violation
desired_capacity = 1
# No scaling policy โ manual only
}
waf-perf-020.tf.azurerm.vmss-autoscale
Engine: terraform | Provider: azurerm | Automated: Yes
Azure VMSS must have autoscale settings configured
Azure Virtual Machine Scale Sets used for production workloads must have autoscale settings configured with at least one scale-out and one scale-in rule.
Scope: resource โ azurerm_monitor_autoscale_setting
Assertions:
* enabled is true โ Autoscale setting must be enabled.
* profile not empty โ Autoscale setting must have at least one profile configured.
Remediation: Enable autoscale settings for the VMSS. Configure at least one profile with scale-out and scale-in rules based on CPU percentage or custom metrics.
resource "azurerm_monitor_autoscale_setting" "app" {
name = "autoscale-payment-api"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
target_resource_id = azurerm_linux_virtual_machine_scale_set.app.id
enabled = true
profile {
name = "defaultProfile"
capacity {
default = 2
minimum = 2
maximum = 10
}
rule {
metric_trigger {
metric_name = "Percentage CPU"
metric_resource_id = azurerm_linux_virtual_machine_scale_set.app.id
time_grain = "PT1M"
statistic = "Average"
time_window = "PT5M"
time_aggregation = "Average"
operator = "GreaterThan"
threshold = 70
}
scale_action {
direction = "Increase"
type = "ChangeCount"
value = "1"
cooldown = "PT3M"
}
}
}
}
# No azurerm_monitor_autoscale_setting resource defined
# VMSS deployed with fixed capacity โ WAF-PERF-020 violation
resource "azurerm_linux_virtual_machine_scale_set" "app" {
instances = 2 # Static, no scaling
}
waf-perf-020.tf.google.managed-instance-group-autoscaler
Engine: terraform | Provider: google | Automated: Yes
GCP Managed Instance Groups must have autoscaler configured
GCP Managed Instance Groups used for production compute must have a google_compute_autoscaler resource configured with appropriate scaling policies.
Scope: resource โ google_compute_autoscaler, google_compute_region_autoscaler
Assertions:
* autoscaling_policy not empty โ Autoscaler must have autoscaling_policy defined with min and max replicas.
Remediation: Add a google_compute_autoscaler resource targeting the Managed Instance Group. Configure autoscaling_policy with appropriate min_replicas, max_replicas, and cpu_utilization target or load_balancing_utilization.
resource "google_compute_autoscaler" "app" {
name = "autoscaler-payment-api"
zone = "europe-west3-a"
target = google_compute_instance_group_manager.app.id
autoscaling_policy {
max_replicas = 10
min_replicas = 2
cooldown_period = 60
cpu_utilization {
target = 0.6
}
}
}
# No google_compute_autoscaler defined
resource "google_compute_instance_group_manager" "app" {
name = "igm-payment-api"
base_instance_name = "payment-api"
zone = "europe-west3-a"
# Static capacity, no autoscaler โ WAF-PERF-020 violation
}
waf-perf-020.tf.stackit.compute-sku-review
Engine: terraform | Provider: stackit | Automated: Yes
STACKIT compute resources must use a reviewed and sized SKU
STACKIT compute resources must use a reviewed and sized SKU. This check validates the Terraform configuration uses the expected resource and attribute.
Scope: resource โ stackit_server, stackit_ske_node_pool
Assertions:
* machine_type attribute exists โ STACKIT compute resource must specify a machine type.
Remediation: Review the Terraform configuration for the listed resource types and ensure the required attribute or tag is present. See the control narrative for provider-specific guidance.
# Example resource meets the requirement.
resource "stackit_server" "example" {
# required attribute/tag/label present
}
# Example resource does not meet the requirement.
resource "stackit_server" "example" {
# Missing required attribute/tag/label
}
waf-perf-020.tf.ovh.compute-flavor-review
Engine: terraform | Provider: ovh | Automated: Yes
OVHcloud compute resources must use a reviewed and sized flavor
OVHcloud compute resources must use a reviewed and sized flavor. This check validates the Terraform configuration uses the expected resource and attribute.
Scope: resource โ ovh_cloud_project_instance, ovh_vps, ovh_cloud_project_kube_nodepool
Assertions:
* flavor_name attribute exists โ OVHcloud compute resource must specify a flavor.
Remediation: Review the Terraform configuration for the listed resource types and ensure the required attribute or tag is present. See the control narrative for provider-specific guidance.
# Example resource meets the requirement.
resource "ovh_cloud_project_instance" "example" {
# required attribute/tag/label present
}
# Example resource does not meet the requirement.
resource "ovh_cloud_project_instance" "example" {
# Missing required attribute/tag/label
}
waf-perf-020.tf.hcloud.server-type-review
Engine: terraform | Provider: hcloud | Automated: Yes
Hetzner Cloud servers must use a reviewed and sized type
Hetzner Cloud servers must use a reviewed and sized type. This check validates the Terraform configuration uses the expected resource and attribute.
Scope: resource โ hcloud_server
Assertions:
* server_type attribute exists โ Hetzner Cloud server must specify a server type.
Remediation: Review the Terraform configuration for the listed resource types and ensure the required attribute or tag is present. See the control narrative for provider-specific guidance.
# Example resource meets the requirement.
resource "hcloud_server" "example" {
# required attribute/tag/label present
}
# Example resource does not meet the requirement.
resource "hcloud_server" "example" {
# Missing required attribute/tag/label
}
Evidence
| Kind | Required | Description |
|---|---|---|
|
Required |
Terraform configuration implementing the control. |
|
Required |
Policy, ADR, or standard documenting the requirement. |
|
Optional |
Cloud console or API output confirming runtime state. |