WAF-SOV-020 β Region Pinning Enforced (IaC)
Description
Deployments MUST be restricted to approved sovereign regions through policy-as-code and IaC guardrails. Region constraints must be technically enforcedβnot merely documented. Violations must be blocked in CI or flagged as critical policy exceptions requiring explicit documented approval.
Rationale
| Risk | Description |
|---|---|
Risk |
Data may leave approved jurisdictions and violate regulatory requirements. |
Risk |
Vendor lock-in reduces future portability and sovereignty options. |
Requirements
-
Deployments MUST be restricted to approved sovereign regions through policy-as-code and IaC guardrails.
-
Region constraints must be technically enforcedβnot merely documented.
-
Violations must be blocked in CI or flagged as critical policy exceptions requiring explicit documented approval.
Implementation Guidance
-
Implement the required configuration as code in Terraform or equivalent IaC.
-
Add an automated check to CI/CD so deviations are caught before deployment.
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-sov-020.tf.aws.provider-region-in-allowed-list
Engine: terraform | Provider: aws | Automated: Yes
AWS provider region must be explicitly set
Every AWS provider block must have a 'region' attribute explicitly set. Relying on AWS_DEFAULT_REGION environment variables or provider defaults is prohibited for sovereign workloads.
Scope: provider β aws
Assertions:
* region attribute exists β AWS provider block is missing an explicit 'region' attribute.
Remediation: Add 'region = var.aws_region' to all AWS provider blocks.
provider "aws" {
region = var.aws_region
}
provider "aws" {
# region sourced from AWS_DEFAULT_REGION β not sovereign-safe
}
waf-sov-020.tf.aws.region-variable-validation
Engine: terraform | Provider: aws | Automated: Yes
AWS region variable must have a validation constraint
Any Terraform variable whose name contains 'region' or 'location' must have a validation block to restrict values to the organization’s approved region list.
Scope: variable
Assertions:
* validation block exists β Region/location variable is missing a 'validation' block to restrict to approved values.
Remediation: Add a validation block to region variables that uses 'contains()' or 'startswith()' to restrict values to the approved list.
variable "aws_region" {
type = string
description = "AWS region for sovereign deployments"
default = "eu-central-1"
validation {
condition = contains(["eu-central-1", "eu-west-1", "eu-north-1"], var.aws_region)
error_message = "Must be an approved sovereign EU region."
}
}
variable "aws_region" {
type = string
default = "us-east-1"
# No validation β any region is accepted
}
waf-sov-020.tf.azurerm.location-variable-validation
Engine: terraform | Provider: azurerm | Automated: Yes
Azure location variable must have a validation constraint
Any Terraform variable whose name contains 'location' or 'region' for Azure must have a validation block restricting to approved Azure regions.
Scope: variable
Assertions:
* validation block exists β Azure location variable is missing a 'validation' block.
Remediation: Add a validation block restricting location to approved Azure sovereign regions.
variable "azure_location" {
type = string
default = "germanywestcentral"
validation {
condition = contains(
["germanywestcentral", "germanynorth", "westeurope", "northeurope", "switzerlandnorth"],
var.azure_location
)
error_message = "Azure location must be an approved sovereign region."
}
}
variable "azure_location" {
type = string
default = "eastus"
# No validation block
}
waf-sov-020.tf.google.region-variable-validation
Engine: terraform | Provider: google | Automated: Yes
GCP region variable must have a validation constraint
GCP region and location variables must have validation blocks restricting to approved European or sovereign GCP regions.
Scope: variable
Assertions:
* validation block exists β GCP region/location variable is missing a 'validation' block.
Remediation: Add a validation block restricting GCP region to approved sovereign values.
variable "gcp_region" {
type = string
default = "europe-west3"
validation {
condition = startswith(var.gcp_region, "europe-")
error_message = "Only European GCP regions are approved for sovereign workloads."
}
}
variable "gcp_region" {
type = string
default = "us-central1"
# No validation
}
waf-sov-020.tf.aws.no-hardcoded-non-sovereign-region
Engine: terraform | Provider: aws | Automated: Yes
No hardcoded non-sovereign AWS region in resource or provider blocks
Hardcoded AWS region strings referencing non-sovereign regions (e.g., us-east-1, ap-southeast-1) are forbidden in provider, resource, and data source blocks.
Scope: any Terraform block
Assertions:
* region not matches pattern ^(us-|ap-|sa-|ca-|me-|af-) β Hardcoded non-sovereign AWS region detected. Only EU/approved regions are permitted.
Remediation: Replace hardcoded region values with variable references that have validation constraints.
provider "aws" {
region = var.aws_region # validated to eu-central-1 or eu-west-1
}
provider "aws" {
region = "us-east-1" # Non-sovereign region hardcoded
}
waf-sov-020.tf.stackit.region-validation
Engine: terraform | Provider: stackit | Automated: Yes
StackIT region variable must have a validation constraint
StackIT project region variables must have validation blocks restricting to approved sovereign regions. StackIT regions include: eu-central-1 (Karlsruhe), eu-west-1 (Strasbourg).
Scope: variable
Assertions:
* validation block exists β StackIT region/location variable is missing a 'validation' block.
Remediation: Add a validation block restricting the StackIT region to approved sovereign values.
variable "stackit_region" {
type = string
default = "eu-central-1"
validation {
condition = contains(["eu-central-1", "eu-west-1"], var.stackit_region)
error_message = "StackIT region must be an approved sovereign region."
}
}
provider "stackit" {
region = var.stackit_region
}
variable "stackit_region" {
type = string
default = "us-east-1"
# No validation block
}
waf-sov-020.tf.ovh.location-validation
Engine: terraform | Provider: ovh | Automated: Yes
OVH location variable must have a validation constraint
OVH project location variables must have validation blocks restricting to approved sovereign regions. OVH regions include: DE-FRA (Frankfurt), DE-EDE (Ede), EU-CY (Cyprus).
Scope: variable
Assertions:
* validation block exists β OVH location variable is missing a 'validation' block.
Remediation: Add a validation block restricting OVH location to approved sovereign regions.
variable "ovh_location" {
type = string
default = "DE-FRA"
validation {
condition = contains(["DE-FRA", "DE-EDE", "EU-CY"], var.ovh_location)
error_message = "OVH location must be an approved sovereign region."
}
}
provider "ovh" {
endpoint = "ovh-eu"
}
variable "ovh_location" {
type = string
default = "US-CA"
# No validation block
}
waf-sov-020.tf.hcloud.location-validation
Engine: terraform | Provider: hcloud | Automated: Yes
Hetzner Cloud location variable must have a validation constraint
Hetzner Cloud location variables must have validation blocks restricting to approved sovereign regions. Hetzner regions include: fsn1 (Frankfurt), nbg1 (Nuremberg), hel1 (Helsinki).
Scope: variable
Assertions:
* validation block exists β Hetzner Cloud location variable is missing a 'validation' block.
Remediation: Add a validation block restricting Hetzner Cloud location to approved sovereign regions.
variable "hcloud_location" {
type = string
default = "fsn1"
validation {
condition = contains(["fsn1", "nbg1", "hel1"], var.hcloud_location)
error_message = "Hetzner Cloud location must be an approved sovereign region."
}
}
resource "hcloud_server" "main" {
name = "sovereign-server"
server_type = "cx22"
location = var.hcloud_location
}
variable "hcloud_location" {
type = string
default = "us-ca"
# No validation block
}
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. |
Related Controls
| Framework | Controls |
|---|---|
GDPR |
* Art. 44 β General principle for transfers * Art. 46 β Transfers to third countries |
BSI C5:2020 |
* OPS-04 β Data management * INF-01 β Physical location |
BSI C3A:2026 |
* Dimension 4 β Data: Location of data processing * Dimension 1 β Strategic: Jurisdictional alignment |
EUCS (ENISA) |
* SOV-01 β Data location * SOV-02 β Jurisdiction control |
GAIA-X |
* Data Sovereignty β Location transparency |
ISO 27001:2022 |
* A.8.10 β Information deletion * A.5.29 β Information security during disruption |