Infrastructure-as-Code for SunBot — a production Discord economy bot (35+ servers, 90k+ combined users). This repo provisions and manages the bot's cloud infrastructure on AWS with Terraform, migrating it from managed hosting to self-provisioned, fully reproducible infrastructure.
Contains no application code and no secrets — only infrastructure definitions. Terraform state and any
*.tfvarsare git-ignored.
The bot originally ran on managed hosting (one click to restart/back up, but a
black box). This project rebuilds its environment as code so it can be reviewed,
versioned, and recreated on any account with a single terraform apply — and to
practice the exact IaC/AWS workflow used by real teams.
- Terraform ≥ 1.6 — declarative infrastructure
- AWS — S3, EC2, VPC, IAM (region
eu-central-1) - Docker — the bot + MySQL run as containers on the instance
| Area | Status |
|---|---|
| S3 bucket for off-site DB backups (versioned, auto-expiring, private) | ✅ done |
| EC2 instance + security group + SSH key pair | ✅ done |
| Containerized bot deploy (Docker Compose) | ✅ done |
| AWS Budgets cost guardrail | ✅ done |
| Managed MySQL on RDS (private, SG-locked to the instance) | ✅ done |
| Elastic IP (stable public address) | ✅ done |
| Self-hosted analytics — Umami + Caddy (auto-TLS) behind a Cloudflare subdomain | ✅ done |
| Scheduled serverless backup (Lambda + EventBridge → S3) | 🔜 planned |
provider.tf which providers + AWS region
variables.tf inputs (e.g. your IP for SSH lockdown)
data.tf look up existing AWS bits (default VPC, subnets, latest Ubuntu AMI)
s3.tf backup bucket + public-access lockdown
s3_lifecycle.tf versioning + auto-expiry of old backups
ec2.tf SSH key pair + security group (22/80/443) + the server + outputs
rds.tf managed MySQL + its security group + subnet group
budgets.tf monthly cost budget with email alerts
eip.tf Elastic IP (stable public address)
The analytics stack (Umami + Caddy) runs on the instance via Docker Compose — Terraform provisions the network/IP/ports it needs; the containers themselves are app-level deployment config, not infrastructure.
Cloudflare DNS
│
analytics.maksympatrushev.com ──443──┐
▼
┌──────────────── AWS eu-central-1 (default VPC) ────────────────┐
│ Elastic IP │
│ │ │
you ──SSH(22)──▶ EC2 t3.micro ───────MySQL(3306)──▶ RDS MySQL │
│ Docker: bot · Caddy(TLS) · Umami private, SG-lock │
│ │ │
│ └──── off-site dumps ────▶ S3 (versioned) 🔜 │
└────────────────────────────────────────────────────────────────┘
AWS Budgets watches spend · AWS layer defined in Terraform
terraform init # download the AWS provider
terraform plan # preview changes (creates nothing)
terraform apply # make it real
terraform destroy # tear everything downCredentials are read from the local AWS CLI config (aws configure) — never
committed.