This application now integrates with the official AWS Price List API to provide up-to-date pricing information. The integration uses a dual-layer approach that combines AWS's authoritative pricing data with your custom business logic.
Reference: AWS Price List API
┌─────────────────────────────────────────────────────────┐
│ Layer 1: AWS Price List API (Authoritative Source) │
│ - Fetches real-time pricing from AWS │
│ - Cached for 24 hours for performance │
│ - Handles complex multi-dimensional pricing │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Layer 2: Your Business Logic (Custom Aggregation) │
│ - Maps AWS services to your features │
│ - Adds professional services costs │
│ - Provides Land Zone bundle pricing │
│ - Fallback to manual pricing if AWS unavailable │
└─────────────────────────────────────────────────────────┘
Maps your feature IDs to AWS offer codes.
Example:
{
"featureId": "guardduty",
"awsOfferCode": "AmazonGuardDuty",
"awsServiceName": "Amazon GuardDuty",
"notes": "Charged per GB of VPC Flow Logs, DNS Logs, S3 Logs, etc."
}Core logic for fetching and caching AWS pricing data.
Key Functions:
buildAWSPricingCache()- Fetch and cache pricing datagetCachedAWSPricing()- Retrieve cached pricingisAWSPricingCacheValid()- Check cache validityinitializeAWSPricingCache()- Initialize on startup
Now checks AWS cache first, falls back to manual pricing.
POST /api/pricing/refresh- Manually refresh pricing cacheGET /api/pricing/status- Check cache status
export const getFeaturePricing = (featureId: string) => {
// 1. Try AWS pricing cache first
if (isAWSPricingCacheValid()) {
const awsInfraCost = getCachedAWSPricing(featureId);
if (awsInfraCost !== null && awsInfraCost > 0) {
// Use AWS pricing for infrastructure
return { infraCostImpact: awsInfraCost, ... };
}
}
// 2. Fall back to manual pricing if AWS unavailable
return pricing.featurePricing[featureId] || { ... };
};- Cache Duration: 24 hours
- Storage: In-memory (can be extended to Redis/DB)
- Refresh: Manual via API or automatic on expiry
Edit shared/aws-service-mapping.json:
{
"featureId": "your-feature-id",
"awsOfferCode": "AWSServiceName",
"awsServiceName": "AWS Service Display Name",
"notes": "Pricing details"
}Edit shared/aws-pricing-loader.ts:
async function aggregateFeaturePricing(featureId: string, offerCode: string, region: string) {
// ... existing code ...
switch (featureId) {
case 'your-feature-id':
return parseYourServicePricing(regionData, region);
// ... other cases ...
}
}
function parseYourServicePricing(serviceData: any, region: string): number {
// Parse the AWS Price List structure for your service
// Return monthly cost estimate in USD
}# Start your server
npm run dev
# Check pricing cache status
curl http://localhost:5000/api/pricing/status
# Refresh pricing cache
curl -X POST http://localhost:5000/api/pricing/refresh
# Test feature pricing
# The feature will automatically use AWS pricing if availableThe integration currently includes parsing logic for:
✅ GuardDuty - Threat detection
✅ Transit Gateway - Network hub
✅ Network Firewall - Managed firewall
✅ Free Services - Organizations, Control Tower, IAM
📋 Mapped but using fallback:
- Security Hub
- Inspector
- Macie
- CloudTrail
- CloudWatch
- OpenSearch
- Budgets
- Cost Explorer
- Backup
- Audit Manager
These services are mapped but use manual pricing until parsers are added.
If you need to override AWS pricing for business reasons, you can:
- Keep manual pricing - Don't add the feature to
aws-service-mapping.json - Hybrid approach - Use AWS for infrastructure, manual for professional services (already implemented)
- Force fallback - Set
infraCostImpact: 0in cache to trigger fallback
POST /api/pricing/refresh?region=us-east-2&force=trueParameters:
region(optional) - AWS region (default: us-east-2)force(optional) - Force refresh even if cache is valid (default: false)
Response:
{
"success": true,
"message": "Pricing cache refreshed successfully",
"cache": {
"lastUpdated": "2025-01-15T10:30:00.000Z",
"publicationDate": "2025-01-15T10:30:00.000Z",
"featuresCount": 16
}
}GET /api/pricing/statusResponse:
{
"success": true,
"isValid": true,
"message": "Pricing cache is valid"
}✅ Accurate Pricing - Always up-to-date with AWS official rates
✅ Reduced Maintenance - No manual price updates needed
✅ Business Logic Preserved - Professional services costs remain custom
✅ Performance - 24-hour caching minimizes API calls
✅ Resilient - Automatic fallback to manual pricing
- In-memory cache - Lost on server restart
- Simplified parsing - Not all services fully parsed yet
- Single region - Currently optimized for us-east-2
- No reservations - Doesn't account for Reserved Instances or Savings Plans
- Persistent Cache - Store in PostgreSQL or Redis
- Comprehensive Parsing - Add full parsers for all mapped services
- Multi-region Support - Allow users to select pricing region
- Pricing Analytics - Track pricing changes over time
- Scheduled Refresh - Automatically refresh cache daily
- Price Alerts - Notify when prices change significantly
# Start development server
npm run dev
# In another terminal, test pricing refresh
curl -X POST http://localhost:5000/api/pricing/refresh
# Check a cost calculation
# Features with AWS pricing will use it automatically# Set up scheduled refresh (cron or AWS EventBridge)
curl -X POST https://your-domain.com/api/pricing/refresh?region=us-east-2
# Monitor cache validity
curl https://your-domain.com/api/pricing/statusSolution:
# Refresh the cache
curl -X POST http://localhost:5000/api/pricing/refreshCheck:
- Is the feature in
aws-service-mapping.json? ✅ - Does the AWS offer code exist? Check AWS Index
- Is there a parser function in
aws-pricing-loader.ts? ✅
Verify:
- Check AWS official pricing page for the service
- Review the parser logic in
aws-pricing-loader.ts - Validate estimated usage assumptions (GB/month, etc.)
For questions or issues with the pricing integration, refer to:
shared/aws-pricing-loader.ts- Implementation detailsshared/aws-service-mapping.json- Service mappingsshared/pricing-loader.ts- Integration layer