Redshift clusters should have enhanced VPC routing enabled
Without enhanced VPC routing, Redshift COPY and UNLOAD commands may route traffic over the public internet to reach S3, DynamoDB, or other AWS services. This bypasses your VPC-level controls entirely, meaning security groups, network ACLs, and VPC endpoints have no effect on that data path. VPC flow logs also cannot capture this traffic, creating a blind spot for monitoring and forensics.
Enabling enhanced VPC routing gives you full visibility and control over data movement. You can restrict egress to specific S3 VPC endpoints, block unintended destinations at the network layer, and capture flow logs for every byte transferred. The performance cost is negligible for most workloads, and for any environment handling sensitive data, the tradeoff is not worth skipping.
Retrofit consideration
Enabling enhanced VPC routing on an existing cluster requires a cluster modification that may cause brief unavailability. Verify that VPC endpoints for S3 and any other required services exist before enabling, or COPY/UNLOAD commands will fail once traffic is forced through the VPC.
Implementation
Choose the approach that matches how you manage Terraform.
Use the compliance.tf module to enforce this control by default. See get started with compliance.tf.
module "redshift" {
source = "pcidss.compliance.tf/terraform-aws-modules/redshift/aws"
version = ">=7.0.0,<8.0.0"
automated_snapshot_retention_period = 7
cluster_identifier = "abc123"
create_cloudwatch_log_group = true
database_name = "mydb"
logging = {
log_destination_type = "cloudwatch"
log_exports = ["connectionlog", "userlog", "useractivitylog"]
}
master_password_wo = "change-me-in-production"
master_username = "admin"
node_type = "ra3.xlplus"
number_of_nodes = 2
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
vpc_security_group_ids = ["sg-12345678"]
}
module "redshift" {
source = "hipaa.compliance.tf/terraform-aws-modules/redshift/aws"
version = ">=7.0.0,<8.0.0"
automated_snapshot_retention_period = 7
cluster_identifier = "abc123"
create_cloudwatch_log_group = true
database_name = "mydb"
logging = {
log_destination_type = "cloudwatch"
log_exports = ["connectionlog", "userlog", "useractivitylog"]
}
master_password_wo = "change-me-in-production"
master_username = "admin"
node_type = "ra3.xlplus"
number_of_nodes = 2
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
vpc_security_group_ids = ["sg-12345678"]
}
module "redshift" {
source = "nist80053.compliance.tf/terraform-aws-modules/redshift/aws"
version = ">=7.0.0,<8.0.0"
automated_snapshot_retention_period = 7
cluster_identifier = "abc123"
create_cloudwatch_log_group = true
database_name = "mydb"
logging = {
log_destination_type = "cloudwatch"
log_exports = ["connectionlog", "userlog", "useractivitylog"]
}
master_password_wo = "change-me-in-production"
master_username = "admin"
node_type = "ra3.xlplus"
number_of_nodes = 2
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
vpc_security_group_ids = ["sg-12345678"]
}
module "redshift" {
source = "nistcsf.compliance.tf/terraform-aws-modules/redshift/aws"
version = ">=7.0.0,<8.0.0"
automated_snapshot_retention_period = 7
cluster_identifier = "abc123"
create_cloudwatch_log_group = true
database_name = "mydb"
logging = {
log_destination_type = "cloudwatch"
log_exports = ["connectionlog", "userlog", "useractivitylog"]
}
master_password_wo = "change-me-in-production"
master_username = "admin"
node_type = "ra3.xlplus"
number_of_nodes = 2
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
vpc_security_group_ids = ["sg-12345678"]
}
module "redshift" {
source = "nist800171.compliance.tf/terraform-aws-modules/redshift/aws"
version = ">=7.0.0,<8.0.0"
automated_snapshot_retention_period = 7
cluster_identifier = "abc123"
create_cloudwatch_log_group = true
database_name = "mydb"
logging = {
log_destination_type = "cloudwatch"
log_exports = ["connectionlog", "userlog", "useractivitylog"]
}
master_password_wo = "change-me-in-production"
master_username = "admin"
node_type = "ra3.xlplus"
number_of_nodes = 2
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
vpc_security_group_ids = ["sg-12345678"]
}
module "redshift" {
source = "ffiec.compliance.tf/terraform-aws-modules/redshift/aws"
version = ">=7.0.0,<8.0.0"
automated_snapshot_retention_period = 7
cluster_identifier = "abc123"
create_cloudwatch_log_group = true
database_name = "mydb"
logging = {
log_destination_type = "cloudwatch"
log_exports = ["connectionlog", "userlog", "useractivitylog"]
}
master_password_wo = "change-me-in-production"
master_username = "admin"
node_type = "ra3.xlplus"
number_of_nodes = 2
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
vpc_security_group_ids = ["sg-12345678"]
}
module "redshift" {
source = "acscism2023.compliance.tf/terraform-aws-modules/redshift/aws"
version = ">=7.0.0,<8.0.0"
automated_snapshot_retention_period = 7
cluster_identifier = "abc123"
create_cloudwatch_log_group = true
database_name = "mydb"
logging = {
log_destination_type = "cloudwatch"
log_exports = ["connectionlog", "userlog", "useractivitylog"]
}
master_password_wo = "change-me-in-production"
master_username = "admin"
node_type = "ra3.xlplus"
number_of_nodes = 2
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
vpc_security_group_ids = ["sg-12345678"]
}
module "redshift" {
source = "cfrpart11.compliance.tf/terraform-aws-modules/redshift/aws"
version = ">=7.0.0,<8.0.0"
automated_snapshot_retention_period = 7
cluster_identifier = "abc123"
create_cloudwatch_log_group = true
database_name = "mydb"
logging = {
log_destination_type = "cloudwatch"
log_exports = ["connectionlog", "userlog", "useractivitylog"]
}
master_password_wo = "change-me-in-production"
master_username = "admin"
node_type = "ra3.xlplus"
number_of_nodes = 2
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
vpc_security_group_ids = ["sg-12345678"]
}
module "redshift" {
source = "nistcsfv11.compliance.tf/terraform-aws-modules/redshift/aws"
version = ">=7.0.0,<8.0.0"
automated_snapshot_retention_period = 7
cluster_identifier = "abc123"
create_cloudwatch_log_group = true
database_name = "mydb"
logging = {
log_destination_type = "cloudwatch"
log_exports = ["connectionlog", "userlog", "useractivitylog"]
}
master_password_wo = "change-me-in-production"
master_username = "admin"
node_type = "ra3.xlplus"
number_of_nodes = 2
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
vpc_security_group_ids = ["sg-12345678"]
}
If you use terraform-aws-modules/redshift/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.
module "redshift" {
source = "terraform-aws-modules/redshift/aws"
version = ">=7.0.0,<8.0.0"
automated_snapshot_retention_period = 7
cluster_identifier = "abc123"
create_cloudwatch_log_group = true
database_name = "mydb"
logging = {
log_destination_type = "cloudwatch"
log_exports = ["connectionlog", "userlog", "useractivitylog"]
}
master_password_wo = "change-me-in-production"
master_username = "admin"
node_type = "ra3.xlplus"
number_of_nodes = 2
subnet_ids = ["subnet-12345678", "subnet-12345678", "subnet-12345678"]
vpc_id = "vpc-12345678"
vpc_security_group_ids = ["sg-12345678"]
enhanced_vpc_routing = true
}
Use AWS provider resources directly. See docs for the resources involved: aws_redshift_cluster.
resource "aws_redshift_cluster" "this" {
automated_snapshot_retention_period = 7
cluster_identifier = "pofix-abc123"
cluster_subnet_group_name = "example-redshift-subnet-group"
master_password = "ChangeMe123!"
master_username = "admin"
node_type = "ra3.large"
skip_final_snapshot = true
enhanced_vpc_routing = true
}
What this control checks
The control checks that aws_redshift_cluster has enhanced_vpc_routing set to true. The argument defaults to false, so clusters that omit it or explicitly set it to false fail. Every aws_redshift_cluster resource definition needs enhanced_vpc_routing = true to pass. No additional resources are required for this check, but in practice you should ensure VPC endpoints (an S3 gateway endpoint via aws_vpc_endpoint, at minimum) exist in the cluster's VPC before enabling, or COPY and UNLOAD operations will fail.
Common pitfalls
Missing VPC endpoints cause COPY/UNLOAD failures
Enabling
enhanced_vpc_routingwithout a corresponding S3 VPC gateway endpoint (aws_vpc_endpointwithservice_name = "com.amazonaws.<region>.s3") in the cluster's VPC will cause COPY and UNLOAD commands targeting S3 to fail. Every destination service needs a valid VPC path. This is the most common production incident when retrofitting this setting.Default value is false
The
enhanced_vpc_routingargument defaults tofalseonaws_redshift_cluster. Omitting it leaves the cluster non-compliant. Terraform modules that wrap Redshift may not expose this argument at all, so check the module source before assuming anything.Subnet route tables must include endpoint routes
Use the correct route table association when creating VPC endpoints. If the endpoint is associated with a different route table than the one used by your Redshift subnets, traffic won't use the endpoint path even though the endpoint exists and
enhanced_vpc_routingis enabled.Cross-region COPY routing can break unexpectedly
Get this wrong and you won't notice until a cross-region COPY job fails in production. Enhanced VPC routing forces all COPY and UNLOAD traffic through VPC-managed paths, and cross-region access requires explicit routing and endpoint design for each target region. Validate and test before enabling on clusters with cross-region workloads.
Audit evidence
Auditors expect evidence that every in-scope Redshift cluster has enhanced VPC routing enabled. The primary artifact is the Config rule evaluation (typically redshift-enhanced-vpc-routing-enabled) showing all clusters as COMPLIANT. Console screenshots of the cluster configuration tab displaying 'Enhanced VPC routing: Enabled' are also accepted. Security Hub findings or a CSPM dashboard showing passing status for this check across all accounts and regions works as continuous assurance evidence.
Supplementary evidence includes VPC flow logs showing Redshift COPY/UNLOAD traffic in the flow log records, confirming that traffic traverses the VPC rather than routing externally.
Framework-specific interpretation
PCI DSS v4.0: For environments storing or processing cardholder data in Redshift, Requirement 1 expects network security controls on every path that data travels. Without enhanced VPC routing, COPY/UNLOAD traffic can skip the segments where your firewalls, security groups, and NACLs live. Requirement 7 benefits too: network-level access restrictions only apply to traffic that actually passes through the VPC.
HIPAA Omnibus Rule 2013: Under 45 CFR 164.312(e)(1), covered entities must implement technical controls to guard ePHI in transit. Without enhanced VPC routing, COPY and UNLOAD operations carrying ePHI can bypass the VPC entirely, undermining network-layer encryption enforcement and audit logging. Routing that traffic through the VPC is one way to satisfy the transmission security standard.
NIST SP 800-53 Rev 5: SC-7 (Boundary Protection) and AC-4 (Information Flow Enforcement) both apply here. Forcing Redshift data traffic through the VPC boundary enables network policy enforcement and flow log monitoring, and prevents data from crossing uncontrolled network paths.
NIST Cybersecurity Framework v2.0: Redshift COPY and UNLOAD traffic becomes visible to VPC flow logs and subject to security group and NACL controls only when enhanced VPC routing is on. That visibility and enforceability is what PR.DS (Data Security) and PR.PS (Platform Security) call for.
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
redshift_cluster_enhanced_vpc_routing_enabledAWS Config Managed Rule:
REDSHIFT_ENHANCED_VPC_ROUTING_ENABLEDCheckov Check:
CKV_AWS_321Powerpipe Control:
aws_compliance.control.redshift_cluster_enhanced_vpc_routing_enabledProwler Check:
redshift_cluster_enhanced_vpc_routingAWS Security Hub Control:
Redshift.7
Last reviewed: 2026-03-09