WAF-PERF-090 โ Storage I/O Performance & Throughput Optimization
Description
All block storage (EBS, Azure Managed Disks, GCP Persistent Disk) and object storage used by production workloads MUST be configured with appropriate I/O performance settings (IOPS, throughput, storage class). Storage volumes MUST use the most cost-efficient performance tier for their workload. EBS volumes MUST use gp3 instead of gp2 for new deployments. Storage I/O performance MUST be monitored and alerts configured for throughput saturation and high queue depth.
Rationale
| Risk | Description |
|---|---|
Risk |
Slow or over-provisioned storage extends response times and increases cost. |
Risk |
Missing storage-tiering strategies prevent cost-efficient long-term archiving. |
Requirements
-
All block storage (EBS, Azure Managed Disks, GCP Persistent Disk) and object storage used by production workloads MUST be configured with appropriate I/O performance settings (IOPS, throughput, storage class).
-
Storage volumes MUST use the most cost-efficient performance tier for their workload.
-
EBS volumes MUST use gp3 instead of gp2 for new deployments.
-
Storage I/O performance MUST be monitored and alerts configured for throughput saturation and high queue depth.
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-090.tf.aws.ebs-gp3-volume-type
Engine: terraform | Provider: aws | Automated: Yes
AWS EBS volumes must use gp3 type instead of gp2
EBS volumes must use gp3 type for new deployments. gp3 provides baseline performance of 3000 IOPS and 125 MB/s throughput without burst mechanics, at 20% lower cost than gp2. gp2 volumes deplete burst credits under sustained load causing unpredictable performance.
Scope: resource โ aws_ebs_volume, aws_db_instance, aws_launch_template
Assertions:
* volume_type not equals gp2 โ EBS volume must not use gp2 type. Migrate to gp3 for consistent performance and lower cost.
* volume_type in ['gp3', 'io2'] โ EBS volume type must be explicitly set to gp3 or io2.
Remediation: Change volume_type from "gp2" to "gp3". For databases requiring higher IOPS, set explicit iops and throughput values on gp3 (max 16000 IOPS, 1000 MB/s). Migration from gp2 to gp3 is online and non-disruptive.
resource "aws_ebs_volume" "data" {
availability_zone = "eu-west-1a"
size = 100
type = "gp3"
iops = 6000 # Explicitly set above default 3000
throughput = 250 # Explicitly set above default 125 MB/s
encrypted = true
tags = {
Name = "data-payment-api"
workload = "payment-api"
}
}
resource "aws_ebs_volume" "data" {
availability_zone = "eu-west-1a"
size = 100
type = "gp2" # gp2 โ burst-dependent โ WAF-PERF-090 violation
# No explicit IOPS; subject to credit depletion
}
waf-perf-090.tf.azurerm.managed-disk-premium
Engine: terraform | Provider: azurerm | Automated: Yes
Azure Managed Disks for production database workloads should use Premium SSD
Azure Managed Disks used for database data volumes should use Premium SSD (P series) or Ultra Disk for high-IOPS workloads. Standard HDD or Standard SSD is inappropriate for production database storage.
Scope: resource โ azurerm_managed_disk
Assertions:
* storage_account_type not in ['Standard_LRS', 'StandardSSD_LRS'] โ Production database disks must use Premium_LRS or UltraSSD_LRS, not Standard or StandardSSD.
Remediation: Set storage_account_type = "Premium_LRS" for database data disks. Use UltraSSD_LRS for extremely latency-sensitive workloads requiring sub-millisecond I/O.
resource "azurerm_managed_disk" "db_data" {
name = "disk-db-payment-data"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
storage_account_type = "Premium_LRS"
create_option = "Empty"
disk_size_gb = 256
tags = {
workload = "payment-db"
tier = "data"
}
}
resource "azurerm_managed_disk" "db_data" {
name = "disk-db-payment-data"
storage_account_type = "Standard_LRS" # HDD for database โ WAF-PERF-090 advisory
create_option = "Empty"
disk_size_gb = 256
}
waf-perf-090.tf.google.persistent-disk-ssd
Engine: terraform | Provider: google | Automated: Yes
GCP Persistent Disks for production workloads should use SSD type
GCP Persistent Disks for production compute and database workloads should use pd-ssd or pd-balanced type, not pd-standard (HDD) which has high latency.
Scope: resource โ google_compute_disk
Assertions:
* type not equals pd-standard โ Production Persistent Disk must not use pd-standard (HDD). Use pd-ssd or pd-balanced.
Remediation: Set type = "pd-balanced" for general workloads or type = "pd-ssd" for high-IOPS databases. pd-extreme is available for ultra-high IOPS requirements.
resource "google_compute_disk" "db_data" {
name = "disk-payment-db-data"
type = "pd-ssd"
zone = "europe-west3-a"
size = 100
labels = {
workload = "payment-db"
}
}
resource "google_compute_disk" "db_data" {
name = "disk-payment-db-data"
type = "pd-standard" # HDD โ high latency for database โ WAF-PERF-090 advisory
zone = "europe-west3-a"
size = 100
}
waf-perf-090.tf.stackit.load-tested
Engine: terraform | Provider: stackit | Automated: Yes
All block storage (EBS, Azure Managed Disks, GCP Persistent Disk) and object… for stackit
All block storage (EBS, Azure Managed Disks, GCP Persistent Disk) and object… must be documented in IaC via a load-tested tag/label on stackit_project. This validates the control is tracked as code.
Scope: resource โ stackit_project
Assertions:
* labels key exists โ stackit_project is missing the load-tested tag/label.
Remediation: Add a load-tested tag/label to the stackit_project resource to show the stackit implementation of WAF-PERF-090 is tracked in IaC.
resource "stackit_project" "example" {
labels = {
load-tested = "true"
}
}
resource "stackit_project" "example" {
# Missing load-tested labels
}
waf-perf-090.tf.ovh.load-tested
Engine: terraform | Provider: ovh | Automated: Yes
All block storage (EBS, Azure Managed Disks, GCP Persistent Disk) and object… for ovh
All block storage (EBS, Azure Managed Disks, GCP Persistent Disk) and object… must be documented in IaC via a load-tested tag/label on ovh_cloud_project. This validates the control is tracked as code.
Scope: resource โ ovh_cloud_project
Assertions:
* tags key exists โ ovh_cloud_project is missing the load-tested tag/label.
Remediation: Add a load-tested tag/label to the ovh_cloud_project resource to show the ovh implementation of WAF-PERF-090 is tracked in IaC.
resource "ovh_cloud_project" "example" {
tags = {
load-tested = "true"
}
}
resource "ovh_cloud_project" "example" {
# Missing load-tested tags
}
waf-perf-090.tf.hcloud.load-tested
Engine: terraform | Provider: hcloud | Automated: Yes
All block storage (EBS, Azure Managed Disks, GCP Persistent Disk) and object… for hcloud
All block storage (EBS, Azure Managed Disks, GCP Persistent Disk) and object… must be documented in IaC via a load-tested tag/label on hcloud_server. This validates the control is tracked as code.
Scope: resource โ hcloud_server
Assertions:
* labels key exists โ hcloud_server is missing the load-tested tag/label.
Remediation: Add a load-tested tag/label to the hcloud_server resource to show the hcloud implementation of WAF-PERF-090 is tracked in IaC.
resource "hcloud_server" "example" {
labels = {
load-tested = "true"
}
}
resource "hcloud_server" "example" {
# Missing load-tested labels
}
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. |