5. Cloud-basierte AWS SaaS Plattform¶
5.1. AWS Allgemein¶
Amazon Web Services bildet das Fundament für moderne, skalierbare Multi-Tenant-SaaS-Anwendungen und bietet alle notwendigen Services für eine vollständig serverlose Architektur.
Projekt-Architektur Überblick
Unsere Multi-Tenant-SaaS-Plattform folgt einer durchdachten, mehrschichtigen Architektur, die optimale Skalierbarkeit, Sicherheit und Tenant-Isolation gewährleistet:
┌───────────────────────────────────────────────────────────────────┐
│ 🌐 FRONTEND BENUTZEROBERFLÄCHE │
│ │
│ React + TypeScript Anwendung │
│ • Responsive Design │
│ • Multi-Tenant Login │
│ • Benutzer-Dashboard │
│ │
│ Gehostet auf: CloudFront CDN + S3 │
└───────────────────────────┬───────────────────────────────────────┘
│
│ HTTPS Anfragen
▼
┌───────────────────────────────────────────────────────────────────┐
│ 🚪 API GATEWAY │
│ │
│ • Custom JWT Authorizers │
│ • Multi-Tenant Routing │
│ • Rate Limiting │
│ • Request/Response Transformation │
└───────────────────────────┬───────────────────────────────────────┘
│
│ Ruft auf
▼
┌───────────────────────────────────────────────────────────────────┐
│ ⚡ AWS LAMBDA FUNKTIONEN │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌──────────┐ │
│ │ 🔐 │ │ 🏢 │ │ 👥 │ │ 📋 │ │
│ │ Authentif. │ │ Mandanten │ │ Benutzer │ │Ressourcen│ │
│ │ Funktionen │ │ Verwaltung │ │ Verwaltung │ │Verwaltung│ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └──────────┘ │
└───────────────────────────┬───────────────────────────────────────┘
│
│ Datenbankverbindungen
▼
┌───────────────────────────────────────────────────────────────────┐
│ 🗄️ AURORA SERVERLESS POSTGRESQL │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 📊 Gemeinsam │ │ 🏢 Mandant 1 │ │ 🏢 Mandant N │ │
│ │ Schema │ │ Schema │ │ Schema │ │
│ │ │ │ │ │ │ │
│ │ • mandanten │ │ • benutzer │ │ • benutzer │ │
│ │ • analytics │ │ • ressourcen │ │ • ressourcen │ │
│ │ • einstellungen │ │ • logs │ │ • logs │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└───────────────────────────────────────────────────────────────────┘
Unterstützende Services:
┌───────────────────────────────────────────────────────────────────┐
│ 🔧 UNTERSTÜTZENDE SERVICES │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 🔑 Amazon │ │ 📡 EventBridge │ │ 📊 CloudWatch │ │
│ │ Cognito │ │ │ │ │ │
│ │ │ │ • Event Routing │ │ • Monitoring │ │
│ │ • Benutzer-Pools│ │ • Service │ │ • Logging │ │
│ │ • Authentifikation│ │ Kommunikation │ │ • Metriken │ │
│ │ • JWT Tokens │ │ • Workflows │ │ • Alarme │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└───────────────────────────────────────────────────────────────────┘
Diese Architektur implementiert bewährte Multi-Tenancy-Patterns und ermöglicht eine klare Trennung zwischen den verschiedenen Schichten, während sie gleichzeitig optimale Performance und Skalierbarkeit gewährleistet.
Dieses Kapitel zeigt die Implementierung einer serverless AWS-Architektur für Multi-Tenant SaaS-Anwendungen.
5.1.1. Service-Portfolio und Architektur-Patterns¶
AWS bietet eine umfassende Palette von Services, die speziell für moderne SaaS-Anwendungen optimiert sind. Die Kombination aus serverlosen Services ermöglicht eine hochskalierbare und kosteneffiziente Architektur.
Core Services für SaaS-Anwendungen:
AWS Lambda: Serverlose Compute-Engine für Business Logic ohne Server-Management
Amazon Aurora Serverless v2: Automatisch skalierender PostgreSQL-Service mit Data API
Amazon API Gateway: Vollständig verwalteter Service für REST APIs mit integrierter Authentifizierung
Amazon Cognito: Benutzer- und Identitätsverwaltung mit Multi-Tenant-Unterstützung
Amazon EventBridge: Event-driven Architektur für lose gekoppelte Services
Amazon S3: Objektspeicher für Static Web Hosting und Dateiverwaltung
// Beispiel: Service-Integration in unserem SaaS-Stack
export class ApiStack extends BaseStack {
constructor(scope: Construct, id: string, props: ApiStackProps) {
super(scope, id, props);
// API Gateway mit CORS und Logging
this.api = new apigateway.RestApi(this, 'TenantAPI', {
restApiName: `${props.envName}-tenant-api`,
description: 'Multi-tenant API Gateway',
defaultCorsPreflightOptions: {
allowOrigins: apigateway.Cors.ALL_ORIGINS,
allowMethods: apigateway.Cors.ALL_METHODS,
allowHeaders: ['Content-Type', 'Authorization', 'X-Tenant-ID'],
},
deployOptions: {
stageName: props.envConfig.stage,
loggingLevel: apigateway.MethodLoggingLevel.INFO,
dataTraceEnabled: true,
},
});
}
}
5.1.2. Multi-Tenant Patterns und Isolationsstrategien¶
Multi-Tenancy erfordert eine durchdachte Balance zwischen Ressourcen-Sharing und Daten-Isolation. Unsere Implementierung verwendet ein hybrides Schema-per-Tenant-Modell für optimale Isolation bei kosteneffizienter Ressourcennutzung.
Tenant-Isolation Patterns:
Schema-per-Tenant: Jeder Tenant erhält ein eigenes Datenbank-Schema für komplette Daten-Isolation
Shared Infrastructure: Gemeinsame Lambda-Funktionen und API Gateway reduzieren Kosten
Context-aware Authorization: Tenant-Kontext wird über Custom Authorizer in jeden Request eingebettet
// Implementierung: Tenant Schema-Erstellung
async function createTenantSchema(tenantId: string): Promise<void> {
const schemaName = `tenant_${tenantId}`;
// Schema erstellen
await rdsClient.send(new ExecuteStatementCommand({
resourceArn: clusterArn,
secretArn: secretArn,
database: database,
sql: `CREATE SCHEMA IF NOT EXISTS ${schemaName}`
}));
// Tenant-spezifische Tabellen
await rdsClient.send(new ExecuteStatementCommand({
resourceArn: clusterArn,
secretArn: secretArn,
database: database,
sql: `
CREATE TABLE IF NOT EXISTS ${schemaName}.users (
id VARCHAR(36) PRIMARY KEY,
email VARCHAR(255) NOT NULL,
firstName VARCHAR(100) NOT NULL,
lastName VARCHAR(100) NOT NULL,
role VARCHAR(50) NOT NULL,
createdAt TIMESTAMP NOT NULL,
updatedAt TIMESTAMP NOT NULL,
UNIQUE(email)
)
`
}));
}
Hier wird das Design und die Implementierung einer Multi-Tenant-Datenbankarchitektur mit Aurora Serverless beschrieben.
Dieses Kapitel behandelt die Implementierung eines sicheren Authentication- und Authorization-Systems mit AWS Cognito.
5.1.3. Security Framework und Compliance¶
Sicherheit ist fundamental für SaaS-Anwendungen und erfordert ein mehrschichtiges Konzept von der Netzwerkebene bis zur Anwendungslogik.
Security-Layers:
Network Security: VPC-Isolation mit privaten Subnetzen für kritische Ressourcen
Identity Management: IAM-Rollen mit Least-Privilege-Prinzip
Data Encryption: End-to-End-Verschlüsselung mit AWS KMS
API Security: JWT-Token-Validation mit Custom Claims für Tenant-Kontext
// Security Group Konfiguration für Lambda-to-Database
const lambdaSecurityGroup = new ec2.SecurityGroup(this, 'LambdaSecurityGroup', {
vpc: props.vpc,
description: 'Security Group for Lambda Functions',
allowAllOutbound: true,
});
// Database-Zugriff nur für autorisierte Lambda-Funktionen
this.database.connections.allowFrom(
lambdaSecurityGroup,
ec2.Port.tcp(5432),
'Allow Lambda to connect to the database'
);
5.2. Infrastruktur¶
Die Infrastruktur-Schicht bildet das robuste Fundament für eine skalierbare Multi-Tenant-SaaS-Anwendung mit durchdachtem Netzwerk-Design und Service-Integration.
5.2.1. VPC Design und Netzwerk-Architektur¶
Eine gut konzipierte Netzwerk-Architektur ist essentiell für Sicherheit und Performance. Unsere Implementierung verwendet eine Multi-Tier-Architektur mit klar getrennten Zonen.
Netzwerk-Topologie:
Public Subnets: Load Balancer und NAT Gateways für Internet-Zugriff
Private Subnets: Lambda-Funktionen und Application Logic mit kontrolliertem Outbound-Zugriff
Isolated Subnets: Datenbank-Cluster ohne Internet-Verbindung für maximale Sicherheit
// VPC mit Multi-AZ-Deployment für High Availability
this.vpc = new ec2.Vpc(this, 'MultiTenantVPC', {
maxAzs: 2,
natGateways: 1,
subnetConfiguration: [
{
cidrMask: 24,
name: 'Public',
subnetType: ec2.SubnetType.PUBLIC,
},
{
cidrMask: 24,
name: 'Private',
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
},
{
cidrMask: 24,
name: 'Isolated',
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
}
]
});
// VPC Flow Logs für Netzwerk-Monitoring
new ec2.FlowLog(this, 'FlowLogs', {
resourceType: ec2.FlowLogResourceType.fromVpc(this.vpc),
destination: ec2.FlowLogDestination.toCloudWatchLogs(),
});
Hier wird die Verwendung von AWS CDK für Infrastructure as Code und automatisierte Deployments erklärt.
5.2.2. Aurora Serverless Integration und Database Design¶
Aurora Serverless v2 bietet die perfekte Balance zwischen Performance und Kosteneffizienz für Multi-Tenant-Anwendungen mit automatischer Skalierung basierend auf der tatsächlichen Nutzung.
Database-Features:
Serverless v2: Automatische Skalierung von 0.5 bis 16 ACUs basierend auf Workload
Data API: HTTP-basierte Datenbankzugriffe ohne persistente Verbindungen
Multi-AZ Deployment: Writer und Reader Instances für High Availability
// Aurora Serverless v2 Cluster mit optimierter Konfiguration
this.database = new rds.DatabaseCluster(this, 'Database', {
engine: rds.DatabaseClusterEngine.auroraPostgres({
version: rds.AuroraPostgresEngineVersion.VER_15_4,
}),
defaultDatabaseName: 'tenantdb',
vpc: props.vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
},
securityGroups: [dbSecurityGroup],
credentials: rds.Credentials.fromSecret(this.dbCredentials),
serverlessV2MinCapacity: 0.5,
serverlessV2MaxCapacity: 16,
enableDataApi: true,
writer: rds.ClusterInstance.serverlessV2('writer'),
readers: [
rds.ClusterInstance.serverlessV2('reader1', { scaleWithWriter: true }),
],
});
5.2.3. API Gateway Setup und Request-Routing¶
API Gateway fungiert als zentraler Eingangspoint für alle Client-Requests und ermöglicht eine einheitliche Authentifizierung und Request-Validation.
Gateway-Features:
CORS Configuration: Vollständige Cross-Origin-Unterstützung für Web-Clients
Custom Authorizer: JWT-Token-Validation mit Tenant-Kontext-Extraktion
Request Validation: Schema-basierte Input-Validation vor Lambda-Ausführung.
// Custom Authorizer für Tenant-aware Authentication
const authorizerLambda = new lambda.Function(this, 'AuthorizerLambda', {
runtime: lambda.Runtime.NODEJS_18_X,
handler: 'index.handler',
code: lambda.Code.fromAsset(
path.join(__dirname, '../../../backend/dist/lambdas/auth/authorizer'),
),
environment: {
USER_POOL_ID: props.userPool.userPoolId,
APP_CLIENT_ID: props.userPoolClient.userPoolClientId,
ENV_NAME: props.envName,
},
timeout: cdk.Duration.seconds(15),
});
// API Gateway mit Custom Authorizer
const authorizer = new apigateway.TokenAuthorizer(this, 'CustomAuthorizer', {
handler: authorizerLambda,
identitySource: 'method.request.header.Authorization',
});
5.3. TypeScript CDK / Infrastructure as Code¶
AWS CDK mit TypeScript ermöglicht die Definition und Verwaltung von Cloud-Infrastruktur durch typsicheren Code und bietet alle Vorteile moderner Software-Entwicklung für Infrastructure as Code.
5.3.1. Stack-Architektur und Modulares Design¶
Eine modulare Stack-Architektur ermöglicht die unabhängige Entwicklung und Deployment verschiedener Infrastruktur-Komponenten und folgt dem Prinzip der Separation of Concerns.
Architektur-Prinzipien:
Base Stack: Gemeinsame Konfiguration und Tags für alle Stacks
Dependency Injection: Explizite Übergabe von Ressourcen zwischen Stacks
Environment Separation: Umgebungsspezifische Konfigurationen ohne Code-Duplikation
// Base Stack für gemeinsame Konfiguration
export interface BaseStackProps extends cdk.StackProps {
envName: string;
envConfig: {
domainName: string;
certificateArn: string;
stage: string;
};
}
export class BaseStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: BaseStackProps) {
super(scope, id, props);
// Gemeinsame Tags für alle Ressourcen
cdk.Tags.of(this).add('Environment', props.envName);
cdk.Tags.of(this).add('Project', 'MultiTenantSaaS');
}
}
Stack-Hierarchie in unserem Projekt:
NetworkStack: VPC, Subnets, Security Groups, NAT Gateways
DatabaseStack: Aurora Cluster, Secrets Manager, Migration Lambda
AuthStack: Cognito User Pools, Identity Provider Configuration
ApiStack: API Gateway, Lambda Functions, Custom Authorizer
EventsStack: EventBridge, SQS Queues, SNS Topics
FrontendStack: S3 Bucket, CloudFront Distribution
5.3.2. Environment-spezifische Konfiguration und Deployment¶
Unterschiedliche Umgebungen erfordern verschiedene Ressourcen-Konfigurationen ohne Code-Änderungen. Unsere Lösung verwendet JSON-basierte Konfigurationsdateien für umgebungsspezifische Parameter.
Konfiguration-Management:
Development: Minimale Ressourcen für Kosten-Optimierung
Staging: Production-ähnliche Konfiguration für realistische Tests
Production: Hochverfügbare und skalierbare Ressourcen-Konfiguration
{
"environments": {
"dev": {
"domainName": "dev-api.multitenant-saas.com",
"stage": "dev",
"database": {
"minCapacity": 0.5,
"maxCapacity": 2,
"backupRetention": 7
},
"lambda": {
"memorySize": 256,
"timeout": 30
}
},
"prod": {
"domainName": "api.multitenant-saas.com",
"stage": "prod",
"database": {
"minCapacity": 2,
"maxCapacity": 16,
"backupRetention": 30
},
"lambda": {
"memorySize": 1024,
"timeout": 60
}
}
}
}
5.3.3. Custom Constructs und Wiederverwendbare Komponenten¶
Custom Constructs abstrahieren wiederkehrende Infrastruktur-Patterns und ermöglichen die Kapselung von Best Practices in wiederverwendbaren Komponenten.
Construct-Patterns:
Multi-Tenant Lambda: Lambda-Funktion mit vorkonfiguriertem Tenant-Kontext
Secure Database Connection: Database-Zugriff mit automatischer Secret-Rotation
Event-Driven Resource: EventBridge-Integration mit standardisierten Event-Schemas
// Custom Construct für Multi-Tenant Lambda Functions
export interface MultiTenantLambdaProps {
handler: string;
environment: Record<string, string>;
tenantTable: dynamodb.Table;
vpc?: ec2.Vpc;
securityGroup?: ec2.SecurityGroup;
}
export class MultiTenantLambda extends Construct {
public readonly function: lambda.Function;
constructor(scope: Construct, id: string, props: MultiTenantLambdaProps) {
super(scope, id);
this.function = new lambda.Function(this, 'Function', {
runtime: lambda.Runtime.NODEJS_18_X,
handler: props.handler,
code: lambda.Code.fromAsset(path.join(__dirname, '../dist')),
environment: {
...props.environment,
TENANT_TABLE: props.tenantTable.tableName,
},
timeout: cdk.Duration.seconds(30),
vpc: props.vpc,
securityGroups: props.securityGroup ? [props.securityGroup] : undefined,
});
// Automatische Berechtigungs-Vergabe
props.tenantTable.grantReadWriteData(this.function);
}
}
5.4. CI/CD¶
Automatisierte CI/CD-Pipelines gewährleisten zuverlässige und reproduzierbare Deployments der Multi-Tenant-SaaS-Anwendung mit integrierter Qualitätssicherung und Rollback-Mechanismen.
5.4.1. Deployment Pipeline und Automatisierung¶
Eine robuste Deployment-Pipeline automatisiert den gesamten Prozess von Code-Änderungen bis zur Production-Bereitstellung und minimiert menschliche Fehler durch konsistente Automatisierung.
Pipeline-Stages:
Source Stage: Git-Repository Integration mit automatischen Triggern
Build Stage: TypeScript-Kompilierung, Linting, Unit Tests
Test Stage: Integration Tests, Security Scans, Infrastructure Validation
Deploy Dev: Automatisches Deployment in Development-Umgebung
Deploy Staging: Manual Approval für Staging-Deployment
Deploy Production: Multi-Approval-Prozess für Production-Release
# PowerShell Deployment-Script für Multi-Environment-Support
param(
[Parameter(Mandatory=$true)]
[ValidateSet("dev", "staging", "prod")]
[string]$Environment,
[switch]$SkipBuild,
[string]$Region = "us-east-1"
)
$ErrorActionPreference = "Stop"
Write-Host "Starting deployment for environment: $Environment" -ForegroundColor Green
Write-Host "Target region: $Region" -ForegroundColor Green
# AWS Environment Setup
$env:CDK_DEFAULT_REGION = $Region
$env:CDK_DEFAULT_ACCOUNT = (aws sts get-caller-identity --query Account --output text)
if (-not $env:CDK_DEFAULT_ACCOUNT) {
Write-Error "Unable to get AWS account ID. Please ensure AWS CLI is configured."
exit 1
}
Write-Host "Deploying to account: $env:CDK_DEFAULT_ACCOUNT" -ForegroundColor Yellow
5.4.2. Infrastructure Deployment und Blue-Green Strategies¶
Blue-Green Deployment ermöglicht Zero-Downtime-Updates durch parallele Deployment-Umgebungen und graduellen Traffic-Shift zwischen den Versionen.
Deployment-Strategien:
Blue-Green Deployment: Parallele Stacks für risikofreie Updates
Traffic Shifting: Graduelle Umleitung über API Gateway Weighted Routing
Automated Rollback: Automatisches Zurückschalten bei Anomalien oder Fehlern
// Migration Lambda für Database Schema Updates
this.migrationLambda = new lambda.Function(this, 'MigrationLambda', {
runtime: lambda.Runtime.NODEJS_18_X,
handler: 'migration.handler',
code: lambda.Code.fromAsset(path.join(__dirname, '../../../backend/dist/lambdas/database')),
environment: {
DB_CLUSTER_ARN: this.database.clusterArn,
DB_SECRET_ARN: this.dbCredentials.secretArn,
DB_NAME: 'tenantdb',
ENV_NAME: props.envName,
},
timeout: cdk.Duration.minutes(10),
vpc: props.vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
},
securityGroups: [lambdaSecurityGroup],
});
Database Migration Patterns:
Forward-Compatible Changes: Schema-Änderungen, die mit alter Code-Version kompatibel sind
Rollback Scripts: Automatische Rollback-Mechanismen für kritische Schema-Änderungen
Version Management: Schema-Versioning für nachvollziehbare Database-Evolution
5.4.3. Monitoring und Alerting Integration¶
Integriertes Monitoring und Alerting ermöglichen proaktive Überwachung der Anwendungsgesundheit und schnelle Reaktion auf Probleme in Production.
Monitoring-Components:
CloudWatch Metrics: Custom Metrics für Business Logic und Performance
Structured Logging: JSON-basierte Logs für automatisierte Analyse
Alert Management: SNS-Topics für verschiedene Kritikalitätsstufen
// CloudWatch Alarm für kritische API-Fehlerrate
const errorAlarm = new cloudwatch.Alarm(this, 'HighErrorRate', {
metric: this.api.metricClientError(),
threshold: 10,
evaluationPeriods: 2,
treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
});
// SNS Topic für Alert-Benachrichtigungen
const alertTopic = new sns.Topic(this, 'AlertTopic', {
displayName: 'SaaS Platform Alerts',
fifo: false,
});
// Alarm Action für automatische Benachrichtigung
errorAlarm.addAlarmAction(new snsActions.SnsAction(alertTopic));
5.5. Backend¶
Das Backend implementiert die gesamte Multi-Tenant-Business-Logic in einer serverlosen, event-driven Architektur und gewährleistet optimale Skalierbarkeit und Tenant-Isolation.
5.5.1. Lambda Functions und Service-Architektur¶
Mikroservice-orientierte Lambda-Architektur ermöglicht die unabhängige Entwicklung und Skalierung verschiedener Business-Domains mit klaren Verantwortlichkeiten.
Service-Domains:
Tenant Management: CRUD-Operationen für Tenant-Verwaltung und Onboarding
User Management: Benutzer-Lifecycle innerhalb von Tenant-Kontexten
Resource Management: Business-Ressourcen-Verwaltung mit Tenant-Isolation
Event Processing: Asynchrone Event-Verarbeitung für Cross-Service-Kommunikation
// Tenant Manager Lambda - Haupteinstiegspunkt für Tenant-Operationen
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
const clusterArn = process.env.DB_CLUSTER_ARN as string;
const secretArn = process.env.DB_SECRET_ARN as string;
const database = process.env.DB_NAME as string;
const eventBusName = process.env.EVENT_BUS_NAME as string;
try {
// Master-Schema für Tenant-Metadaten initialisieren
await executeQuery({
clusterArn,
secretArn,
database,
sql: `
CREATE TABLE IF NOT EXISTS master.tenants (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
tier VARCHAR(50) NOT NULL,
status VARCHAR(50) NOT NULL,
contact_email VARCHAR(255) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
`,
});
// Request-Routing basierend auf HTTP-Method
switch (event.httpMethod) {
case 'GET':
return await handleGetTenants(event, clusterArn, secretArn, database);
case 'POST':
return await handleCreateTenant(event, clusterArn, secretArn, database, eventBusName);
case 'PUT':
return await handleUpdateTenant(event, clusterArn, secretArn, database, eventBusName);
case 'DELETE':
return await handleDeleteTenant(event, clusterArn, secretArn, database, eventBusName);
default:
return formatResponse(405, { message: 'Method not allowed' });
}
} catch (error) {
console.error('Error in tenant manager:', error);
return formatResponse(500, { message: 'Internal server error' });
}
};
5.5.3. Event-Driven Architecture und Asynchrone Verarbeitung¶
Event-driven Architektur ermöglicht lose Kopplung zwischen Services und skalierbare Verarbeitung von Tenant-Lifecycle-Events.
Event-Processing Patterns:
Tenant Created: Schema-Erstellung, Default-Ressourcen, Welcome-Email
Tenant Updated: Quota-Updates, Tier-Changes, Permission-Adjustments
Tenant Deleted: Cleanup-Prozesse, Daten-Archivierung, Resource-Freigabe
// Event Handler für Tenant-Lifecycle-Events
export const handler = async (
event: EventBridgeEvent<string, any>,
context: Context
): Promise<void> => {
try {
// Tenant-Kontext aus Event extrahieren
const tenantId = getEventTenantContext(event);
const { detail, 'detail-type': detailType } = event;
// Event-Type-basierte Verarbeitung
switch (detailType) {
case EventTypes.TENANT_CREATED:
await handleTenantCreated(detail, tenantId);
break;
case EventTypes.TENANT_UPDATED:
await handleTenantUpdated(detail, tenantId);
break;
case EventTypes.TENANT_DELETED:
await handleTenantDeleted(detail, tenantId);
break;
default:
console.log(`Unhandled event type: ${detailType}`);
}
} catch (error) {
console.error('Error processing tenant event:', error);
throw error;
}
};
// Tenant-Schema-Initialisierung für neue Tenants
async function createTenantSchema(tenantId: string): Promise<void> {
const schemaName = `tenant_${tenantId}`;
// Tenant-spezifisches Schema erstellen
await rdsClient.send(new ExecuteStatementCommand({
resourceArn: clusterArn,
secretArn: secretArn,
database: database,
sql: `CREATE SCHEMA IF NOT EXISTS ${schemaName}`
}));
// Tenant-spezifische Tabellen-Struktur
await rdsClient.send(new ExecuteStatementCommand({
resourceArn: clusterArn,
secretArn: secretArn,
database: database,
sql: `
CREATE TABLE IF NOT EXISTS ${schemaName}.resources (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
type VARCHAR(50) NOT NULL,
data JSON,
ownerId VARCHAR(36) NOT NULL,
createdAt TIMESTAMP NOT NULL,
updatedAt TIMESTAMP NOT NULL
)
`
}));
console.log(`Created database schema for tenant ${tenantId}`);
}
5.6. Fazit¶
Die Entwicklung einer cloudbasierten Multi-Tenant-SaaS-Plattform mit AWS demonstriert die Stärken der Amazon Web Services Infrastruktur für moderne Anwendungsarchitekturen. Die serverless-first Architektur mit AWS Lambda, API Gateway und Aurora Serverless v2 ermöglicht automatische Skalierung und kosteneffiziente Pay-per-Use-Ressourcennutzung. AWS Cognito bietet robuste Authentifizierung mit Multi-Tenant-fähigen Custom Claims, während EventBridge eine lose gekoppelte, event-driven Architektur ermöglicht. TypeScript CDK als Infrastructure as Code Lösung reduziert Konfigurationsfehler durch typsichere Definitionen und ermöglicht wiederverwendbare Konstrukte. Die umfassenden AWS-Sicherheitsfeatures von VPC-Isolation bis IAM-Integration gewährleisten Defense-in-Depth für kritische Multi-Tenant-Datenisolation. Herausforderungen wie Architektur-Komplexität, Lambda Cold Starts und Kostenmanagement bei hohem Traffic erfordern kontinuierliches Monitoring und Optimierung. AWS bietet insgesamt eine ausgereifte Plattform für skalierbare Multi-Tenant-SaaS-Lösungen, wobei der Erfolg von sorgfältiger Architekturplanung und datenbasierter Optimierung abhängt.
5.7. Quellen¶
AWS Lambda Developer Guide. Amazon Web Services. https://docs.aws.amazon.com/lambda/
Amazon API Gateway Developer Guide. Amazon Web Services. https://docs.aws.amazon.com/apigateway/
Amazon Aurora User Guide. Amazon Web Services. https://docs.aws.amazon.com/AuroraServerless/
AWS CDK Developer Guide. Amazon Web Services. https://docs.aws.amazon.com/cdk/
Amazon Cognito Developer Guide. Amazon Web Services. https://docs.aws.amazon.com/cognito/
Amazon EventBridge User Guide. Amazon Web Services. https://docs.aws.amazon.com/eventbridge/