Event-Driven Fan-Out (CDK)¶
Source: examples/event-driven-fanout.yaml
To check and price this model from a clone of the repository:
infra-cost-model validate examples/event-driven-fanout.yaml
infra-cost-model compute --time-basis monthly examples/event-driven-fanout.yaml
# Example: Event-Driven Fan-Out (CDK)
# Demonstrates: SNS fan-out to multiple SQS queues with different call rates,
# multi-path DAG accumulation via Kahn's algorithm, long-running compute,
# data volume metrics.
#
# Issue: https://github.com/elecnix/infra-cost-model/issues/5
version: "1.0"
workflow:
name: event-driven-orders
entry: aws_apigatewayv2_api.orders_api
frequency:
unit: perMinute
value: 500
nodes:
aws_apigatewayv2_api.orders_api:
nodeType: routing
resourceAddress: aws_apigatewayv2_api.orders_api
provider: aws
region: us-east-1
service: AmazonAPIGatewayHTTP
usageMetrics:
requests: { unit: requests, value: 1 }
# An HTTP API has no egress price of its own. AWS bills the response bytes
# as data transfer out to the internet.
data_transfer.orders_api_egress:
nodeType: external
resourceAddress: data_transfer.orders_api_egress
provider: aws
region: us-east-1
service: AWSDataTransfer
usageMetrics:
internetOutGb: { unit: GB, value: 0.00001 } # 10KB per request
aws_lambda_function.producer:
nodeType: compute
resourceAddress: aws_lambda_function.producer
provider: aws
region: us-east-1
service: AWSLambda
usageMetrics:
invocations: { unit: requests, value: 1 }
avgDurationMs: { unit: ms, value: 100 }
memoryMb: { unit: MB, value: 256 }
aws_sns_topic.order_events:
nodeType: routing
resourceAddress: aws_sns_topic.order_events
provider: aws
region: us-east-1
service: AmazonSNS
usageMetrics:
publishes: { unit: requests, value: 1 }
aws_sqs_queue.orders_queue:
nodeType: routing
resourceAddress: aws_sqs_queue.orders_queue
provider: aws
region: us-east-1
service: AmazonSQS
usageMetrics:
messagesSent: { unit: requests, value: 1 }
aws_sqs_queue.notifications_queue:
nodeType: routing
resourceAddress: aws_sqs_queue.notifications_queue
provider: aws
region: us-east-1
service: AmazonSQS
usageMetrics:
messagesSent: { unit: requests, value: 1 }
aws_sqs_queue.analytics_queue:
nodeType: routing
resourceAddress: aws_sqs_queue.analytics_queue
provider: aws
region: us-east-1
service: AmazonSQS
usageMetrics:
messagesSent: { unit: requests, value: 1 }
aws_lambda_function.order_processor:
nodeType: compute
resourceAddress: aws_lambda_function.order_processor
provider: aws
region: us-east-1
service: AWSLambda
usageMetrics:
invocations: { unit: requests, value: 1 }
avgDurationMs: { unit: ms, value: 300 }
memoryMb: { unit: MB, value: 512 }
aws_lambda_function.notifier:
nodeType: compute
resourceAddress: aws_lambda_function.notifier
provider: aws
region: us-east-1
service: AWSLambda
usageMetrics:
invocations: { unit: requests, value: 1 }
avgDurationMs: { unit: ms, value: 50 }
memoryMb: { unit: MB, value: 256 }
aws_lambda_function.analyzer:
nodeType: compute
resourceAddress: aws_lambda_function.analyzer
provider: aws
region: us-east-1
service: AWSLambda
usageMetrics:
invocations: { unit: requests, value: 1 }
avgDurationMs: { unit: ms, value: 5000 }
memoryMb: { unit: MB, value: 1024 }
aws_dynamodb_table.orders:
nodeType: storage
resourceAddress: aws_dynamodb_table.orders
provider: aws
region: us-east-1
service: AmazonDynamoDB
usageMetrics:
# One write per call. The edge from order_processor carries rate 2.
writeRequests: { unit: requests, value: 1 }
aws_sns_topic.alerts:
nodeType: routing
resourceAddress: aws_sns_topic.alerts
provider: aws
region: us-east-1
service: AmazonSNS
usageMetrics:
publishes: { unit: requests, value: 1 }
aws_s3_bucket.data_lake:
nodeType: storage
resourceAddress: aws_s3_bucket.data_lake
provider: aws
region: us-east-1
service: AmazonS3
usageMetrics:
putRequests: { unit: requests, value: 1 }
edges:
# Every response leaves AWS as data transfer out
- from: aws_apigatewayv2_api.orders_api
to: data_transfer.orders_api_egress
rate: 1
# Entry: API Gateway → Producer Lambda
- from: aws_apigatewayv2_api.orders_api
to: aws_lambda_function.producer
rate: 1
# Producer → SNS (fan-out source)
- from: aws_lambda_function.producer
to: aws_sns_topic.order_events
rate: 1
# SNS fan-out to 3 SQS queues with different call rates
- from: aws_sns_topic.order_events
to: aws_sqs_queue.orders_queue
rate: 0.8 # 80% are order events
- from: aws_sns_topic.order_events
to: aws_sqs_queue.notifications_queue
rate: 1.0 # 100% get notifications
- from: aws_sns_topic.order_events
to: aws_sqs_queue.analytics_queue
rate: 0.5 # 50% sampled for analytics
# Orders path: SQS → order_processor → DynamoDB
- from: aws_sqs_queue.orders_queue
to: aws_lambda_function.order_processor
rate: 1
- from: aws_lambda_function.order_processor
to: aws_dynamodb_table.orders
rate: 2
type: write
# Notifications path: SQS → notifier → SNS alerts
- from: aws_sqs_queue.notifications_queue
to: aws_lambda_function.notifier
rate: 1
- from: aws_lambda_function.notifier
to: aws_sns_topic.alerts
rate: 1
# Analytics path: SQS → analyzer → S3
- from: aws_sqs_queue.analytics_queue
to: aws_lambda_function.analyzer
rate: 1
- from: aws_lambda_function.analyzer
to: aws_s3_bucket.data_lake
rate: 1
dataSize:
unit: kB
average: 500 # 500KB per analytics event