AWS Redshift Terraform module

January 8, 2026 ยท View on GitHub

Terraform module which creates Redshift resources on AWS.

SWUbanner

Usage

module "redshift" {
  source  = "terraform-aws-modules/redshift/aws"

  cluster_identifier    = "example"
  allow_version_upgrade = true
  node_type             = "ra3.xlplus"
  number_of_nodes       = 3

  database_name   = "mydb"
  master_username = "mydbuser"

  manage_master_password                       = true
  manage_master_password_rotation              = true
  master_password_rotation_schedule_expression = "rate(90 days)"

  encrypted   = true
  kms_key_arn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"

  vpc_id                               = "vpc-1234556abcdef"
  enhanced_vpc_routing                 = true
  availability_zone_relocation_enabled = true

  snapshot_copy = {
    destination_region = "us-east-1"
    grant_name         = "example-grant"
  }

  logging = {
    bucket_name   = "my-s3-log-bucket"
    s3_key_prefix = "example/"
  }

  # Parameter group
  parameter_group_name        = "example-custom"
  parameter_group_description = "Custom parameter group for example cluster"
  parameter_group_parameters = {
    wlm_json_configuration = {
      name = "wlm_json_configuration"
      value = jsonencode([
        {
          query_concurrency = 15
        }
      ])
    }
    require_ssl = {
      name  = "require_ssl"
      value = true
    }
    use_fips_ssl = {
      name  = "use_fips_ssl"
      value = false
    }
    enable_user_activity_logging = {
      name  = "enable_user_activity_logging"
      value = true
    }
    max_concurrency_scaling_clusters = {
      name  = "max_concurrency_scaling_clusters"
      value = 3
    }
    enable_case_sensitive_identifier = {
      name  = "enable_case_sensitive_identifier"
      value = true
    }
  }
  parameter_group_tags = {
    Additional = "CustomParameterGroup"
  }

  # Subnet group
  subnet_group_name        = "example-custom"
  subnet_group_description = "Custom subnet group for example cluster"
  subnet_ids               = ["subnet-123456", "subnet-654321"]
  subnet_group_tags = {
    Additional = "CustomSubnetGroup"
  }

  # Snapshot schedule
  snapshot_schedule = {
    identifier    = "example"
    use_prefix    = true
    description   = "Example snapshot schedule"
    definitions   = ["rate(12 hours)"]
    force_destroy = true
  }

  # Scheduled actions
  create_scheduled_action_iam_role = true
  scheduled_actions = {
    pause = {
      name          = "example-pause"
      description   = "Pause cluster every night"
      schedule      = "cron(0 22 * * ? *)"
      target_action = {
        pause_cluster = true
      }
    }
    resize = {
      name        = "example-resize"
      description = "Resize cluster (demo only)"
      schedule    = "cron(00 13 * * ? *)"
      target_action = {
        resize_cluster = {
          node_type       = "ds2.xlarge"
          number_of_nodes = 5
        }
      }
    }
    resume = {
      name           = "example-resume"
      description    = "Resume cluster every morning"
      schedule       = "cron(0 12 * * ? *)"
      target_action = {
        resume_cluster = true
      }
    }
  }

  # Endpoint access
  endpoint_access = {
    example = {
      name                   = "example-example"
      subnet_group_name      = "example-subnet-group"
      vpc_security_group_ids = ["sg-12345678"]
    }
  }

  # Usage limits
  usage_limits = {
    currency_scaling = {
      feature_type  = "concurrency-scaling"
      limit_type    = "time"
      amount        = 60
      breach_action = "emit-metric"
    }
    spectrum = {
      feature_type  = "spectrum"
      limit_type    = "data-scanned"
      amount        = 2
      breach_action = "disable"
      tags = {
        Additional = "CustomUsageLimits"
      }
    }
  }

  # Authentication profile
  authentication_profiles = {
    example = {
      name = "example"
      content = {
        AllowDBUserOverride = "1"
        Client_ID           = "ExampleClientID"
        App_ID              = "example"
      }
    }
    bar = {
      content = {
        AllowDBUserOverride = "1"
        Client_ID           = "ExampleClientID"
        App_ID              = "bar"
      }
    }
  }

  tags = {
    Environment = "dev"
    Terraform   = "true"
  }
}

Examples

Requirements

NameVersion
terraform>= 1.11
aws>= 6.27

Providers

NameVersion
aws>= 6.27

Modules

No modules.

Resources

