Stream AWS CloudWatch metrics, logs, and optionally X-Ray traces and CloudTrail audit logs to Better Stack via Kinesis Data Firehose.
See the main README for an overview or the Lambda documentation for details on deployed lambdas.
- Better Stack Account - Sign up at betterstack.com
- Cluster ID - Your Better Stack cluster identifier (e.g.,
g1,s1234,acme) - Source Token - Authentication token from Better Stack
- Source ID - Source ID from Better Stack for resource matching
- AWS CLI - Configured with appropriate permissions
aws cloudformation deploy \
--template-file better-stack-full.yaml \
--stack-name better-stack-full \
--parameter-overrides \
ClusterId=YOUR_CLUSTER_ID \
SourceToken=YOUR_SOURCE_TOKEN \
SourceId=YOUR_SOURCE_ID \
--capabilities CAPABILITY_NAMED_IAMWhen deploying to additional regions, set CreateGlobalResources=false to reuse the IAM roles created in the first region:
aws cloudformation deploy \
--template-file better-stack-full.yaml \
--stack-name better-stack-full \
--region us-west-2 \
--parameter-overrides \
ClusterId=YOUR_CLUSTER_ID \
SourceToken=YOUR_SOURCE_TOKEN \
SourceId=YOUR_SOURCE_ID \
CreateGlobalResources=false \
--capabilities CAPABILITY_NAMED_IAM| Data Type | Flow |
|---|---|
| Metrics | CloudWatch Metric Stream (JSON) -> Firehose -> Lambda (enrichment) -> Better Stack |
| Logs | CloudWatch Logs -> Subscription Filter -> Firehose -> Lambda (enrichment) -> Better Stack |
| Traces | X-Ray -> CloudWatch Logs (aws/spans) -> Subscription Filter -> Better Stack |
| Audit | CloudTrail -> CloudWatch Logs -> Subscription Filter -> Better Stack |
| Parameter | Description |
|---|---|
ClusterId |
Your Better Stack cluster ID |
SourceToken |
Better Stack source token for authentication |
SourceId |
Better Stack source ID for resource matching |
| Parameter | Default | Description |
|---|---|---|
CreateGlobalResources |
true |
Create IAM roles. Set to false for secondary regions. |
| Parameter | Default | Description |
|---|---|---|
EnableTagEnrichment |
true |
Enable Lambda-based tag enrichment for metrics and logs |
EnableCloudTrail |
true |
Create a new CloudTrail trail and forward to Better Stack |
EnableXRayTransactionSearch |
true |
Enable X-Ray Transaction Search and forward spans |
Most AWS accounts already have CloudTrail enabled. Before enabling EnableCloudTrail=true, check for existing trails:
aws cloudtrail describe-trailsIf a trail already exists, you may want to:
- Keep
EnableCloudTrail=falseand manually subscribe the existing CloudTrail log group - Or enable it to create a dedicated trail for Better Stack
CloudTrail logs have a 1-day retention in CloudWatch (they are forwarded immediately to Better Stack).
When EnableXRayTransactionSearch=true, the template automatically:
- Creates a CloudWatch Logs resource policy allowing X-Ray to write spans
- Enables Transaction Search via
AWS::XRay::TransactionSearchConfig - X-Ray sends trace segments to the
aws/spansCloudWatch Logs group
No manual steps required - fully automated via CloudFormation.
The template creates a better-stack-integration-role IAM role that allows Better Stack to:
- Read CloudWatch metrics and logs
- Manage metric streams and log subscriptions
- Discover AWS resources for context enrichment
After deployment, provide these values to Better Stack:
- Role ARN: From stack output
IntegrationRoleArn - External ID: From stack output
ExternalId
When EnableTagEnrichment=true, Lambda functions enrich metrics and logs with AWS resource tags.
Metrics enrichment adds tags from:
- EC2 instances
- RDS databases
- Lambda functions
- DynamoDB tables
- S3 buckets
- ELB/ALB/NLB load balancers
- SQS queues
- SNS topics
Logs enrichment extracts resource info from log group/stream names:
/aws/lambda/{function-name}-> Lambda tags/aws/rds/instance/{db-instance}/{type}-> RDS tagsRDSOSMetrics(Enhanced Monitoring) -> RDS tags from message body/ecs/{cluster}/...-> ECS tags/aws/api-gateway/{api-id}-> API Gateway tags
See the Lambda README for implementation details. Lambda code is deployed from regional S3 buckets (better-stack-lambda-{region}).
When CreateGlobalResources=true, the stack outputs:
| Output | Description |
|---|---|
IntegrationRoleArn |
STS role ARN to provide to Better Stack |
ExternalId |
External ID to provide to Better Stack |
Better Stack will discover all other resources (Firehose streams, Metric Streams, etc.) via the STS integration role.
aws logs filter-log-events \
--log-group-name /aws/kinesisfirehose/better-stack-metrics \
--start-time $(date -d '1 hour ago' +%s000)aws logs filter-log-events \
--log-group-name /aws/lambda/better-stack-metrics \
--start-time $(date -d '1 hour ago' +%s000)aws cloudwatch get-metric-stream --name better-stack-metric-streamTo delete the stack:
aws cloudformation delete-stack --stack-name better-stack-fullNote: S3 buckets have DeletionPolicy: Retain to preserve any failed delivery data and CloudTrail logs. Delete manually if needed:
# Delete Firehose backup bucket
aws s3 rb s3://better-stack-firehose-ACCOUNT_ID-REGION --force
# Delete CloudTrail bucket (if CloudTrail was enabled)
aws s3 rb s3://better-stack-cloudtrail-ACCOUNT_ID-REGION --forceFor issues or questions, please reach out at hello@betterstack.com