Skip to content

Redshift clusters should not use the default admin username

Default usernames are well-known and appear in AWS documentation, blog posts, and attack toolkits. An attacker who discovers a Redshift endpoint can immediately attempt authentication against "awsuser" without any enumeration effort. Changing the admin username adds a layer of ambiguity that forces credential guessing across both username and password dimensions.

This is a low-cost hardening measure. There is no operational reason to keep the default.

Retrofit consideration

Changing master_username on an existing aws_redshift_cluster forces cluster replacement: downtime, snapshot restore, and updated connection strings across all consuming applications. Test the migration path in a lower environment before scheduling production maintenance.

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  = "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"]
}

module "redshift" {
  source  = "pcidssv321.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"]
}

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
}

What this control checks

In the aws_redshift_cluster resource, master_username must be set to a value other than "awsuser". Any non-empty string that differs passes. If master_username is omitted, Terraform requires it for new clusters, but some import workflows may leave it unset, causing drift. Setting a custom value such as "redshift_admin" or a name that incorporates the environment satisfies this control. The check is a simple string comparison: "awsuser" fails, everything else passes.

Common pitfalls

  • Changing master_username destroys and recreates the cluster

    The master_username argument is marked ForceNew in the AWS provider. Any change triggers a full cluster replacement, not an in-place update. For production clusters with large datasets, that can mean hours of downtime during snapshot restore. Plan this change as a blue-green migration, not a routine Terraform apply.

  • Hardcoded usernames in application config

    Before changing the username, audit every consumer: Secrets Manager secrets, SSM Parameter Store entries, environment variables, and any IAM policy conditions that reference the username directly. Changing the username without updating downstream references breaks connectivity immediately.

  • Snapshot restores keep snapshot credentials

    Restoring from a snapshot via snapshot_identifier pulls credentials from the snapshot context, not from the master_username argument in your Terraform config. A cluster restored from a snapshot that used "awsuser" continues using it regardless of what the code says. The only remediation is a planned cluster replacement or data migration to a new cluster provisioned with a different admin username.

Audit evidence

An auditor expects to see each Redshift cluster's MasterUsername confirmed as something other than "awsuser", via aws redshift describe-clusters output or the Redshift console cluster detail view. If using AWS Config or a CSPM platform, this typically requires a custom rule and should show compliant status for all in-scope clusters. Security Hub findings or third-party CSPM tool results are also valid when mapped to this check.

Framework-specific interpretation

NIST Cybersecurity Framework v1.1: PR.AC-1 under the Protect function expects credentials and accounts to be managed in ways that limit unauthorized access. Keeping "awsuser" as the admin name hands attackers half the credential with no enumeration effort; a custom username forces guessing across both dimensions.

Tool mappings

Use these identifiers to cross-reference this control across tools, reports, and evidence.

  • Compliance.tf Control: redshift_cluster_no_default_admin_name

  • AWS Config Managed Rule: REDSHIFT_DEFAULT_ADMIN_CHECK

  • Checkov Check: CKV_AWS_391

  • Powerpipe Control: aws_compliance.control.redshift_cluster_no_default_admin_name

  • Prowler Check: redshift_cluster_non_default_username

  • AWS Security Hub Controls: Redshift.8, RedshiftServerless.5

Last reviewed: 2026-03-09