Skip to content

Case_studies

Chapter 50: Real-World Architecture Case Studies

Section titled “Chapter 50: Real-World Architecture Case Studies”

This chapter presents real-world architecture case studies demonstrating how to apply AWS services and best practices to solve common business challenges.

Case Studies Overview
+------------------------------------------------------------------+
| |
| +------------------------+ |
| | Architecture Cases | |
| +------------------------+ |
| | |
| +---------------------+---------------------+ |
| | | | | |
| v v v v |
| +----------+ +----------+ +----------+ +----------+ |
| | E-commerce| | SaaS | | Data | | Enterprise| |
| | Platform | | Multi-Tenant| Lake | | Migration | |
| | | | | | | | | |
| | - Web App| | - Isolation| | - Analytics| | - Hybrid | |
| | - API | | - Scaling| | - ML | | - Legacy | |
| | - Data | | - Billing| | - ETL | | - Modern | |
| +----------+ +----------+ +----------+ +----------+ |
| |
+------------------------------------------------------------------+

E-Commerce Requirements
+------------------------------------------------------------------+
| |
| Functional Requirements |
| +----------------------------------------------------------+ |
| | | |
| | - Product catalog with search and filtering | |
| | - Shopping cart and checkout | |
| | - User authentication and profiles | |
| | - Order management and tracking | |
| | - Payment processing | |
| | - Inventory management | |
| | | |
| +----------------------------------------------------------+ |
| |
| Non-Functional Requirements |
| +----------------------------------------------------------+ |
| | | |
| | - 99.99% availability | |
| | - < 200ms response time | |
| | - Handle 10,000 concurrent users | |
| | - PCI-DSS compliance for payments | |
| | - Auto-scaling for traffic spikes | |
| | | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
E-Commerce Architecture
+------------------------------------------------------------------+
| |
| Users |
| +----------------------------------------------------------+ |
| | Route53 (Latency-Based) | |
| +----------------------------------------------------------+ |
| | |
| v |
| +----------------------------------------------------------+ |
| | CloudFront (CDN) | |
| +----------------------------------------------------------+ |
| | |
| v |
| +----------------------------------------------------------+ |
| | Application Load Balancer | |
| +----------------------------------------------------------+ |
| | | |
| v v |
| +------------------+ +------------------+ |
| | Web Tier (Auto | | API Tier (Auto | |
| | Scaling Group) | | Scaling Group) | |
| | | | | |
| | - Nginx | | - Node.js API | |
| | - React/Next.js | | - Express | |
| +------------------+ +------------------+ |
| | | |
| v v |
| +----------------------------------------------------------+ |
| | ElastiCache (Redis) | |
| | - Session cache | |
| | - Product cache | |
| +----------------------------------------------------------+ |
| | |
| v |
| +----------------------------------------------------------+ |
| | Aurora PostgreSQL (Multi-AZ) | |
| | - Product data | |
| | - User data | |
| | - Order data | |
| +----------------------------------------------------------+ |
| | |
| v |
| +----------------------------------------------------------+ |
| | S3 + DynamoDB | |
| | - Product images (S3) | |
| | - Shopping cart (DynamoDB) | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
e-commerce-infrastructure.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: E-Commerce Platform Infrastructure
Parameters:
Environment:
Type: String
Default: production
AllowedValues: [development, staging, production]
Resources:
# VPC
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub "${Environment}-vpc"
# Public Subnets
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${Environment}-public-subnet-a"
PublicSubnetB:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.2.0/24
AvailabilityZone: !Select [1, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${Environment}-public-subnet-b"
# Private Subnets
PrivateSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.3.0/24
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: !Sub "${Environment}-private-subnet-a"
PrivateSubnetB:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.4.0/24
AvailabilityZone: !Select [1, !GetAZs '']
Tags:
- Key: Name
Value: !Sub "${Environment}-private-subnet-b"
# Aurora Cluster
AuroraCluster:
Type: AWS::RDS::DBCluster
Properties:
Engine: aurora-postgresql
EngineVersion: "14.7"
DatabaseName: ecommerce
MasterUsername: admin
MasterUserPassword: !Ref DBPassword
VpcSecurityGroupIds:
- !Ref DBSecurityGroup
DBSubnetGroupName: !Ref DBSubnetGroup
AvailabilityZones:
- !Select [0, !GetAZs '']
- !Select [1, !GetAZs '']
BackupRetentionPeriod: 7
PreferredBackupWindow: "03:00-04:00"
PreferredMaintenanceWindow: "sun:04:00-sun:05:00"
DeletionProtection: true
StorageEncrypted: true
# ElastiCache
ElastiCacheCluster:
Type: AWS::ElastiCache::ReplicationGroup
Properties:
ReplicationGroupDescription: Session and product cache
CacheNodeType: cache.r6g.large
Engine: redis
EngineVersion: "7.0"
NumCacheClusters: 2
AutomaticFailoverEnabled: true
MultiAZEnabled: true
SecurityGroupIds:
- !Ref CacheSecurityGroup
CacheSubnetGroupName: !Ref CacheSubnetGroup
# Application Load Balancer
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub "${Environment}-alb"
Type: application
Scheme: internet-facing
Subnets:
- !Ref PublicSubnetA
- !Ref PublicSubnetB
SecurityGroups:
- !Ref ALBSecurityGroup
# Web Server ASG
WebServerASG:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
VPCZoneIdentifier:
- !Ref PrivateSubnetA
- !Ref PrivateSubnetB
LaunchTemplate:
LaunchTemplateId: !Ref WebServerLaunchTemplate
Version: !GetAtt WebServerLaunchTemplate.LatestVersionNumber
MinSize: 2
MaxSize: 10
DesiredCapacity: 4
TargetGroupARNs:
- !Ref WebTargetGroup
HealthCheckType: ELB
HealthCheckGracePeriod: 300
# API Server ASG
APIServerASG:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
VPCZoneIdentifier:
- !Ref PrivateSubnetA
- !Ref PrivateSubnetB
LaunchTemplate:
LaunchTemplateId: !Ref APIServerLaunchTemplate
Version: !GetAtt APIServerLaunchTemplate.LatestVersionNumber
MinSize: 2
MaxSize: 20
DesiredCapacity: 4
TargetGroupARNs:
- !Ref APITargetGroup
HealthCheckType: ELB
HealthCheckGracePeriod: 300
Outputs:
LoadBalancerDNS:
Description: ALB DNS Name
Value: !GetAtt ApplicationLoadBalancer.DNSName
AuroraEndpoint:
Description: Aurora Cluster Endpoint
Value: !GetAtt AuroraCluster.Endpoint.Address

50.3 Case Study 2: SaaS Multi-Tenant Platform

Section titled “50.3 Case Study 2: SaaS Multi-Tenant Platform”
SaaS Requirements
+------------------------------------------------------------------+
| |
| Multi-Tenancy Requirements |
| +----------------------------------------------------------+ |
| | | |
| | - Tenant isolation (data, compute, network) | |
| | - Per-tenant customization | |
| | - Usage-based billing | |
| | - Self-service onboarding | |
| | - Per-tenant monitoring | |
| | | |
| +----------------------------------------------------------+ |
| |
| Scaling Requirements |
| +----------------------------------------------------------+ |
| | | |
| | - Support 1000+ tenants | |
| | - Handle variable tenant workloads | |
| | - Auto-scale per tenant | |
| | - Cost-effective for small tenants | |
| | | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
Multi-Tenancy Models
+------------------------------------------------------------------+
| |
| Silo Model (Full Isolation) |
| +----------------------------------------------------------+ |
| | | |
| | Tenant A Tenant B Tenant C | |
| | +--------+ +--------+ +--------+ | |
| | | VPC | | VPC | | VPC | | |
| | | +----+ | | +----+ | | +----+ | | |
| | | |DB | | | |DB | | | |DB | | | |
| | | +----+ | | +----+ | | +----+ | | |
| | | +----+ | | +----+ | | +----+ | | |
| | | |App | | | |App | | | |App | | | |
| | | +----+ | | +----+ | | +----+ | | |
| | +--------+ +--------+ +--------+ | |
| | | |
| | Pros: Maximum isolation, compliance | |
| | Cons: Higher cost, management overhead | |
| | | |
| +----------------------------------------------------------+ |
| |
| Pool Model (Shared Resources) |
| +----------------------------------------------------------+ |
| | | |
| | Shared Infrastructure | |
| | +------------------------------------------------------+ | |
| | | Shared VPC | | |
| | | +----------------------------------------------+ | | |
| | | | Shared Database | | | |
| | | | +--------+ +--------+ +--------+ | | | |
| | | | |Tenant A | |Tenant B | |Tenant C | | | | |
| | | | | Schema | | Schema | | Schema | | | | |
| | | | +--------+ +--------+ +--------+ | | | |
| | | +----------------------------------------------+ | | |
| | | +----------------------------------------------+ | | |
| | | | Shared Application | | | |
| | | +----------------------------------------------+ | | |
| | +------------------------------------------------------+ | |
| | | |
| | Pros: Cost-effective, easier management | |
| | Cons: Less isolation, noisy neighbor issues | |
| | | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
tenant_context.py
import json
import boto3
from functools import wraps
from flask import request, g
class TenantContext:
"""Manage tenant context for multi-tenant application"""
TENANT_HEADER = 'X-Tenant-ID'
@staticmethod
def get_tenant_id():
"""Get tenant ID from request"""
tenant_id = request.headers.get(TenantContext.TENANT_HEADER)
if not tenant_id:
raise ValueError("Tenant ID header required")
return tenant_id
@staticmethod
def get_tenant_config(tenant_id):
"""Get tenant configuration from DynamoDB"""
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('tenant-configurations')
response = table.get_item(
Key={'tenant_id': tenant_id}
)
if 'Item' not in response:
raise ValueError(f"Tenant {tenant_id} not found")
return response['Item']
@staticmethod
def require_tenant(f):
"""Decorator to require tenant context"""
@wraps(f)
def decorated_function(*args, **kwargs):
tenant_id = TenantContext.get_tenant_id()
g.tenant_id = tenant_id
g.tenant_config = TenantContext.get_tenant_config(tenant_id)
return f(*args, **kwargs)
return decorated_function
# Application with tenant context
from flask import Flask, g, jsonify
app = Flask(__name__)
@app.route('/api/products')
@TenantContext.require_tenant
def get_products():
"""Get products for current tenant"""
tenant_id = g.tenant_id
tenant_config = g.tenant_config
# Query tenant-specific data
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(tenant_config['products_table'])
response = table.query(
KeyConditionExpression=boto3.dynamodb.conditions.Key('tenant_id').eq(tenant_id)
)
return jsonify({
'tenant': tenant_id,
'products': response['Items']
})
@app.route('/api/orders', methods=['POST'])
@TenantContext.require_tenant
def create_order():
"""Create order for current tenant"""
tenant_id = g.tenant_id
tenant_config = g.tenant_config
# Validate tenant limits
if tenant_config.get('max_orders_per_day'):
# Check order count
pass
# Create order in tenant-specific table
order_data = request.json
order_data['tenant_id'] = tenant_id
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(tenant_config['orders_table'])
table.put_item(Item=order_data)
return jsonify({'status': 'created', 'order_id': order_data['id']})
tenant_billing.py
import boto3
import json
from datetime import datetime, timedelta
from decimal import Decimal
class TenantBilling:
"""Handle tenant usage tracking and billing"""
def __init__(self):
self.dynamodb = boto3.resource('dynamodb')
self.usage_table = self.dynamodb.Table('tenant-usage')
self.billing_table = self.dynamodb.Table('tenant-billing')
def record_usage(self, tenant_id, resource_type, quantity):
"""Record resource usage for a tenant"""
today = datetime.now().strftime('%Y-%m-%d')
self.usage_table.update_item(
Key={
'tenant_id': tenant_id,
'date': today
},
UpdateExpression='ADD #resource :quantity',
ExpressionAttributeNames={
'#resource': resource_type
},
ExpressionAttributeValues={
':quantity': Decimal(str(quantity))
}
)
def calculate_monthly_bill(self, tenant_id, year, month):
"""Calculate monthly bill for a tenant"""
# Get pricing from tenant config
tenant_config = self.get_tenant_config(tenant_id)
pricing = tenant_config.get('pricing', {})
# Aggregate usage for the month
start_date = datetime(year, month, 1)
if month == 12:
end_date = datetime(year + 1, 1, 1)
else:
end_date = datetime(year, month + 1, 1)
total_usage = {}
current_date = start_date
while current_date < end_date:
date_str = current_date.strftime('%Y-%m-%d')
response = self.usage_table.get_item(
Key={
'tenant_id': tenant_id,
'date': date_str
}
)
if 'Item' in response:
for resource, quantity in response['Item'].items():
if resource not in ['tenant_id', 'date']:
if resource not in total_usage:
total_usage[resource] = Decimal('0')
total_usage[resource] += quantity
current_date += timedelta(days=1)
# Calculate bill
bill_items = []
total_amount = Decimal('0')
for resource, quantity in total_usage.items():
unit_price = Decimal(str(pricing.get(resource, '0')))
amount = quantity * unit_price
total_amount += amount
bill_items.append({
'resource': resource,
'quantity': float(quantity),
'unit_price': float(unit_price),
'amount': float(amount)
})
# Store bill
bill_id = f"{tenant_id}-{year}-{month:02d}"
self.billing_table.put_item(
Item={
'bill_id': bill_id,
'tenant_id': tenant_id,
'year': year,
'month': month,
'items': bill_items,
'total_amount': float(total_amount),
'status': 'pending',
'created_at': datetime.now().isoformat()
}
)
return {
'bill_id': bill_id,
'total_amount': float(total_amount),
'items': bill_items
}
def get_tenant_config(self, tenant_id):
"""Get tenant configuration"""
response = self.dynamodb.Table('tenant-configurations').get_item(
Key={'tenant_id': tenant_id}
)
return response.get('Item', {})

Data Lake Requirements
+------------------------------------------------------------------+
| |
| Data Sources |
| +----------------------------------------------------------+ |
| | | |
| | - Application logs (CloudWatch, custom) | |
| | - Clickstream data | |
| | - IoT sensor data | |
| | - Database exports | |
| | - Third-party data | |
| | | |
| +----------------------------------------------------------+ |
| |
| Processing Requirements |
| +----------------------------------------------------------+ |
| | | |
| | - Real-time analytics | |
| | - Batch processing | |
| | - Machine learning pipelines | |
| | - Data transformation | |
| | - Data quality validation | |
| | | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
Data Lake Architecture
+------------------------------------------------------------------+
| |
| Data Sources |
| +----------------------------------------------------------+ |
| | +--------+ +--------+ +--------+ +--------+ | |
| | | Apps | | IoT | | DBs | | APIs | | |
| | +---+----+ +---+----+ +---+----+ +---+----+ | |
| +------|-----------|-----------|-----------|----------------+ |
| | | | | |
| v v v v |
| +----------------------------------------------------------+ |
| | Ingestion Layer | |
| | +--------+ +--------+ +--------+ +--------+ | |
| | | Kinesis| | DMS | | API | | Batch | | |
| | | Data | | | | Gateway| | Upload | | |
| | | Streams| | | | | | | | |
| | +--------+ +--------+ +--------+ +--------+ | |
| +----------------------------------------------------------+ |
| | | | | |
| v v v v |
| +----------------------------------------------------------+ |
| | Raw Layer (S3) | |
| | +----------------------------------------------------+ | |
| | | s3://data-lake/raw/ | | |
| | | - /logs/ | | |
| | | - /clickstream/ | | |
| | | - /iot/ | | |
| | | - /database/ | | |
| | +----------------------------------------------------+ | |
| +----------------------------------------------------------+ |
| | | | | |
| v v v v |
| +----------------------------------------------------------+ |
| | Processing Layer | |
| | +--------+ +--------+ +--------+ +--------+ | |
| | | Glue | | EMR | | Lambda | | Step | | |
| | | ETL | | | | | | Functions| | |
| | +--------+ +--------+ +--------+ +--------+ | |
| +----------------------------------------------------------+ |
| | | | | |
| v v v v |
| +----------------------------------------------------------+ |
| | Curated Layer (S3) | |
| | +----------------------------------------------------+ | |
| | | s3://data-lake/curated/ | | |
| | | - /analytics/ | | |
| | | - /ml-features/ | | |
| | | - /reports/ | | |
| | +----------------------------------------------------+ | |
| +----------------------------------------------------------+ |
| | | | | |
| v v v v |
| +----------------------------------------------------------+ |
| | Consumption Layer | |
| | +--------+ +--------+ +--------+ +--------+ | |
| | | Athena | | Redshift| | SageMaker| | QuickSight| | |
| | | | | Spectrum| | | | | | |
| | +--------+ +--------+ +--------+ +--------+ | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
data-lake-infrastructure.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Data Lake Infrastructure
Resources:
# S3 Buckets
RawDataBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: data-lake-raw
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
KMSMasterKeyID: !Ref DataLakeKMSKey
LifecycleConfiguration:
Rules:
- Id: TransitionToIA
Status: Enabled
Transitions:
- TransitionInDays: 30
StorageClass: STANDARD_IA
- TransitionInDays: 90
StorageClass: GLACIER
CuratedDataBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: data-lake-curated
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
KMSMasterKeyID: !Ref DataLakeKMSKey
# Glue Database
GlueDatabase:
Type: AWS::Glue::Database
Properties:
CatalogId: !Ref AWS::AccountId
DatabaseInput:
Name: data_lake
Description: Data Lake Catalog
# Glue Crawlers
RawDataCrawler:
Type: AWS::Glue::Crawler
Properties:
Name: raw-data-crawler
Role: !Ref GlueServiceRole
DatabaseName: !Ref GlueDatabase
Targets:
S3Targets:
- Path: !Sub "s3://${RawDataBucket}/logs"
- Path: !Sub "s3://${RawDataBucket}/clickstream"
- Path: !Sub "s3://${RawDataBucket}/iot"
SchemaChangePolicy:
UpdateBehavior: UPDATE_IN_DATABASE
DeleteBehavior: LOG
# Glue ETL Jobs
LogsETLJob:
Type: AWS::Glue::Job
Properties:
Name: logs-etl-job
Role: !Ref GlueServiceRole
Command:
Name: glueetl
ScriptLocation: !Sub "s3://${ScriptsBucket}/scripts/logs_etl.py"
PythonVersion: "3"
DefaultArguments:
"--TempDir": !Sub "s3://${RawDataBucket}/temp"
"--job-language": python
GlueVersion: "4.0"
NumberOfWorkers: 10
WorkerType: G.1X
# Kinesis Data Streams
ClickstreamStream:
Type: AWS::Kinesis::Stream
Properties:
Name: clickstream-data
ShardCount: 4
RetentionPeriodHours: 24
StreamEncryption:
EncryptionType: KMS
KeyId: !Ref DataLakeKMSKey
# Kinesis Firehose
ClickstreamFirehose:
Type: AWS::KinesisFirehose::DeliveryStream
Properties:
DeliveryStreamName: clickstream-to-s3
DeliveryStreamType: KinesisStreamAsSource
KinesisStreamSourceConfiguration:
KinesisStreamARN: !GetAtt ClickstreamStream.Arn
RoleARN: !Ref FirehoseRole
S3DestinationConfiguration:
BucketARN: !GetAtt RawDataBucket.Arn
Prefix: clickstream/
ErrorOutputPrefix: errors/
BufferingHints:
SizeInMBs: 128
IntervalInSeconds: 300
CompressionFormat: GZIP
EncryptionConfiguration:
KMSEncryptionConfig:
AWSKMSKeyARN: !Ref DataLakeKMSKey
RoleARN: !Ref FirehoseRole
# Lambda for real-time processing
RealtimeProcessor:
Type: AWS::Lambda::Function
Properties:
FunctionName: realtime-data-processor
Runtime: python3.9
Role: !Ref LambdaRole
Handler: index.handler
Code:
ZipFile: |
import json
import boto3
def handler(event, context):
for record in event['Records']:
data = json.loads(record['kinesis']['data'])
# Process data
process_data(data)
return {'statusCode': 200}
def process_data(data):
# Transform and validate
pass
ReservedConcurrentExecutions: 100
# Lambda event source mapping
LambdaEventSource:
Type: AWS::Lambda::EventSourceMapping
Properties:
FunctionName: !Ref RealtimeProcessor
EventSourceArn: !GetAtt ClickstreamStream.Arn
StartingPosition: LATEST
BatchSize: 100

50.5 Case Study 4: Enterprise Hybrid Cloud

Section titled “50.5 Case Study 4: Enterprise Hybrid Cloud”
Hybrid Cloud Requirements
+------------------------------------------------------------------+
| |
| Connectivity Requirements |
| +----------------------------------------------------------+ |
| | | |
| | - Secure connection to on-premises | |
| | - Low latency for hybrid applications | |
| | - High bandwidth for data transfer | |
| | - Redundant connectivity | |
| | | |
| +----------------------------------------------------------+ |
| |
| Application Requirements |
| +----------------------------------------------------------+ |
| | | |
| | - Run legacy apps on-premises | |
| | - Modern apps in AWS | |
| | - Burst to cloud for peak loads | |
| | - Data residency compliance | |
| | | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
Hybrid Cloud Architecture
+------------------------------------------------------------------+
| |
| On-Premises Data Center |
| +----------------------------------------------------------+ |
| | | |
| | +------------------+ +------------------+ | |
| | | Legacy Apps | | Database | | |
| | | | | | | |
| | | - ERP | | - Oracle | | |
| | | - CRM | | - SQL Server | | |
| | +------------------+ +------------------+ | |
| | | |
| | +------------------+ +------------------+ | |
| | | Direct Connect | | VPN Gateway | | |
| | | (Primary) | | (Backup) | | |
| | +--------+---------+ +--------+---------+ | |
| | | | | |
| +-----------+---------------------+--------------------------+ |
| | | |
| v v |
| +----------------------------------------------------------+ |
| | AWS Cloud | |
| | | |
| | +------------------------------------------------------+ | |
| | | Transit Gateway | | |
| | +------------------------------------------------------+ | |
| | | | | | |
| | v v v | |
| | +----------+ +----------+ +----------+ | |
| | | VPC A | | VPC B | | VPC C | | |
| | | (Prod) | | (Dev) | | (Shared) | | |
| | | | | | | | | |
| | | - EC2 | | - EC2 | | - AD | | |
| | | - RDS | | - RDS | | - DNS | | |
| | | - Lambda | | - Lambda | | - Secrets| | |
| | +----------+ +----------+ +----------+ | |
| | | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
hybrid-connectivity.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Hybrid Cloud Connectivity
Resources:
# Direct Connect Gateway
DirectConnectGateway:
Type: AWS::DirectConnect::DirectConnectGateway
Properties:
DirectConnectGatewayName: hybrid-dx-gateway
AmazonSideAsn: 64512
# Direct Connect Connection
DirectConnectConnection:
Type: AWS::DirectConnect::Connection
Properties:
Bandwidth: 10Gbps
Location: EqDC2
Name: primary-dx-connection
# Direct Connect Gateway Association
DirectConnectGatewayAssociation:
Type: AWS::DirectConnect::DirectConnectGatewayAssociation
Properties:
DirectConnectGatewayId: !Ref DirectConnectGateway
VirtualGatewayId: !Ref VirtualPrivateGateway
# Transit Gateway
TransitGateway:
Type: AWS::EC2::TransitGateway
Properties:
AmazonSideAsn: 64512
AutoAcceptSharedAttachments: enable
DefaultRouteTableAssociation: enable
DefaultRouteTablePropagation: enable
DnsSupport: enable
VpnEcmpSupport: enable
# Site-to-Site VPN (Backup)
VPNConnection:
Type: AWS::EC2::VPNConnection
Properties:
CustomerGatewayId: !Ref CustomerGateway
Type: ipsec.1
TransitGatewayId: !Ref TransitGateway
StaticRoutesOnly: false
TunnelOptions:
- TunnelInsideCidr: 169.254.10.0/30
PreSharedKey: !Ref VPNPreSharedKey1
- TunnelInsideCidr: 169.254.11.0/30
PreSharedKey: !Ref VPNPreSharedKey2
# Customer Gateway
CustomerGateway:
Type: AWS::EC2::CustomerGateway
Properties:
Type: ipsec.1
BgpAsn: 65000
IpAddress: !Ref OnPremisesPublicIP
# VPC Attachments
ProductionVPCAttachment:
Type: AWS::EC2::TransitGatewayVpcAttachment
Properties:
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref ProductionVPC
SubnetIds:
- !Ref ProductionSubnetA
- !Ref ProductionSubnetB
DevelopmentVPCAttachment:
Type: AWS::EC2::TransitGatewayVpcAttachment
Properties:
TransitGatewayId: !Ref TransitGateway
VpcId: !Ref DevelopmentVPC
SubnetIds:
- !Ref DevelopmentSubnetA
- !Ref DevelopmentSubnetB
# Route to on-premises
RouteToOnPremises:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref ProductionRouteTable
DestinationCidrBlock: 10.0.0.0/8 # On-premises CIDR
TransitGatewayId: !Ref TransitGateway

Case StudyKey Patterns
E-CommerceMulti-tier, auto-scaling, caching, managed databases
SaaSMulti-tenancy, tenant isolation, usage-based billing
Data LakeLayered architecture, multiple ingestion, processing options
HybridDirect Connect, Transit Gateway, VPN backup


End of AWS Complete DevOps Guide