TheArchitect

Redshift Data Warehouse

AWS architecture template · SAA-C03: Kinesis → Lambda ETL → S3 staging → Redshift + Athena federated query

Redshift Data Warehouse is a free AWS architecture template built with Athena, CloudWatch, IAM, Kinesis, Lambda, Redshift and S3. Open it in TheArchitect to edit the diagram, estimate monthly cost, and export the CloudFormation or Terraform that deploys it.

KinesisETL LambdaETL RoleStaging BucketDW ClusterAthena Federat…DW Disk Alarm
Redshift Data Warehouse architecture diagram

AWS services in this template

  • Athena
  • CloudWatch
  • IAM
  • Kinesis
  • Lambda
  • Redshift
  • S3

Deployment notes

Needs input

  • Set a MasterUserPassword in the Redshift cluster configuration before deployment.

Generated CloudFormation — 8 resources

Logical IDResource type
KinesiskinesisAWS::Kinesis::Stream
ETLLambdalambdaAWS::Lambda::Function
ETLRoleiamAWS::IAM::Role
StagingBuckets3AWS::S3::Bucket
DWClusterredshiftAWS::Redshift::Cluster
AthenaFederatedathenaAWS::Athena::WorkGroup
DWDiskAlarmcloudwatchAWS::CloudWatch::Alarm
ETLLambdalambdaStagingBuckets3PermissionAWS::Lambda::Permission
View the full CloudFormation template
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Generated by TheArchitect — https://www.thecloudarchitect.dev",
  "Metadata": {
    "TheArchitect": {
      "Edges": [
        {
          "From": "Kinesiskinesis",
          "To": "ETLLambdalambda",
          "Label": "records"
        },
        {
          "From": "ETLRoleiam",
          "To": "ETLLambdalambda",
          "Label": "role"
        },
        {
          "From": "ETLLambdalambda",
          "To": "StagingBuckets3",
          "Label": "stage"
        },
        {
          "From": "StagingBuckets3",
          "To": "DWClusterredshift",
          "Label": "COPY"
        },
        {
          "From": "StagingBuckets3",
          "To": "AthenaFederatedathena",
          "Label": "federated"
        }
      ]
    }
  },
  "Resources": {
    "Kinesiskinesis": {
      "Type": "AWS::Kinesis::Stream",
      "Properties": {
        "Name": "saa-dw-ingest-stream",
        "StreamModeDetails": {
          "StreamMode": "PROVISIONED"
        },
        "ShardCount": 4,
        "RetentionPeriodHours": 48
      }
    },
    "ETLLambdalambda": {
      "Type": "AWS::Lambda::Function",
      "DependsOn": [
        "ETLRoleiam"
      ],
      "Properties": {
        "Runtime": "nodejs20.x",
        "Handler": "index.handler",
        "MemorySize": 512,
        "Architectures": [
          "arm64"
        ],
        "Timeout": 30,
        "Description": "Transforms Kinesis records and writes to S3 for Redshift COPY.",
        "Environment": {
          "Variables": {
            "APP_ENV": "demo",
            "LOG_LEVEL": "info"
          }
        },
        "TracingConfig": {
          "Mode": "Active"
        },
        "Code": {
          "ZipFile": "exports.handler = async (event) => ({ processed: Array.isArray(event.Records) ? event.Records.length : 1 });"
        },
        "Role": {
          "Fn::GetAtt": [
            "ETLRoleiam",
            "Arn"
          ]
        }
      }
    },
    "ETLRoleiam": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": "saa-dw-etl-role",
        "Description": "Execution role for the Kinesis-to-S3 ETL Lambda.",
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Service": "lambda.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        },
        "ManagedPolicyArns": [
          "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
        ]
      }
    },
    "StagingBuckets3": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": "saa-dw-staging",
        "VersioningConfiguration": {
          "Status": "Enabled"
        },
        "OwnershipControls": {
          "Rules": [
            {
              "ObjectOwnership": "BucketOwnerEnforced"
            }
          ]
        },
        "BucketEncryption": {
          "ServerSideEncryptionConfiguration": [
            {
              "ServerSideEncryptionByDefault": {
                "SSEAlgorithm": "AES256"
              }
            }
          ]
        },
        "PublicAccessBlockConfiguration": {
          "BlockPublicAcls": true,
          "BlockPublicPolicy": true,
          "IgnorePublicAcls": true,
          "RestrictPublicBuckets": true
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "saa-dw-staging"
          }
        ],
        "NotificationConfiguration": {
          "LambdaConfigurations": [
            {
              "Event": "s3:ObjectCreated:*",
              "Function": {
                "Fn::GetAtt": [
                  "ETLLambdalambda",
                  "Arn"
                ]
              }
            }
          ]
        }
      },
      "DependsOn": [
        "ETLLambdalambdaStagingBuckets3Permission"
      ]
    },
    "DWClusterredshift": {
      "Type": "AWS::Redshift::Cluster",
      "Properties": {
        "ClusterIdentifier": "saa-dw-cluster",
        "ClusterType": "single-node",
        "DBName": "analytics",
        "MasterUsername": "dwadmin",
        "NodeType": "dc2.large",
        "Port": 5439,
        "Encrypted": true,
        "AutomatedSnapshotRetentionPeriod": 7
      }
    },
    "AthenaFederatedathena": {
      "Type": "AWS::Athena::WorkGroup",
      "Properties": {
        "Name": "saa-dw-federated",
        "Description": "Athena WorkGroup for federated S3 + Redshift queries.",
        "State": "ENABLED",
        "WorkGroupConfiguration": {
          "PublishCloudWatchMetricsEnabled": true,
          "ResultConfiguration": {
            "OutputLocation": "s3://saa-dw-staging/athena-results/"
          }
        }
      }
    },
    "DWDiskAlarmcloudwatch": {
      "Type": "AWS::CloudWatch::Alarm",
      "Properties": {
        "AlarmName": "saa-dw-disk-usage",
        "AlarmDescription": "Alert when Redshift disk usage exceeds 80%.",
        "Namespace": "AWS/Redshift",
        "MetricName": "PercentageDiskSpaceUsed",
        "Statistic": "Average",
        "Period": 300,
        "EvaluationPeriods": 3,
        "Threshold": 80,
        "ComparisonOperator": "GreaterThanOrEqualToThreshold",
        "TreatMissingData": "notBreaching"
      }
    },
    "ETLLambdalambdaStagingBuckets3Permission": {
      "Type": "AWS::Lambda::Permission",
      "DependsOn": [
        "ETLLambdalambda"
      ],
      "Properties": {
        "Action": "lambda:InvokeFunction",
        "FunctionName": {
          "Ref": "ETLLambdalambda"
        },
        "Principal": "s3.amazonaws.com",
        "SourceAccount": {
          "Ref": "AWS::AccountId"
        },
        "SourceArn": {
          "Fn::Sub": "arn:${AWS::Partition}:s3:::saa-dw-staging"
        }
      }
    }
  }
}

Generated by TheArchitect from the diagram above. Review values such as names, CIDR ranges and instance sizes before deploying to your account.

Related templates