This tutorial explains how to deploy Apache Burr tracking infrastructure on AWS using Terraform. All Terraform code lives in examples/deployment/aws/terraform/. It covers deployment with S3 only (polling mode), with S3 and SQS (event-driven mode), and local development without AWS.
cd examples/deployment/aws/terraform terraform init terraform apply -var-file=dev.tfvars # S3 only, polling mode # or terraform apply -var-file=prod.tfvars # S3 + SQS, event-driven + DLQ alarm
Bucket names are auto-generated. After apply, run terraform output burr_environment_variables and set those on your Burr server.
The Terraform configuration provisions:
burr-tracking-{env}-{region}-{account_id}-{random}) when not specified.enable_sqsAll code is in examples/deployment/aws/terraform/:
examples/deployment/aws/terraform/
├── main.tf # Root module: S3, SQS, CloudWatch alarm, SNS, IAM
├── variables.tf # Input variables
├── outputs.tf # Output values
├── dev.tfvars # Development: S3 only (enable_sqs = false)
├── prod.tfvars # Production: S3 + SQS + DLQ alarm (enable_sqs = true)
├── tutorial.md # This file
└── modules/
├── s3/ # S3 bucket with versioning, encryption, lifecycle
├── sqs/ # SQS queue with DLQ and redrive policy
└── iam/ # IAM role with least-privilege policies
No manual bucket naming required; names are auto-generated. account_id is fetched from AWS credentials when not set. For a custom bucket name, set s3_bucket_name in your tfvars.
| File | Mode | enable_sqs | Resources created |
|---|---|---|---|
| dev.tfvars | S3 only (polling) | false | S3 bucket, IAM role |
| prod.tfvars | S3 + SQS (event) | true | S3 bucket, SQS queue, DLQ, CloudWatch alarm, SNS, IAM |
Uses S3 polling mode (no SQS). Bucket name is auto-generated (burr-tracking-{env}-{region}-{account_id}-{random}). Override with s3_bucket_name = "my-bucket" in tfvars if needed.
Deploy:
cd examples/deployment/aws/terraform terraform init terraform plan -var-file=dev.tfvars terraform apply -var-file=dev.tfvars
Uses event-driven mode with SQS. Bucket name is auto-generated (burr-tracking-{env}-{region}-{account_id}-{random}). A CloudWatch alarm fires when messages land in the DLQ.
Deploy:
terraform plan -var-file=prod.tfvars terraform apply -var-file=prod.tfvars
To deploy with SQS using dev.tfvars, override: terraform apply -var-file=dev.tfvars -var="enable_sqs=true". To deploy S3-only with prod.tfvars: terraform apply -var-file=prod.tfvars -var="enable_sqs=false".
Default configuration. Provides near-instant telemetry updates (~200ms latency).
enable_sqs = true in your tfvars (e.g. prod.tfvars).terraform apply -var-file=prod.tfvars.terraform output burr_environment_variables
Use when you prefer simpler infrastructure or cannot use SQS. Burr polls S3 periodically (default 120 seconds).
enable_sqs = false in your tfvars.terraform apply -var-file=dev.tfvars
The Terraform will create only the S3 bucket and IAM role. No SQS queue or S3 event notifications.
For local development, no Terraform deployment is needed. Burr uses the local filesystem for tracking.
burr --no-open
Use LocalTrackingClient in your application instead of S3TrackingClient.
Data is stored in ~/.burr by default.
| Variable | Description | Default |
|---|---|---|
| aws_region | AWS region | us-east-1 |
| environment | Environment name (dev, prod) | dev |
| account_id | AWS account ID. Empty = auto-fetch from credentials | "" |
| s3_bucket_name | S3 bucket name. Empty = auto-generated (env, region, account_id, random) | "" |
| enable_sqs | Create SQS for event-driven tracking | true |
| sqs_queue_name | Name of the SQS queue | burr-s3-events |
| log_retention_days | Days to retain logs in S3 | 90 |
| snapshot_retention_days | Days to retain DB snapshots | 30 |
| dlq_alarm_notification_emails | Emails to notify when DLQ has messages (confirm via AWS email) | [] |
When SQS is enabled, a CloudWatch alarm fires when messages appear in the dead letter queue. An SNS topic is created for notifications. To receive email alerts, add your addresses to dlq_alarm_notification_emails in your tfvars:
dlq_alarm_notification_emails = ["ops@example.com", "oncall@example.com"]
Each email will receive a confirmation request from AWS; you must confirm the subscription before alerts are delivered. To use Slack or other endpoints, subscribe them to the SNS topic ARN (see terraform output dlq_alarm_sns_topic_arn) after apply.
After apply, useful outputs:
terraform output s3_bucket_name
terraform output sqs_queue_url
terraform output sqs_dlq_url
terraform output dlq_alarm_arn
terraform output dlq_alarm_sns_topic_arn
terraform output burr_environment_variables
The IAM role grants only:
To destroy all resources:
terraform destroy -var-file=dev.tfvars
For S3 buckets with versioning, you may need to empty the bucket first:
aws s3api list-object-versions --bucket BUCKET_NAME --output json | jq -r '.Versions[],.DeleteMarkers[]|.Key+" "+.VersionId' | while read key vid; do aws s3api delete-object --bucket BUCKET_NAME --key "$key" --version-id "$vid"; done
S3 bucket name already exists: S3 bucket names are globally unique. With auto-generation, each apply gets a new random suffix. For a fixed name, set s3_bucket_name explicitly.
SQS policy errors: Ensure the S3 bucket notification depends on the queue policy. The Terraform handles this with depends_on.
Burr server not receiving events: Verify BURR_SQS_QUEUE_URL is set and the IAM role has sqs:ReceiveMessage. Check CloudWatch for the SQS consumer.
DLQ alarm firing: Messages in the DLQ mean the Burr server failed to process S3 events (e.g. crashed, timeout). Check the DLQ in the AWS Console, inspect failed messages, and fix the root cause. Confirm SNS email subscriptions via the link AWS sends.
No email from DLQ alarm: Check your spam folder for the SNS confirmation email. Subscriptions are pending until confirmed.