NameType
aws_cloudwatch_log_group.thisresource
aws_iam_role.scheduled_actionresource
aws_iam_role_policy.scheduled_actionresource
aws_redshift_authentication_profile.thisresource
aws_redshift_cluster.thisresource
aws_redshift_cluster_iam_roles.thisresource
aws_redshift_endpoint_access.thisresource
aws_redshift_logging.thisresource
aws_redshift_parameter_group.thisresource
aws_redshift_scheduled_action.thisresource
aws_redshift_snapshot_copy.thisresource
aws_redshift_snapshot_schedule.thisresource
aws_redshift_snapshot_schedule_association.thisresource
aws_redshift_subnet_group.thisresource
aws_redshift_usage_limit.thisresource
aws_secretsmanager_secret_rotation.thisresource
aws_security_group.thisresource
aws_vpc_security_group_egress_rule.thisresource
aws_vpc_security_group_ingress_rule.thisresource
aws_iam_policy_document.scheduled_actiondata source
aws_iam_policy_document.scheduled_action_assumedata source
aws_service_principal.scheduler_redshiftdata source

Inputs

NameDescriptionTypeDefaultRequired
allow_version_upgradeIf true, major version upgrades can be applied during the maintenance window to the Amazon Redshift engine that is running on the cluster. Default is trueboolnullno
apply_immediatelySpecifies whether any cluster modifications are applied immediately, or during the next maintenance window. Default is falseboolnullno
authentication_profilesMap of authentication profiles to create
map(object({
name = optional(string) # Will fall back to key if not set
content = any
}))
{}no
automated_snapshot_retention_periodThe number of days that automated snapshots are retained. If the value is 0, automated snapshots are disabled. Even if automated snapshots are disabled, you can still create manual snapshots when you want with create-cluster-snapshot. Default is 1numbernullno
availability_zoneThe EC2 Availability Zone (AZ) in which you want Amazon Redshift to provision the cluster. Can only be changed if availability_zone_relocation_enabled is truestringnullno
availability_zone_relocation_enabledIf true, the cluster can be relocated to another availability zone, either automatically by AWS or when requested. Default is false. Available for use on clusters from the RA3 instance familyboolnullno
cloudwatch_log_group_kms_key_idThe ARN of the KMS Key to use when encrypting log datastringnullno
cloudwatch_log_group_retention_in_daysThe number of days to retain CloudWatch logs for the redshift clusternumber0no
cloudwatch_log_group_skip_destroySet to true if you do not wish the log group (and any logs it may contain) to be deleted at destroy time, and instead just remove the log group from the Terraform stateboolnullno
cloudwatch_log_group_tagsAdditional tags to add to cloudwatch log groups createdmap(string){}no
cluster_identifierThe Cluster Identifier. Must be a lower case stringstring""no
cluster_timeoutsCreate, update, and delete timeout configurations for the cluster
object({
create = optional(string)
update = optional(string)
delete = optional(string)
})
nullno
cluster_versionThe version of the Amazon Redshift engine software that you want to deploy on the cluster. The version selected runs on all the nodes in the clusterstringnullno
createDetermines whether to create Redshift cluster and resources (affects all resources)booltrueno
create_cloudwatch_log_groupDetermines whether a CloudWatch log group is created for each var.logging.log_exportsboolfalseno
create_parameter_groupDetermines whether to create a parameter group or use existingbooltrueno
create_scheduled_action_iam_roleDetermines whether a scheduled action IAM role is createdboolfalseno
create_security_groupDetermines whether to create security group for Redshift clusterbooltrueno
create_subnet_groupDetermines whether to create a subnet group or use existingbooltrueno
database_nameThe name of the first database to be created when the cluster is created. If you do not provide a name, Amazon Redshift will create a default database called devstringnullno
default_iam_role_arnThe Amazon Resource Name (ARN) for the IAM role that was set as default for the cluster when the cluster was createdstringnullno
elastic_ipThe Elastic IP (EIP) address for the clusterstringnullno
encryptedIf true, the data in the cluster is encrypted at restboolnullno
endpoint_accessMap of endpoint access (managed VPC endpoint) definitions to create
map(object({
name = optional(string) # Will fall back to key if not set
resource_owner = optional(string)
subnet_group_name = string
vpc_security_group_ids = optional(list(string))
}))
{}no
enhanced_vpc_routingIf true, enhanced VPC routing is enabledboolnullno
final_snapshot_identifierThe identifier of the final snapshot that is to be created immediately before deleting the cluster. If this parameter is provided, skip_final_snapshot must be falsestringnullno
iam_role_arnsA list of IAM Role ARNs to associate with the cluster. A Maximum of 10 can be associated to the cluster at any timelist(string)[]no
iam_role_descriptionDescription of the scheduled action IAM rolestringnullno
iam_role_nameName to use on scheduled action IAM role createdstringnullno
iam_role_pathScheduled action IAM role pathstringnullno
iam_role_permissions_boundaryARN of the policy that is used to set the permissions boundary for the scheduled action IAM rolestringnullno
iam_role_tagsA map of additional tags to add to the scheduled action IAM role createdmap(string){}no
iam_role_use_name_prefixDetermines whether scheduled action the IAM role name (iam_role_name) is used as a prefixstringtrueno
kms_key_arnThe ARN for the KMS encryption key. When specifying kms_key_arn, encrypted needs to be set to truestringnullno
loggingLogging configuration for the cluster
object({
bucket_name = optional(string)
log_destination_type = optional(string)
log_exports = optional(list(string))
s3_key_prefix = optional(string)
})
nullno
maintenance_track_nameThe name of the maintenance track for the restored cluster. When you take a snapshot, the snapshot inherits the MaintenanceTrack value from the cluster. The snapshot might be on a different track than the cluster that was the source for the snapshot. Default value is currentstringnullno
manage_master_passwordWhether to use AWS SecretsManager to manage the cluster admin credentials. Conflicts with master_password_wo. One of master_password_wo or manage_master_password is required unless snapshot_identifier is providedbooltrueno
manage_master_password_rotationWhether to manage the master user password rotation. Setting this value to false after previously having been set to true will disable automatic rotationboolfalseno
manual_snapshot_retention_periodThe default number of days to retain a manual snapshot. If the value is -1, the snapshot is retained indefinitely. This setting doesn't change the retention period of existing snapshots. Valid values are between -1 and 3653. Default value is -1numbernullno
master_password_rotate_immediatelySpecifies whether to rotate the secret immediately or wait until the next scheduled rotation windowboolnullno
master_password_rotation_automatically_after_daysSpecifies the number of days between automatic scheduled rotations of the secret. Either master_user_password_rotation_automatically_after_days or master_user_password_rotation_schedule_expression must be specifiednumbernullno
master_password_rotation_durationThe length of the rotation window in hours. For example, 3h for a three hour windowstringnullno
master_password_rotation_schedule_expressionA cron() or rate() expression that defines the schedule for rotating your secret. Either master_user_password_rotation_automatically_after_days or master_user_password_rotation_schedule_expression must be specifiedstringnullno
master_password_secret_kms_key_idID of the KMS key used to encrypt the cluster admin credentials secretstringnullno
master_password_woPassword for the master DB user. Must contain at least 8 chars, one uppercase letter, one lowercase letter, and one numberstringnullno
master_password_wo_versionUsed together with master_password_wo to trigger an update. Increment this value when an update to the master_password_wo is requiredstringnullno
master_usernameUsername for the master DB user. Defaults to awsuserstring"awsuser"no
multi_azSpecifies if the Redshift cluster is multi-AZboolnullno
node_typeThe node type to be provisioned for the clusterstring""no
number_of_nodesNumber of nodes in the cluster. Defaults to 1. Note: values greater than 1 will trigger cluster_type to switch to multi-nodenumber1no
owner_accountThe AWS customer account used to create or copy the snapshot. Required if you are restoring a snapshot you do not own, optional if you own the snapshotstringnullno
parameter_group_descriptionThe description of the Redshift parameter group. Defaults to Managed by Terraformstringnullno
parameter_group_familyThe family of the Redshift parameter groupstring"redshift-2.0"no
parameter_group_nameThe name of the Redshift parameter group, existing or to be createdstringnullno
parameter_group_parametersA list of Redshift parameters to apply
list(object({
name = string
value = string
}))
nullno
parameter_group_tagsAdditional tags to add to the parameter groupmap(string){}no
portThe port number on which the cluster accepts incoming connections. Default port is 5439number5439no
preferred_maintenance_windowThe weekly time range (in UTC) during which automated cluster maintenance can occur. Format: ddd:hh24:mi-ddd:hh24:mistring"sat:10:00-sat:10:30"no
publicly_accessibleIf true, the cluster can be accessed from a public networkboolnullno
regionRegion where the resource(s) will be managed. Defaults to the Region set in the provider configurationstringnullno
scheduled_actionsMap of scheduled action definitions to create
map(object({
name = optional(string) # Will fall back to key if not set
description = optional(string)
enable = optional(bool)
start_time = optional(string)
end_time = optional(string)
schedule = string
iam_role = optional(string)
target_action = object({
pause_cluster = optional(bool, false)
resize_cluster = optional(object({
classic = optional(bool)
cluster_type = optional(string)
node_type = optional(string)
number_of_nodes = optional(number)
}))
resume_cluster = optional(bool, false)
})
}))
{}no
security_group_descriptionThe description of the security group. If value is set to empty string it will contain cluster name in the descriptionstringnullno
security_group_egress_rulesMap of security group egress rules to add to the security group created
map(object({
name = optional(string)

cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(number)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
region = optional(string)
tags = optional(map(string), {})
to_port = optional(number)
}))
{}no
security_group_ingress_rulesMap of security group ingress rules to add to the security group created
map(object({
name = optional(string)

cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(number)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
region = optional(string)
tags = optional(map(string), {})
to_port = optional(number)
}))
{}no
security_group_nameThe security group namestring""no
security_group_tagsAdditional tags for the security groupmap(string){}no
security_group_use_name_prefixDetermines whether the security group name (security_group_name) is used as a prefixbooltrueno
skip_final_snapshotDetermines whether a final snapshot of the cluster is created before Redshift deletes the cluster. If true, a final cluster snapshot is not created. If false , a final cluster snapshot is created before the cluster is deletedbooltrueno
snapshot_arnThe ARN of the snapshot from which to create the new cluster. Conflicts with snapshot_identifierstringnullno
snapshot_cluster_identifierThe name of the cluster the source snapshot was created fromstringnullno
snapshot_copyConfiguration of automatic copy of snapshots from one region to another
object({
destination_region = string
manual_snapshot_retention_period = optional(number)
retention_period = optional(number)
grant_name = optional(string)
})
nullno
snapshot_identifierThe name of the snapshot from which to create the new cluster. Conflicts with snapshot_arnstringnullno
snapshot_scheduleConfiguration for creating a snapshot schedule and associating it with the cluster
object({
definitions = list(string)
description = optional(string)
force_destroy = optional(bool)
use_prefix = optional(bool, false)
identifier = optional(string)
tags = optional(map(string), {})
})
nullno
subnet_group_descriptionThe description of the Redshift Subnet group. Defaults to Managed by Terraformstringnullno
subnet_group_nameThe name of the Redshift subnet group, existing or to be createdstringnullno
subnet_group_tagsAdditional tags to add to the subnet groupmap(string){}no
subnet_idsAn array of VPC subnet IDs to use in the subnet grouplist(string)[]no
tagsA map of tags to add to all resourcesmap(string){}no
usage_limitsMap of usage limit definitions to create
map(object({
amount = number
breach_action = optional(string)
feature_type = string
limit_type = optional(string) # Will fall back to key if not set
period = optional(string)
tags = optional(map(string), {})
}))
{}no
vpc_idID of the VPC where to create security groupstring""no
vpc_security_group_idsA list of Virtual Private Cloud (VPC) security groups to be associated with the clusterlist(string)[]no

