AWS Deployment
This guide covers deploying EvidentSource on AWS using DynamoDB for storage and SNS for event streaming. The deployment uses CloudFormation templates for infrastructure as code and supports auto-scaling for production workloads.
Architecture Overview
Section titled “Architecture Overview”graph TB subgraph "Public Subnet" ALB[Application Load Balancer] end
subgraph "Private Subnet" ASG[Auto Scaling Group] EC2[EC2 Instances<br/>EvidentSource Servers] end
subgraph "AWS Services" DDB[(DynamoDB)] SNS[SNS Topic] S3[(S3 Bucket)] CW[CloudWatch] end
subgraph "Optional Components" Lambda[Lambda Functions] SQS[SQS Queues] end
ALB --> EC2 EC2 --> DDB EC2 --> SNS EC2 --> S3 EC2 --> CW SNS --> Lambda SNS --> SQSPrerequisites
Section titled “Prerequisites”- AWS Account with appropriate permissions
- AWS CLI configured with credentials
- Docker (for building container images)
- ACM certificate for your domain
- Route53 hosted zone (or equivalent DNS management)
DNS Configuration
Section titled “DNS Configuration”EvidentSource requires proper DNS configuration for both external client access and internal service communication (particularly for the MCP server).
Required DNS Records
Section titled “Required DNS Records”| Record | Type | Target | Purpose |
|---|---|---|---|
api.evidentsource.example.com | A (Alias) | Application Load Balancer | External and internal API access |
Private Hosted Zone (Required for MCP)
Section titled “Private Hosted Zone (Required for MCP)”When deploying with MCP enabled (EnableMcp=true), the MCP server must connect to the EvidentSource API via the internal ALB. This requires the Host parameter to resolve from within the VPC.
Option 1: Route53 Private Hosted Zone
# Create private hosted zone associated with your VPCaws route53 create-hosted-zone \ --name example.com \ --vpc VPCRegion=us-east-1,VPCId=vpc-xxxxx \ --caller-reference $(date +%s) \ --hosted-zone-config PrivateZone=true
# Add alias record pointing to the internal ALB# (Get ALB DNS name from CloudFormation outputs after deployment)Option 2: Split-Horizon DNS
If you already have a public hosted zone, create a matching private hosted zone with the same domain. The VPC resolver will prefer the private zone for internal queries.
Endpoints
Section titled “Endpoints”After deployment, EvidentSource exposes:
| Endpoint | Port | Description |
|---|---|---|
https://{Host} | 443 | REST API, gRPC API |
https://{Host}:8000 | 8000 | MCP server (AI agent integration) |
For detailed parameter documentation, see CloudFormation Parameters.
Quick Start with AWS Marketplace
Section titled “Quick Start with AWS Marketplace”The easiest way to deploy EvidentSource is through the AWS Marketplace:
🚀 Coming Soon: AWS Marketplace
EvidentSource will be available on AWS Marketplace for one-click deployment.
Subscribe on AWS MarketplaceManual Deployment
Section titled “Manual Deployment”Step 1: Prepare the Environment
Section titled “Step 1: Prepare the Environment”# Set your AWS regionexport AWS_REGION=us-east-1
# Create S3 bucket for CloudFormation templatesaws s3 mb s3://my-evident-deployment-$AWS_REGION
# Download CloudFormation templates from customer portal# https://customers.evidentsource.com/downloads/cloudformationStep 2: Push Docker Image to ECR
Section titled “Step 2: Push Docker Image to ECR”# Create ECR repositoryaws ecr create-repository --repository-name evident-source-server
# Get login tokenaws ecr get-login-password --region $AWS_REGION | \ docker login --username AWS --password-stdin \ $(aws sts get-caller-identity --query Account --output text).dkr.ecr.$AWS_REGION.amazonaws.com
# Pull official imagedocker login registry.evidentsource.comdocker pull registry.evidentsource.com/evident-source-server:latest
# Tag and push to your ECRdocker tag registry.evidentsource.com/evident-source-server:latest \ $(aws sts get-caller-identity --query Account --output text).dkr.ecr.$AWS_REGION.amazonaws.com/evident-source-server:latest
docker push \ $(aws sts get-caller-identity --query Account --output text).dkr.ecr.$AWS_REGION.amazonaws.com/evident-source-server:latestStep 3: Deploy Infrastructure
Section titled “Step 3: Deploy Infrastructure”Using CloudFormation
Section titled “Using CloudFormation”# Deploy VPC (optional, if you don't have one)aws cloudformation deploy \ --template-file infrastructure/cloudformation/vpc.yaml \ --stack-name evident-vpc \ --parameter-overrides \ AvailabilityZones=us-east-1a,us-east-1b
# Deploy EvidentSourceaws cloudformation deploy \ --template-file infrastructure/cloudformation/evident-stack.yaml \ --stack-name evident-stack \ --parameter-overrides \ VpcId=vpc-xxxxx \ PrivateSubnetIds=subnet-xxxxx,subnet-yyyyy \ PublicSubnetIds=subnet-aaaaa,subnet-bbbbb \ InstanceType=m6i.large \ MinSize=2 \ MaxSize=10 \ DesiredCapacity=3 \ --capabilities CAPABILITY_IAMCloudFormation Template Overview
Section titled “CloudFormation Template Overview”The main template creates:
Resources: # DynamoDB Tables EventsTable: Type: AWS::DynamoDB::Table Properties: BillingMode: PAY_PER_REQUEST PointInTimeRecoverySpecification: PointInTimeRecoveryEnabled: true StreamSpecification: StreamViewType: NEW_AND_OLD_IMAGES
IndexesTable: Type: AWS::DynamoDB::Table Properties: BillingMode: PAY_PER_REQUEST
# SNS Topic for Events EventTopic: Type: AWS::SNS::Topic Properties: KmsMasterKeyId: alias/aws/sns
# Auto Scaling Group AutoScalingGroup: Type: AWS::AutoScaling::AutoScalingGroup Properties: LaunchTemplate: LaunchTemplateId: !Ref LaunchTemplate TargetGroupARNs: - !Ref TargetGroup HealthCheckType: ELB HealthCheckGracePeriod: 300
# Application Load Balancer LoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Type: application Scheme: internet-facingStep 4: Configure EvidentSource
Section titled “Step 4: Configure EvidentSource”Create the launch configuration:
#!/bin/bash# User data script for EC2 instances
# Install CloudWatch agentwget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpmrpm -U ./amazon-cloudwatch-agent.rpm
# Configure EvidentSourcecat > /etc/evident-source/config.toml <<EOF[server]host = "0.0.0.0"port = 8080scheme = "http"
[storage]adapter = "dynamodb"
[dynamodb]events_table = "${EventsTable}"indexes_table = "${IndexesTable}"databases_table = "${DatabasesTable}"
[sns]topic_arn = "${EventTopicArn}"enable_raw_delivery = true
[observability]metrics_endpoint = "cloudwatch"traces_endpoint = "xray"EOF
# Start EvidentSourcedocker run -d \ --name evident-source \ --restart always \ -p 8080:8080 \ -v /etc/evident-source:/config \ -e AWS_REGION=${AWS_REGION} \ ${ECR_URI}/evident-source-server:latest \ --config /config/config.tomlStep 5: Configure Auto Scaling
Section titled “Step 5: Configure Auto Scaling”# CPU-based scalingCPUScalingPolicy: Type: AWS::AutoScaling::ScalingPolicy Properties: AutoScalingGroupName: !Ref AutoScalingGroup PolicyType: TargetTrackingScaling TargetTrackingConfiguration: PredefinedMetricSpecification: PredefinedMetricType: ASGAverageCPUUtilization TargetValue: 70.0
# Custom metric scaling (events per second)EventRateScalingPolicy: Type: AWS::AutoScaling::ScalingPolicy Properties: AutoScalingGroupName: !Ref AutoScalingGroup PolicyType: TargetTrackingScaling TargetTrackingConfiguration: CustomizedMetricSpecification: MetricName: EventsPerSecond Namespace: EvidentSource Statistic: Average TargetValue: 1000.0Production Configuration
Section titled “Production Configuration”DynamoDB Optimization
Section titled “DynamoDB Optimization”# Production DynamoDB configurationEventsTable: Type: AWS::DynamoDB::Table Properties: BillingMode: PROVISIONED ProvisionedThroughput: ReadCapacityUnits: 5000 WriteCapacityUnits: 5000 GlobalSecondaryIndexes: - IndexName: by-stream Keys: - AttributeName: database_name KeyType: HASH - AttributeName: stream_revision KeyType: RANGE Projection: ProjectionType: ALL ProvisionedThroughput: ReadCapacityUnits: 1000 WriteCapacityUnits: 1000Enable Auto-scaling for DynamoDB
Section titled “Enable Auto-scaling for DynamoDB”# Register scalable targetsaws application-autoscaling register-scalable-target \ --service-namespace dynamodb \ --resource-id "table/evident-events" \ --scalable-dimension "dynamodb:table:ReadCapacityUnits" \ --min-capacity 5 \ --max-capacity 40000
# Create scaling policyaws application-autoscaling put-scaling-policy \ --service-namespace dynamodb \ --resource-id "table/evident-events" \ --scalable-dimension "dynamodb:table:ReadCapacityUnits" \ --policy-name "evident-events-read-scaling" \ --policy-type "TargetTrackingScaling" \ --target-tracking-scaling-policy-configuration '{ "TargetValue": 70.0, "PredefinedMetricSpecification": { "PredefinedMetricType": "DynamoDBReadCapacityUtilization" } }'Security Best Practices
Section titled “Security Best Practices”IAM Role for EC2 Instances
Section titled “IAM Role for EC2 Instances”{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:BatchGetItem", "dynamodb:BatchWriteItem" ], "Resource": [ "arn:aws:dynamodb:*:*:table/evident-*", "arn:aws:dynamodb:*:*:table/evident-*/index/*" ] }, { "Effect": "Allow", "Action": [ "sns:Publish" ], "Resource": "arn:aws:sns:*:*:evident-events" }, { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": "arn:aws:s3:::evident-data/*" } ]}Network Security
Section titled “Network Security”# Security group for ALBALBSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0
# Security group for instancesInstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: SecurityGroupIngress: - IpProtocol: tcp FromPort: 8080 ToPort: 8080 SourceSecurityGroupId: !Ref ALBSecurityGroupTLS Configuration
Section titled “TLS Configuration”# ALB HTTPS listenerHTTPSListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: LoadBalancerArn: !Ref LoadBalancer Port: 443 Protocol: HTTPS Certificates: - CertificateArn: !Ref Certificate DefaultActions: - Type: forward TargetGroupArn: !Ref TargetGroup
# ACM CertificateCertificate: Type: AWS::CertificateManager::Certificate Properties: DomainName: evident.example.com ValidationMethod: DNS DomainValidationOptions: - DomainName: evident.example.com HostedZoneId: !Ref HostedZoneMonitoring and Observability
Section titled “Monitoring and Observability”CloudWatch Dashboards
Section titled “CloudWatch Dashboards”Create a dashboard for monitoring:
{ "widgets": [ { "type": "metric", "properties": { "metrics": [ ["EvidentSource", "EventsPerSecond", {"stat": "Average"}], [".", "QueryLatency", {"stat": "p99"}], [".", "ActiveConnections", {"stat": "Average"}] ], "period": 300, "stat": "Average", "region": "us-east-1", "title": "EvidentSource Metrics" } } ]}CloudWatch Alarms
Section titled “CloudWatch Alarms”HighLatencyAlarm: Type: AWS::CloudWatch::Alarm Properties: MetricName: QueryLatency Namespace: EvidentSource Statistic: Average Period: 300 EvaluationPeriods: 2 Threshold: 100 ComparisonOperator: GreaterThanThreshold AlarmActions: - !Ref SNSAlertTopic
DynamoDBThrottleAlarm: Type: AWS::CloudWatch::Alarm Properties: MetricName: UserErrors Namespace: AWS/DynamoDB Dimensions: - Name: TableName Value: evident-events Statistic: Sum Period: 60 EvaluationPeriods: 1 Threshold: 10 ComparisonOperator: GreaterThanThresholdX-Ray Tracing
Section titled “X-Ray Tracing”Enable distributed tracing:
# Configure X-Ray daemoncat > /etc/systemd/system/xray.service <<EOF[Unit]Description=AWS X-Ray DaemonAfter=network.target
[Service]Type=simpleExecStart=/usr/bin/xray -o -n us-east-1Restart=on-failureRestartSec=5s
[Install]WantedBy=multi-user.targetEOF
systemctl enable xraysystemctl start xrayCost Optimization
Section titled “Cost Optimization”DynamoDB Cost Management
Section titled “DynamoDB Cost Management”-
Use On-Demand for Variable Workloads
BillingMode: PAY_PER_REQUEST -
Enable Auto-scaling for Predictable Workloads
- Set appropriate min/max capacity
- Use scheduled scaling for known patterns
-
Configure DynamoDB Accelerator (DAX)
DAXCluster:Type: AWS::DAX::ClusterProperties:NodeType: dax.r3.largeReplicationFactor: 3
EC2 Cost Optimization
Section titled “EC2 Cost Optimization”-
Use Graviton Instances
InstanceType: m6g.large # ARM-based, 20% better price/performance -
Spot Instances for Non-Critical Workloads
MixedInstancesPolicy:InstancesDistribution:OnDemandPercentageAboveBaseCapacity: 30SpotAllocationStrategy: capacity-optimized -
Reserved Instances
- Purchase RIs for baseline capacity
- Use Savings Plans for flexibility
Backup and Disaster Recovery
Section titled “Backup and Disaster Recovery”DynamoDB Backups
Section titled “DynamoDB Backups”# Enable continuous backupsaws dynamodb update-continuous-backups \ --table-name evident-events \ --point-in-time-recovery-specification \ PointInTimeRecoveryEnabled=true
# Create on-demand backupaws dynamodb create-backup \ --table-name evident-events \ --backup-name evident-events-$(date +%Y%m%d)Cross-Region Replication
Section titled “Cross-Region Replication”GlobalTable: Type: AWS::DynamoDB::GlobalTable Properties: TableName: evident-events-global Replicas: - Region: us-east-1 - Region: eu-west-1 - Region: ap-southeast-1Troubleshooting
Section titled “Troubleshooting”Common Issues
Section titled “Common Issues”High Latency
- Check DynamoDB throttling metrics
- Verify EC2 instance CPU/memory usage
- Review CloudWatch logs for errors
Connection Errors
- Verify security group rules
- Check IAM permissions
- Ensure DynamoDB tables exist
Event Processing Delays
- Monitor SNS metrics
- Check Lambda function errors (if using)
- Verify dead letter queue
Performance Tuning
Section titled “Performance Tuning”# Optimal configuration for high throughput[performance]connection_pool_size = 100batch_size = 25write_buffer_size = "10MB"compression = "snappy"
[dynamodb]max_retries = 3retry_delay_ms = 100consistent_reads = falseNext Steps
Section titled “Next Steps”- Set up Monitoring and Alerting
- Configure Backup and Recovery
- Implement Security Best Practices
- Review Performance Tuning
Support
Section titled “Support”For AWS-specific deployment support:
- EvidentSource Customer Support: support@evidentsource.com
- AWS Support (if you have a support plan)
- Customer Portal: customers.evidentsource.com
- AWS Marketplace Support (coming soon)