This project delivers a fully-instrumented Event Driven Architecture on Amazon Web Services. A React-free web UI emits synthetic user events, a Java Kafka producer publishes them to an in-cluster broker, a Kafka consumer exposes history, and Prometheus + Grafana provide real-time observability. Terraform builds the AWS foundation, Jenkins (optional) automates container builds and deployments, and everything ultimately runs in Amazon EKS.
flowchart LR
subgraph Internet
U([Users])
UI[(ALB - Website)]
API[(ALB - Producer API)]
PROM[(ALB - Prometheus)]
GRAF[(ALB - Grafana)]
end
subgraph "Amazon EKS Cluster"
W["Website Pod<br/>Nginx + Chart.js<br/>Proxy /api/send"]
P["Kafka Producer<br/>/send & /metrics"]
B["Kafka Broker<br/>Confluent Kafka"]
Z["ZooKeeper"]
C["Kafka Consumer<br/>/events"]
M["Prometheus<br/>2s scrape"]
G["Grafana<br/>5s refresh"]
end
U --> UI --> W
W -->|/api/send| P
P -->|publish| B
B --> Z
B --> C
P -->|/metrics| M
M --> G
API --> P
PROM --> M
GRAF --> G
Pro tip: open this README in GitHub (or any markdown viewer with Mermaid support) and use your browser zoom (Ctrl/Cmd + Scroll) to inspect individual mappings between services.
- User Interaction – A browser session hits the public website ALB. The static UI (Nginx + Chart.js) renders instantly.
- UI Proxy – Each button fires
fetch("/api/send"); Nginx forwards this to the internal producer service within the cluster. - Producer Service – Validates payloads, persists to Kafka (
eventstopic), and increments the Prometheus counter exposed at/metrics. - Kafka Layer – Confluent broker + ZooKeeper store the event stream. A consumer pod tails the topic and exposes the last 50 messages on
/events. - Observability – Prometheus scrapes the producer (
producer_events_total) and broker endpoints every 2 seconds; Grafana refreshes its panels every 5 seconds and is accessible via its own ALB. - Feedback Loop – UI counters update immediately (client-side), Prometheus/Grafana reflect the same traffic within seconds, providing real-time visibility.
| Layer | Services / Tools |
|---|---|
| Networking | Amazon VPC, public subnets, Internet Gateway, route tables, security groups |
| Compute / Containers | Amazon EKS (control plane + managed node group), Kubernetes Deployments/Services |
| Container Registry | Amazon ECR |
| Load Balancing | AWS Application Load Balancers in front of Website, Producer, Prometheus, Grafana |
| CI/CD | Jenkins (Dockerfile + pipeline), Docker Buildx |
| Infrastructure as Code | Terraform >= 1.5 + hashicorp/aws provider |
| Kafka Stack | Java producer & consumer, Confluent Kafka broker & ZooKeeper |
| Frontend | Static HTML/CSS + Chart.js, proxied through Nginx |
| Observability | Prometheus (2s scrape), Grafana (5s auto-refresh dashboard), custom producer_events_total metric |
infra/– Terraform for AWS account bootstrapping (VPC, subnets, security groups, IAM roles, EKS cluster + node group).jenkins/– Jenkins master image and declarative pipeline (jenkins_pipeline.groovy) that:- Logs into ECR
- Builds/pushes
website&kafkaimages - Updates kubeconfig
- Applies website, kafka, and monitoring manifests.
kafka/ProducerAppexposesPOST /sendandGET /metrics(Prometheus counterproducer_events_total).ConsumerAppstreams the last 50 events viaGET /events.k8s-deployment.yamldeploys producer/consumer plus external LoadBalancer for the producer API.k8s-broker.yamlspins up Confluent Kafka broker + ZooKeeper inside EKS.
website/- Static UI served by Nginx, proxies
/api/send->producer-service. - Chart.js renders metrics instantly with every click.
- Kubernetes deployment uses ECR image and AWS LB.
- Static UI served by Nginx, proxies
monitoring/k8s-config.yamlconfigures Prometheus to scrape Kafka broker (job="kafka") and Producer metrics (job="producer-events") every 2 seconds.grafana-config.yamlauto-provisions:- Datasource pointing to Prometheus service inside the cluster.
- “Producer Event Metrics” dashboard (5s auto-refresh) showing total events (stat) and live rate (timeseries).
k8s-deployment.yamldeploys Prometheus + Grafana with external LoadBalancers for easy access.
| Component | URL | Notes |
|---|---|---|
| Website UI | http://a6f7051c2c31741a79470329000fd849-2116788968.us-east-1.elb.amazonaws.com |
Click buttons to emit events |
| Producer API | http://a97157a7e76e343c7971d665b20ef529-578636936.us-east-1.elb.amazonaws.com:8080/send |
POST JSON (GET returns “Producer API is running…”) |
| Producer Metrics | http://a97157a7e76e343c7971d665b20ef529-578636936.us-east-1.elb.amazonaws.com:8080/metrics |
Exposes producer_events_total counter |
| Prometheus | http://ae92d9c6857784853800e18375a1ea4e-935777073.us-east-1.elb.amazonaws.com:9090 |
Run producer_events_total or rate(producer_events_total[1m]) |
| Grafana | http://a18dab1aa3d9a4148b281e7ecb811213-1022019633.us-east-1.elb.amazonaws.com:3000/login |
Creds admin / admin → “Producer Event Metrics” dashboard |
- Infrastructure –
cd infra && terraform init && terraform apply -var 'region=us-east-1'. - Container builds – Either run the Jenkins pipeline or build manually:
docker build -t ${ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com/website:latest ./website docker build -t ${ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com/kafka:latest ./kafka docker push ...
- Deploy to EKS – Update kubeconfig (
aws eks update-kubeconfig --name event-driven-eks --region us-east-1) and apply manifests:kubectl apply -f kafka/k8s-broker.yaml kubectl apply -f kafka/k8s-deployment.yaml kubectl apply -f website/k8s-deployment.yaml kubectl apply -f monitoring/k8s-config.yaml kubectl apply -f monitoring/grafana-config.yaml kubectl apply -f monitoring/k8s-deployment.yaml
- Verify
- Website responds with latest UI (
Ctrl+Shift+Rto bypass cache). kubectl logs deployment/kafka-producershows📤 Event sent.kubectl logs deployment/kafka-consumershows📥 Received.- Prometheus query
producer_events_total. - Grafana dashboard updates within ~5s of each click.
- Website responds with latest UI (
- Prometheus
producer_events_total rate(producer_events_total[1m]) up{job="producer-events"} - Grafana
- Dashboard: Producer Event Metrics (auto-provisioned).
- Panels refresh every 5 seconds.
- Add more panels by editing
monitoring/grafana-config.yamland re-applying.
- Start Kafka + ZooKeeper + Prometheus + Grafana via docker-compose:
docker compose -f kafka/docker-compose.yml up -d docker compose -f monitoring/docker-compose.yml up -d
- Run producer/consumer locally (
mvn package && java -cp ... ProducerApp). docker build -t website-ui ./website && docker run -p 3000:80 website-ui.- Point
website/app.jsPRODUCER_APIat your local producer endpoint.
- UI not updating: Hard refresh, ensure
app.jsloads (Networktab). Browser extensions sometimes block/api/send. - Port-forward unauthorized: run
aws eks update-kubeconfig --name event-driven-eks --region us-east-1beforekubectl port-forward. - Grafana empty: Ensure you’re logged in (admin/admin) and on “Producer Event Metrics”; Prometheus must show non-zero
producer_events_total. - Need HTTPS / custom domains: front the ALBs with Route53 + ACM certificates.
This README now serves as the single source of truth for everything in the stack—architecture, AWS touch points, runtime URLs, metrics, and the steps required to maintain or extend the system. Have fun instrumenting!