WAF-SUS-040 โ€“ Idle & Underutilized Resource Elimination

Description

All cloud compute resources MUST be continuously monitored for utilization. Resources with CPU utilization below 5% for 14 consecutive days MUST be flagged as idle and subject to a stop/terminate review. Non-production environments MUST have scheduled shutdown policies (evenings and weekends). Autoscaling groups MUST be configured for all stateless compute workloads to eliminate idle capacity during off-peak hours. EC2 instances with persistent idle state MUST be converted to spot instances, reserved capacity, or terminated.

Rationale

Risk Description

Risk

Security incidents go undetected without centralised, tamper-proof audit logs.

Risk

Forensic investigations are delayed or inconclusive when logs are missing.

Requirements

  • All cloud compute resources MUST be continuously monitored for utilization.

  • Resources with CPU utilization below 5% for 14 consecutive days MUST be flagged as idle and subject to a stop/terminate review.

  • Non-production environments MUST have scheduled shutdown policies (evenings and weekends).

  • Autoscaling groups MUST be configured for all stateless compute workloads to eliminate idle capacity during off-peak hours.

  • EC2 instances with persistent idle state MUST be converted to spot instances, reserved capacity, or terminated.

Implementation Guidance

  1. Document the requirement in a version-controlled policy or standard.

  2. Assign ownership and establish a review cadence (e.g., quarterly).

  3. 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-sus-040.tf.aws.autoscaling-enabled

Engine: terraform | Provider: aws | Automated: Yes

AWS autoscaling groups must have scale-in enabled to eliminate idle capacity

Autoscaling groups must have scale-in policies defined to reduce capacity during low utilization periods. Scale-in protection should not be enabled on all instances as it prevents idle capacity from being terminated.

Scope: resource โ€” aws_autoscaling_group

Assertions: * min_size attribute exists โ€” Autoscaling group has no min_size defined. * max_size attribute exists โ€” Autoscaling group has no max_size defined.

Remediation: Configure autoscaling groups with target tracking scaling policies based on CPU or request count. Set min_size to 0 for non-production environments to allow complete scale-in during off hours. Use predictive scaling for production to balance performance and sustainability.

Compliant
resource "aws_autoscaling_group" "app" {
  name                = "app-asg"
  min_size            = 0  # scale to zero in off-peak
  max_size            = 10
  desired_capacity    = 2
  vpc_zone_identifier = var.private_subnets

  mixed_instances_policy {
    instances_distribution {
      on_demand_base_capacity                  = 1
      on_demand_percentage_above_base_capacity = 20
      spot_allocation_strategy                 = "capacity-optimized"
    }
  }
}
Non-Compliant
resource "aws_autoscaling_group" "app" {
  name             = "app-asg"
  min_size         = 5  # WAF-SUS-040: high minimum prevents scale-in
  max_size         = 5  # fixed capacity, no scaling
  desired_capacity = 5
}

waf-sus-040.tf.aws.spot-instances-for-dev

Engine: terraform | Provider: aws | Automated: Yes

Non-production autoscaling groups should allow spot instances

Spot instances use the same physical hardware as on-demand instances but allow AWS to reclaim unused capacity. Using spot for non-production reduces demand for dedicated on-demand capacity, improving overall data center energy efficiency.

Scope: resource โ€” aws_autoscaling_group

Assertions: * mixed_instances_policy attribute exists โ€” Autoscaling group uses no mixed instances policy โ€“ missing opportunity for spot instance sustainability optimization.

Remediation: Add mixed_instances_policy with spot allocation for non-production environments. For production: use 20-40% spot on top of on-demand base capacity. For dev/test: use 100% spot with instance type diversification for resilience.

Compliant
resource "aws_autoscaling_group" "dev" {
  name = "dev-asg"

  mixed_instances_policy {
    instances_distribution {
      on_demand_base_capacity                  = 0
      on_demand_percentage_above_base_capacity = 0  # 100% spot for dev
      spot_allocation_strategy                 = "capacity-optimized"
    }
    launch_template {
      launch_template_specification {
        launch_template_id = aws_launch_template.app.id
      }
      override {
        instance_type = "t4g.medium"
      }
      override {
        instance_type = "t4g.large"
      }
    }
  }
}
Non-Compliant
resource "aws_autoscaling_group" "dev" {
  name             = "dev-asg"
  launch_template {
    id      = aws_launch_template.app.id
  }
  # WAF-SUS-040 Warning: no spot instances configured for dev environment
}