Outputs

NameDescription
authentication_profilesMap of authentication profiles created and their associated attributes
cluster_arnThe Redshift cluster ARN
cluster_automated_snapshot_retention_periodThe backup retention period
cluster_availability_zoneThe availability zone of the Cluster
cluster_database_nameThe name of the default database in the Cluster
cluster_dns_nameThe DNS name of the cluster
cluster_encryptedWhether the data in the cluster is encrypted
cluster_endpointThe connection endpoint
cluster_hostnameThe hostname of the Redshift cluster
cluster_idThe Redshift cluster ID
cluster_identifierThe Redshift cluster identifier
cluster_master_passwordThe Redshift cluster master password
cluster_master_usernameThe Redshift cluster master username
cluster_namespace_arnThe namespace Amazon Resource Name (ARN) of the cluster
cluster_node_typeThe type of nodes in the cluster
cluster_nodesThe nodes in the cluster. Each node is a map of the following attributes: node_role, private_ip_address, and public_ip_address
cluster_parameter_group_nameThe name of the parameter group to be associated with this cluster
cluster_portThe port the cluster responds on
cluster_preferred_maintenance_windowThe backup window
cluster_public_keyThe public key for the cluster
cluster_revision_numberThe specific revision number of the database in the cluster
cluster_secretsmanager_secret_rotation_enabledSpecifies whether automatic rotation is enabled for the secret
cluster_subnet_group_nameThe name of a cluster subnet group to be associated with this cluster
cluster_typeThe Redshift cluster type
cluster_versionThe version of Redshift engine software
cluster_vpc_security_group_idsThe VPC security group ids associated with the cluster
endpoint_accessA map of access endpoints created and their attributes
master_password_secret_arnARN of managed master password secret
parameter_group_arnAmazon Resource Name (ARN) of the parameter group created
parameter_group_idThe name of the Redshift parameter group created
scheduled_action_iam_role_arnScheduled actions IAM role ARN
scheduled_action_iam_role_nameScheduled actions IAM role name
scheduled_action_iam_role_unique_idStable and unique string identifying the scheduled action IAM role
scheduled_actionsA map of maps containing scheduled action details
snapshot_schedule_arnAmazon Resource Name (ARN) of the Redshift Snapshot Schedule
subnet_group_arnAmazon Resource Name (ARN) of the Redshift subnet group created
subnet_group_idThe ID of Redshift Subnet group created
usage_limitsMap of usage limits created and their associated attributes

Authors

Module is maintained by Anton Babenko with help from these awesome contributors.

License

Apache 2 Licensed. See LICENSE for full details.