AWSTemplateFormatVersion: '2010-09-09' Description: 'Amazon Redshift CloudFormation Oct 31,2021' Transform: AWS::SecretsManager-2020-07-23 Parameters: VPCID: Description: The ID of your existing VPC that you’re deploying Redshift into. Type: 'AWS::EC2::VPC::Id' RemoteAccessCIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x Description: Allowed CIDR block to access Redshift cluster. Type: String Subnet1ID: Description: The ID of the private subnet in Availability Zone 1 in your existing VPC. Type: 'AWS::EC2::Subnet::Id' Subnet2ID: Description: The ID of the private subnet in Availability Zone 2 in your existing VPC. Type: 'AWS::EC2::Subnet::Id' PubliclyAccessible: AllowedValues: - 'true' - 'false' Default: 'false' Description: Indicates whether the cluster can be accessed from a public network. Type: String DatabaseName: Description: The name of the first database to be created when the cluster is created. Type: String Default: rsdev01 AllowedPattern: '([a-z]|[0-9])+' RedshiftClusterPort: Description: The port number on which the cluster accepts incoming connections. Type: Number Default: '5439' NumberOfNodes: Description: The number of compute nodes in the cluster. For multi-node clusters, the NumberOfNodes parameter must be greater than 1. Type: Number Default: '2' NodeType: Description: The type of node to be provisioned, we recommend select RA3 nodes wherever available. Type: String Default: ra3.xlplus AllowedValues: - ra3.xlplus - ra3.4xlarge - ra3.16xlarge - dc2.large - dc2.8xlarge - ds2.xlarge - ds2.8xlarge AutoPasswordRotationIntervalDays: Description: Number of days after which master user password will be auto-rotated Type: String Default: 30 AllowedPattern: '([0-9])*' ConstraintDescription: must be a number MasterUsername: Description: The user name that is associated with the master user account for the cluster that is being created. Type: String Default: rsadmin AllowedPattern: '([a-z])([a-z]|[0-9])*' ConstraintDescription: must start with a-z and contain only a-z or 0-9. ConcurrencyScaling: Default: 'auto' Type: String AllowedValues: - 'auto' - 'off' Description: When the number of queries routed to a queue exceeds the queue's configured concurrency, eligible queries go to the scaling cluster. MaxConcurrentCluster: Description: The maximum number of concurrency scaling Redshift clusters. Type: String Default: '1' EnableAQUA: Default: 'auto' Type: String AllowedValues: - 'auto' - 'enabled' - 'disabled' Description: Enables or disables AQUA (Advanced Query Accelerator). With auto, Redshift determines whether to use AQUA. EncryptionAtRest: Description: Enables or disables encryption at rest of the Redshift database. Type: String Default: 'true' AllowedValues: - 'true' - 'false' ConstraintDescription: must be true or false. NotificationList: Type: String Description: The email notification list that is used to configure an SNS topic for sending CloudWatch alarm and event notifications. AllowedPattern: '^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$' ConstraintDescription: provide a valid email address. Default: 'ops@company.com' SnapshotIdentifier: Description: The Redshift snapshot identifier. For a new cluster, keep N/A. Enter the snapshot identifier, only if you want to restore from a snapshot. Default: 'N/A' Type: String SnapshotAccountNumber: Description: The AWS account number where the Redshift snapshot was created. If the snapshot was created in the current AWS account, keep N/A. Default: 'N/A' Type: String EnableLoggingToS3: Default: 'true' Type: String AllowedValues: - 'true' - 'false' Description: Enables or disables logging to an S3 bucket. To enable logging, select True. EnableCrossAZRelocation: Default: 'true' Type: String AllowedValues: - 'true' - 'false' Description: Enables or disables automatic cross AZ relocation. To enable, select True. EnableVPCEnhancedRouting: Default: 'true' Type: String AllowedValues: - 'true' - 'false' Description: Enables or disables VPC enhanced routing. To enable enhanced routing, select True. Maintenancewindow: Description: The maintenance window for the Redshift cluster. Type: String Default: 'sat:05:00-sat:05:30' MaintenanceTrack: Default: 'current' Type: String AllowedValues: - 'current' - 'trailing' Description: Defines Amazon Redshift version to apply during a maintenance window. Select "current" to apply most recent version and "trailing" for the previous version. S3BucketForRedshiftIAMRole: Type: String Description: The existing Amazon S3 bucket. An IAM role will be created and associated to the Redshift cluster with GET and LIST access to this bucket. Default: '' GlueCatalogDatabase: Default: 'default' Type: String Description: The name of your Glue Data Catalog database. Keep the value default, if you do not want to create a new data catalog. AllowedPattern: '([ \t\n\x0B\f\r])*|([a-z])([\-]|[a-z]|[\-]|[0-9])*' ConstraintDescription: must start with a-z and contain only a-z or 0-9 or hyphen (-). TagName: Type: String Description: The unique friendly name as required by your company’s tagging strategy document, and which will be added to the environment tag. Default: 'redshift' TagEnvironment: Type: String AllowedValues: - dev - test - pre-prod - prod - none Default: none Description: The environment tag that is used to designate the environment stage of the associated AWS resource. Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: VPC Network Configuration Parameters: - VPCID - Subnet1ID - Subnet2ID - RemoteAccessCIDR - Label: default: Amazon Redshift configuration Parameters: - NodeType - NumberOfNodes - DatabaseName - NotificationList - Label: default: Amazon Redshift advanced configuration - optional Parameters: - MasterUsername - EnableLoggingToS3 - ConcurrencyScaling - MaxConcurrentCluster - EnableAQUA - RedshiftClusterPort - PubliclyAccessible - EnableVPCEnhancedRouting - EnableCrossAZRelocation - EncryptionAtRest - S3BucketForRedshiftIAMRole - GlueCatalogDatabase - Maintenancewindow - MaintenanceTrack - AutoPasswordRotationIntervalDays - SnapshotIdentifier - SnapshotAccountNumber - Label: default: Tag identifiers Parameters: - TagEnvironment - TagName ParameterLabels: VPCID: default: VPC ID Subnet1ID: default: Private subnet 1 ID Subnet2ID: default: Private subnet 2 ID RemoteAccessCIDR: default: Permitted IP range DatabaseName: default: Redshift database name RedshiftClusterPort: default: Redshift cluster port NodeType: default: Node type for Redshift cluster NumberOfNodes: default: Number of nodes in Redshift cluster MasterUsername: default: Redshift master user name S3BucketForRedshiftIAMRole: default: Amazon S3 bucket for Redshift IAM role NotificationList: default: Email address for SNS notification EnableAQUA: default: Enable AQUA EnableLoggingToS3: default: Enable Redshift logging to S3 EnableCrossAZRelocation: default: Enable cross-AZ relocation EnableVPCEnhancedRouting: default: Enable VPC enhanced routing MaxConcurrentCluster: default: Max. number of concurrent clusters EncryptionAtRest: default: Encryption at rest SnapshotIdentifier: default: Redshift snapshot identifier SnapshotAccountNumber: default: AWS account-ID of the Redshift Snapshot GlueCatalogDatabase: default: Glue catalog database name ConcurrencyScaling: default: Concurrency Scaling Maintenancewindow: default: Maintenance window AutoPasswordRotationIntervalDays: default: Automatic password rotation interval (in days) TagEnvironment: default: Environment TagName: default: Unique friendly name PubliclyAccessible: default: Make Redshift publicly accessible Mappings: Redshift: # static values related to the redshift cluster Password: Length: 32 AuditLogging: ExpirationDays: 400 TransitionDays: 60 CPUUtilizationAlarm: Threshold: 95 AZ: Relocation: true RedshiftLoggingAccountIDRegionMap: us-gov-west-1: RSAccountID: xx us-east-1: RSAccountID: 193672423079 us-east-2: RSAccountID: 391106570357 us-west-1: RSAccountID: 262260360010 us-west-2: RSAccountID: 902366379725 ap-east-1: RSAccountID: 313564881002 ap-south-1: RSAccountID: 865932855811 ap-northeast-3: RSAccountID: 090321488786 ap-northeast-2: RSAccountID: 760740231472 ap-southeast-1: RSAccountID: 361669875840 ap-southeast-2: RSAccountID: 762762565011 ap-northeast-1: RSAccountID: 404641285394 ca-central-1: RSAccountID: 907379612154 cn-north-1: RSAccountID: 111890595117 cn-northwest-1: RSAccountID: 660998842044 eu-west-1: RSAccountID: 210876761215 eu-central-1: RSAccountID: 053454850223 eu-west-2: RSAccountID: 307160386991 eu-west-3: RSAccountID: 915173422425 eu-north-1: RSAccountID: 729911121831 sa-east-1: RSAccountID: 075028567923 Conditions: GovCloudCondition: !Equals [!Ref 'AWS::Region', 'us-gov-west-1'] RedshiftSingleNodeClusterCondition: Fn::Equals: - Ref: NumberOfNodes - '1' IsPublic: !Equals - !Ref PubliclyAccessible - 'true' IsEncryptionAtRest: !Equals - !Ref EncryptionAtRest - 'true' IsProd: !Equals [!Ref TagEnvironment, 'prod'] IsEnableLoggingToS3: !And - !Equals [!Ref EnableLoggingToS3, 'true'] - !Not [!Condition GovCloudCondition] IsConfigureRedshiftIAMRole: Fn::Not: - Fn::Equals: - '' - Ref: S3BucketForRedshiftIAMRole IsGlueCatalogName: Fn::Not: - Fn::Equals: - 'default' - Ref: GlueCatalogDatabase IsSnapshotSpecified: Fn::Not: - Fn::Equals: - 'N/A' - Ref: SnapshotIdentifier IsSnapshotAccountSpecified: Fn::Not: - Fn::Equals: - 'N/A' - Ref: SnapshotAccountNumber IsRA3: Fn::Equals: - !Select [0, !Split [".", !Ref NodeType]] - 'ra3' #IsAquaCompatible: !Or [!Equals [!Ref "NodeType", "ra3.16xlarge"], !Equals [!Ref "NodeType", "ra3.4xlarge"], !Equals [!Ref "NodeType", "ra3.xlarge"]] Rules: RuleToEnableCrossAZRelocation: RuleCondition: 'Fn::Equals': - !Ref EnableCrossAZRelocation - 'true' Assertions: - Assert: 'Fn::Equals': - !Ref RedshiftClusterPort - '5439' AssertDescription: 'To enable Cross-AZ relocation, select Redshift cluster port to 5439.' Assertions: - Assert: 'Fn::Equals': - !Ref 'PubliclyAccessible' - 'false' AssertDescription: 'To enable Cross-AZ relocation, cluster can not be publicly accessible.' Resources: RedshiftSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: !Join [ " ", [ !Ref 'AWS::StackName', " - Redshift Security Group" ] ] VpcId: !Ref VPCID SecurityGroupIngress: - IpProtocol: tcp FromPort: !Ref RedshiftClusterPort ToPort: !Ref RedshiftClusterPort CidrIp: !Ref RemoteAccessCIDR Description: 'Redshift Access to VPC CIDR' Tags: - Key: Name Value: !Join - '_' - - !Ref TagName - !Sub '${AWS::StackName}-RedshiftSecurityGroup' - Key: Environment Value: !Ref TagEnvironment RedshiftLoggingS3Bucket: Type: 'AWS::S3::Bucket' DeletionPolicy: Retain Condition: IsEnableLoggingToS3 Properties: LifecycleConfiguration: Rules: - Id: RedshiftLogsArchivingToGlacier Status: Enabled ExpirationInDays: !FindInMap [ Redshift, AuditLogging, ExpirationDays] Transitions: - TransitionInDays: !FindInMap [ Redshift, AuditLogging, TransitionDays] StorageClass: Glacier Tags: - Key: Name Value: !Join [ '-', [ !Ref TagName, !Ref 'AWS::StackName', 'Redshift-Cluster-LoggingBucket', ], ] - Key: Environment Value: !Ref TagEnvironment RedshiftLoggingS3BucketPolicy: Type: 'AWS::S3::BucketPolicy' Condition: IsEnableLoggingToS3 Properties: Bucket: !Ref RedshiftLoggingS3Bucket PolicyDocument: Statement: - Principal: AWS: !Join [ '', [ 'arn:aws:iam::', !FindInMap [ RedshiftLoggingAccountIDRegionMap, !Ref 'AWS::Region', RSAccountID, ], ':user/logs', ], ] Effect: Allow Action: 's3:GetBucketAcl' Resource: !Sub '${RedshiftLoggingS3Bucket.Arn}' - Principal: AWS: !Join [ '', [ 'arn:aws:iam::', !FindInMap [ RedshiftLoggingAccountIDRegionMap, !Ref 'AWS::Region', RSAccountID, ], ':user/logs', ], ] Effect: Allow Action: 's3:PutObject' Resource: !Sub '${RedshiftLoggingS3Bucket.Arn}/AWSLogs/*' RedshiftClusterParameterGroup: Type: 'AWS::Redshift::ClusterParameterGroup' Properties: Description: !Join [ " ", [ !Ref 'AWS::StackName', " - Redshift Cluster Parameter group" ]] ParameterGroupFamily: redshift-1.0 Parameters: - ParameterName: enable_user_activity_logging ParameterValue: !If [IsProd, 'true', 'false'] - ParameterName: require_ssl ParameterValue: 'true' - ParameterName: auto_analyze ParameterValue: 'true' - ParameterName: statement_timeout ParameterValue: '43200000' - ParameterName: max_concurrency_scaling_clusters ParameterValue: !Ref MaxConcurrentCluster - ParameterName: 'wlm_json_configuration' ParameterValue: !Sub '[ { "query_group" : [ ],"query_group_wild_card" : 0,"user_group" : [ ],"user_group_wild_card" : 0,"concurrency_scaling" : "${ConcurrencyScaling}","rules" : [ { "rule_name" : "DiskSpilling", "predicate" : [ { "metric_name" : "query_temp_blocks_to_disk", "operator" : ">", "value" : 100000 } ], "action" : "log"}, { "rule_name" : "QueryRunningMoreThan30min", "predicate" : [ { "metric_name" : "query_execution_time", "operator" : ">", "value" : 1800 } ], "action": "change_query_priority", "value": "normal"} ],"priority" : "high","queue_type" : "auto","auto_wlm" : true, "name": "HighPriorityQueue1"}, {"user_group": [],"query_group": [],"auto_wlm": true,"queue_type": "auto","name": "Default Queue"}, {"short_query_queue" : true } ]' Tags: - Key: Name Value: !Join [ '-', [ !Ref TagName, !Ref 'AWS::StackName', 'Primary Cluster Parameter group', ], ] - Key: Environment Value: !Ref TagEnvironment RedshiftClusterSubnetGroup: Type: 'AWS::Redshift::ClusterSubnetGroup' Properties: Description: Cluster subnet group SubnetIds: - !Ref Subnet1ID - !Ref Subnet2ID Tags: - Key: Name Value: !Join [ '-', [ !Ref TagName, !Ref 'AWS::StackName', 'Primary Redshift Cluster Subnet group', ], ] - Key: Environment Value: !Ref TagEnvironment SecretRedshiftMasterUser: Type: "AWS::SecretsManager::Secret" Properties: Description: "Secrets Manager to store Redshift master user credentials" GenerateSecretString: SecretStringTemplate: !Sub - '{"username": "${MasterUsername}"}' - {MasterUsername: !Ref MasterUsername} GenerateStringKey: "password" PasswordLength: !FindInMap [ Redshift, Password, Length] ExcludePunctuation: true SecretAttachmentRedshiftMasterUser: Type: "AWS::SecretsManager::SecretTargetAttachment" Properties: SecretId: !Ref SecretRedshiftMasterUser TargetId: !Ref RedshiftCluster TargetType: AWS::Redshift::Cluster RotationScheduleRedshiftMasterUser: Type: AWS::SecretsManager::RotationSchedule DependsOn: SecretAttachmentRedshiftMasterUser Properties: SecretId: !Ref SecretRedshiftMasterUser HostedRotationLambda: RotationLambdaName: !Join [ "-", [ !Ref 'AWS::StackName', "RotationRedshiftMasterUserPassword" ] ] RotationType: RedshiftSingleUser RotationRules: AutomaticallyAfterDays: !Ref AutoPasswordRotationIntervalDays CMKeyRedshiftCluster: Type: AWS::KMS::Key Condition: IsEncryptionAtRest #DeletionPolicy: Retain Properties: Description: 'Customer managed key to be used for encryption at rest' Enabled: Yes EnableKeyRotation: Yes KeyPolicy: Version: 2012-10-17 Id: key-default-1 Statement: - Sid: Enable KMS Permissions for root account user Effect: Allow Principal: AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root' Action: 'kms:*' Resource: '*' - Sid: Enable IAM User Permissions Effect: Allow Principal: AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root' Action: 'kms:*' Resource: '*' - Sid: 'Allow access through Redshift for all principals in the account that are authorized to use Redshift' Effect: 'Allow' Principal: AWS: '*' Action: - 'kms:Encrypt' - 'kms:Decrypt' - 'kms:ReEncrypt*' - 'kms:GenerateDataKey*' - 'kms:CreateGrant' - 'kms:ListGrants' - 'kms:DescribeKey' Resource: '*' Condition: StringEquals: 'kms:CallerAccount': !Sub '${AWS::AccountId}' 'kms:ViaService': !Sub 'redshift.${AWS::Region}.amazonaws.com' RedshiftCluster: DependsOn: - SecretRedshiftMasterUser Type: 'AWS::Redshift::Cluster' DeletionPolicy: 'Snapshot' UpdateReplacePolicy: 'Snapshot' Properties: ClusterType: !If [RedshiftSingleNodeClusterCondition, 'single-node', 'multi-node'] ClusterIdentifier: !Join ["-", [!Ref DatabaseName, !Ref 'AWS::StackName']] NumberOfNodes: !If [ RedshiftSingleNodeClusterCondition, !Ref 'AWS::NoValue', !Ref NumberOfNodes ] NodeType: !Ref NodeType DBName: !Ref DatabaseName KmsKeyId: !If [IsSnapshotSpecified, !Ref 'AWS::NoValue', !If [IsEncryptionAtRest, !Ref CMKeyRedshiftCluster, !Ref 'AWS::NoValue']] Encrypted: !Ref EncryptionAtRest Port: !Ref RedshiftClusterPort MasterUsername: !Join ['', ['{{resolve:secretsmanager:', !Ref SecretRedshiftMasterUser, ':SecretString:username}}' ]] MasterUserPassword: !Join ['', ['{{resolve:secretsmanager:', !Ref SecretRedshiftMasterUser, ':SecretString:password}}' ]] ClusterParameterGroupName: !Ref RedshiftClusterParameterGroup SnapshotIdentifier: !If [IsSnapshotSpecified, !Ref SnapshotIdentifier, !Ref 'AWS::NoValue'] AquaConfigurationStatus: !If [IsRA3, !Ref EnableAQUA, !Ref 'AWS::NoValue'] AvailabilityZoneRelocation: !If [IsRA3, !Ref EnableCrossAZRelocation, !Ref 'AWS::NoValue'] EnhancedVpcRouting: !Ref EnableVPCEnhancedRouting MaintenanceTrackName: !Ref MaintenanceTrack OwnerAccount: !If [ IsSnapshotAccountSpecified, !Ref SnapshotAccountNumber, !Ref 'AWS::NoValue', ] VpcSecurityGroupIds: - !Ref RedshiftSecurityGroup PreferredMaintenanceWindow: !Ref Maintenancewindow AutomatedSnapshotRetentionPeriod: !If [IsProd, 35, 8] PubliclyAccessible: !If - IsPublic - true - false ClusterSubnetGroupName: !Ref RedshiftClusterSubnetGroup LoggingProperties: !If - IsEnableLoggingToS3 - BucketName: !Ref RedshiftLoggingS3Bucket S3KeyPrefix: 'AWSLogs' - !Ref 'AWS::NoValue' IamRoles: - !If - IsConfigureRedshiftIAMRole - !GetAtt MyRedshiftIAMRole.Arn - !Ref 'AWS::NoValue' Tags: - Key: Name Value: !Join [ '-', [!Ref TagName, !Ref 'AWS::StackName', 'Redshift-Cluster'], ] - Key: Environment Value: !Ref TagEnvironment GlueCatalogDB: Condition: IsGlueCatalogName Type: 'AWS::Glue::Database' Properties: CatalogId: !Ref AWS::AccountId DatabaseInput: Name: !Ref GlueCatalogDatabase Description: !Join [ " ", ["AWS Glue Catalog database from Stack ", !Ref 'AWS::StackName'] ] MyRedshiftIAMRole: Type: 'AWS::IAM::Role' Condition: IsConfigureRedshiftIAMRole Properties: RoleName: !Join [ "-", [!Ref 'AWS::StackName', "Redshift-IAM-Role"] ] AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: 'Allow' Principal: Service: - 'redshift.amazonaws.com' - 'glue.amazonaws.com' Action: - 'sts:AssumeRole' Path: '/' Policies: - PolicyName: !Join [ "-", [!Ref 'AWS::StackName', "Spectrum-Glue-Access-Policy"] ] PolicyDocument: Version: '2012-10-17' Statement: - Effect: 'Allow' Action: - s3:GetBucketLocation - s3:GetObject - s3:ListMultipartUploadParts - s3:ListBucket - s3:ListBucketMultipartUploads Resource: - !Join [ '', ['arn:aws:s3:::', !Ref S3BucketForRedshiftIAMRole], ] - !Join [ '', ['arn:aws:s3:::', !Ref S3BucketForRedshiftIAMRole, '/*'], ] - Effect: Allow Action: - glue:CreateDatabase - glue:DeleteDatabase - glue:GetDatabase - glue:GetDatabases - glue:UpdateDatabase - glue:CreateTable - glue:DeleteTable - glue:BatchDeleteTable - glue:UpdateTable - glue:GetTable - glue:GetTables - glue:BatchCreatePartition - glue:CreatePartition - glue:DeletePartition - glue:BatchDeletePartition - glue:UpdatePartition - glue:GetPartition - glue:GetPartitions - glue:BatchGetPartition - logs:* Resource: - '*' SNSTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: !Ref NotificationList Protocol: email DiskSpacealarmredshift: Type: 'AWS::CloudWatch::Alarm' Properties: MetricName: !Join - '' - - !Ref RedshiftCluster - High-PercentageDiskSpaceUsed AlarmDescription: !Join - '' - - DiskSpace Utilization > 85% for - !Ref RedshiftCluster Namespace: AWS/Redshift Statistic: Average Period: 300 EvaluationPeriods: 3 Threshold: 85 AlarmActions: - !Ref SNSTopic Dimensions: - Name: ClusterIdentifier Value: !Ref RedshiftCluster ComparisonOperator: GreaterThanThreshold Unit: Percent HighCPUutilizationalarmredshift: Type: 'AWS::CloudWatch::Alarm' Condition: IsProd Properties: MetricName: !Join - '' - - !Ref RedshiftCluster - High-CPUUtilization AlarmDescription: !Join - '' - - CPUUtilization > 95% for last 15 min for cluster - !Ref RedshiftCluster Namespace: AWS/Redshift Statistic: Average Period: 900 EvaluationPeriods: 3 Threshold: !FindInMap [ Redshift, CPUUtilizationAlarm, Threshold] AlarmActions: - !Ref SNSTopic Dimensions: - Name: ClusterIdentifier Value: !Ref RedshiftCluster ComparisonOperator: GreaterThanThreshold Unit: Percent Outputs: StackName: Description: 'Stack name' Value: !Sub '${AWS::StackName}' RedshiftClusterEndpoint: Description: Redshift cluster endpoint address with port Value: !Sub '${RedshiftCluster.Endpoint.Address}:${RedshiftCluster.Endpoint.Port}' Export: Name: !Sub '${AWS::StackName}-RedshiftClusterEndpoint' RedshiftEndpoint: Description: Redshift endpoint address Value: !Sub '${RedshiftCluster.Endpoint.Address}' Export: Name: !Sub '${AWS::StackName}-RedshiftEndpoint' RedshiftPort: Description: Redshift endpoint port Value: !Sub '${RedshiftCluster.Endpoint.Port}' Export: Name: !Sub '${AWS::StackName}-RedshiftPort' RedshiftCluster: Description: Redshift cluser identifier Value: !Sub '${RedshiftCluster}' Export: Name: !Sub '${AWS::StackName}-RedshiftCluster' RedshiftParameterGroupName: Description: Redshift parameter group Value: !Ref RedshiftClusterParameterGroup Export: Name: !Sub '${AWS::StackName}-RedshiftParameterGroupName' RedshiftDatabaseName: Description: Redshift database name Value: !If - IsSnapshotSpecified - !Join [ ' ', [ 'Check name of database from which the Snapshot', !Ref SnapshotIdentifier, ' was originally taken.', ], ] - !Ref DatabaseName Export: Name: !Sub '${AWS::StackName}-RedshiftDatabaseName' RedshiftUsername: Value: !Ref MasterUsername Export: Name: !Sub '${AWS::StackName}-RedshiftUsername' SecretRedshiftMasterUserSecret: Description: Redshift master user's secret Value: !Ref SecretRedshiftMasterUser RedshiftLoggingS3Bucket: Description: Amazon S3 bucket created for audit logging Condition: IsEnableLoggingToS3 Value: !Ref RedshiftLoggingS3Bucket Export: Name: !Sub '${AWS::StackName}-RedshiftLoggingS3Bucket' RedshiftClusterIAMRole: Description: IAM Role assigned to Redshift cluster Condition: IsConfigureRedshiftIAMRole Value: !GetAtt MyRedshiftIAMRole.Arn Export: Name: !Sub '${AWS::StackName}-RedshiftClusterIAMRole' GlueCatalogDBName: Description: AWS Glue Catalog database Condition: IsGlueCatalogName Value: !Ref GlueCatalogDB Export: Name: !Sub '${AWS::StackName}-GlueCatalogDBName' PSQLCommandLine: Description: PSQL command line Value: !Join - '' - - 'psql -h ' - !GetAtt 'RedshiftCluster.Endpoint.Address' - ' -p ' - !GetAtt 'RedshiftCluster.Endpoint.Port' - ' -U ' - !Ref MasterUsername - ' -d ' - !Ref DatabaseName RedshiftClusterJDBCUrl: Value: !Sub "jdbc:redshift://${RedshiftCluster.Endpoint.Address}:${RedshiftCluster.Endpoint.Port}/${DatabaseName}"