waf-sus-040.tf.google.managed-instance-group-autoscaler

Engine: terraform | Provider: google | Automated: Yes

GCP managed instance groups must have autoscaler configured

GCP managed instance groups without autoscalers run at fixed capacity, consuming energy proportionally regardless of actual load. Autoscalers allow scale-to-minimum during low utilization periods.

Scope: resource โ€” google_compute_autoscaler

Assertions: * autoscaling_policy attribute exists โ€” GCP autoscaler has no autoscaling policy defined. * autoscaling_policy.min_replicas attribute exists โ€” Autoscaler must have min_replicas defined to allow scale-in.

Remediation: Configure google_compute_autoscaler with CPU utilization target of 60-70% and set min_replicas = 0 for non-production. For production, set min_replicas = 1 and max_replicas based on peak load testing.

Compliant
resource "google_compute_autoscaler" "app" {
  name   = "app-autoscaler"
  zone   = var.zone
  target = google_compute_instance_group_manager.app.id

  autoscaling_policy {
    max_replicas    = 10
    min_replicas    = 0  # scale to zero for non-prod
    cooldown_period = 60

    cpu_utilization {
      target = 0.65
    }
  }
}
Non-Compliant
# google_compute_instance_group_manager with no autoscaler defined
# WAF-SUS-040 Violation: fixed capacity, no scale-in possible

waf-sus-040.tf.azurerm.autoscale-setting-exists

Engine: terraform | Provider: azurerm | Automated: Yes

Azure monitor autoscale settings must exist with scale rules

Azure compute resources must be continuously monitored for utilization. At least one azurerm_monitor_autoscale_setting must exist with profiles containing scale-out and scale-in rules to prevent idle over-provisioning.

Scope: resource โ€” azurerm_monitor_autoscale_setting

Assertions: * profile not empty โ€” Autoscale setting must contain at least one profile. * profile.rule not empty โ€” Autoscale profile must contain scale rules for utilization-based scaling.

Remediation: Add an azurerm_monitor_autoscale_setting resource linked to VM scale sets or app service plans with profile capacity limits and metric-based scale rules.

Compliant
resource "azurerm_monitor_autoscale_setting" "workers" {
  name                = "worker-autoscale"
  target_resource_id  = azurerm_linux_virtual_machine_scale_set.workers.id
  location            = "germanywestcentral"
  profile {
    name = "defaultProfile"
    capacity {
      default = 2
      minimum = 1
      maximum = 10
    }
    rule {
      metric_trigger {
        metric_name      = "Percentage CPU"
        operator         = "GreaterThan"
        threshold        = 75
        time_grain       = "PT1M"
        statistic        = "Average"
        time_window      = "PT5M"
        time_aggregation = "Average"
      }
      scale_action {
        direction = "Increase"
        type      = "ChangeCount"
        value     = "1"
        cooldown  = "PT1M"
      }
    }
  }
}
Non-Compliant
resource "azurerm_monitor_autoscale_setting" "workers" {
  name                = "worker-autoscale"
  target_resource_id  = azurerm_linux_virtual_machine_scale_set.workers.id
  location            = "germanywestcentral"
  # No profile or scale rules configured
}

Evidence

Kind Required Description

iac

Required

Terraform configuration implementing the control.

governance

Required

Policy, ADR, or standard documenting the requirement.

config

Optional

Cloud console or API output confirming runtime state.

Framework Controls

Green Software Foundation

* Hardware Efficiency โ€“ eliminate idle compute * Energy Efficiency โ€“ utilization-driven compute

EU CSRD (Corporate Sustainability Reporting Directive)

* ESRS E1 โ€“ Climate Change โ€“ resource efficiency measures

GHG Protocol

* Scope 3 Category 11 โ€“ reducing purchased cloud compute emissions

ISO 14001

* 6.1.2 โ€“ Environmental Aspects โ€“ resource consumption reduction * 8.1 โ€“ Operational planning and control