Skip to content

Commit 8377a81

Browse files
Simplify: Use Coolify for Elasticsearch instead of AWS
- Remove OpenSearch/Fargate Elasticsearch from Terraform - Elasticsearch deployed manually on Coolify (existing infrastructure) - AWS only manages: SQS + 2 Lambdas - Lambdas connect to Coolify Elasticsearch via URL - Much simpler and cheaper: ~-5/month AWS only - No VPC complexity needed for Lambdas
1 parent 782a561 commit 8377a81

File tree

5 files changed

+85
-280
lines changed

5 files changed

+85
-280
lines changed

.github/workflows/deploy.yaml

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,8 @@ jobs:
6262
working-directory: terraform
6363
run: terraform plan -input=false
6464
env:
65-
TF_VAR_vpc_id: ${{ secrets.VPC_ID }}
66-
TF_VAR_es_subnet_ids: ${{ secrets.ES_SUBNET_IDS }}
67-
TF_VAR_assign_public_ip: false
68-
TF_VAR_allowed_cidr_blocks: ${{ secrets.VPC_CIDR_BLOCKS }}
6965
TF_VAR_elasticsearch_password: ${{ secrets.ELASTICSEARCH_PASSWORD }}
66+
TF_VAR_elasticsearch_url: ${{ secrets.ELASTICSEARCH_URL }}
7067
TF_VAR_webhook_secret: ${{ secrets.WEBHOOK_SECRET }}
7168
TF_VAR_moresleep_url: ${{ secrets.MORESLEEP_URL }}
7269
TF_VAR_moresleep_username: ${{ secrets.MORESLEEP_USERNAME }}
@@ -76,15 +73,8 @@ jobs:
7673
working-directory: terraform
7774
run: terraform apply -auto-approve -input=false
7875
env:
79-
TF_VAR_vpc_id: ${{ secrets.VPC_ID }}
80-
TF_VAR_es_subnet_ids: ${{ secrets.ES_SUBNET_IDS }}
81-
TF_VAR_assign_public_ip: false
82-
TF_VAR_allowed_cidr_blocks: ${{ secrets.VPC_CIDR_BLOCKS }}
8376
TF_VAR_elasticsearch_password: ${{ secrets.ELASTICSEARCH_PASSWORD }}
84-
TF_VAR_elasticsearch_url: http://elasticsearch.javazone.internal:9200
85-
TF_VAR_task_cpu: 1024
86-
TF_VAR_task_memory: 2048
87-
TF_VAR_heap_size: 1024
77+
TF_VAR_elasticsearch_url: ${{ secrets.ELASTICSEARCH_URL }}
8878
TF_VAR_webhook_secret: ${{ secrets.WEBHOOK_SECRET }}
8979
TF_VAR_moresleep_url: ${{ secrets.MORESLEEP_URL }}
9080
TF_VAR_moresleep_username: ${{ secrets.MORESLEEP_USERNAME }}
@@ -94,32 +84,16 @@ jobs:
9484
working-directory: terraform
9585
run: |
9686
echo "================================================"
97-
echo "✅ Deployment Complete!"
87+
echo "✅ AWS Infrastructure Deployed!"
9888
echo "================================================"
9989
echo ""
10090
echo "🔗 Webhook URL for moresleep:"
10191
terraform output -raw webhook_url
10292
echo ""
10393
echo ""
104-
echo "📊 OpenSearch:"
105-
terraform output -raw opensearch_endpoint
106-
echo ""
107-
echo ""
10894
echo "📦 SQS Queue:"
10995
terraform output -raw sqs_queue_url
11096
echo ""
97+
echo ""
98+
echo "📊 Elasticsearch: Deploy on Coolify (see README)"
11199
echo "================================================"
112-
113-
- name: Wait for OpenSearch to be ready
114-
run: |
115-
echo "Waiting 5 minutes for OpenSearch domain to be active..."
116-
sleep 300
117-
118-
- name: Create OpenSearch Index
119-
working-directory: terraform
120-
run: |
121-
OS_URL=$(terraform output -raw opensearch_endpoint)
122-
curl -X PUT "$OS_URL/javazone_talks" \
123-
-u elastic:${{ secrets.ELASTICSEARCH_PASSWORD }} \
124-
-H "Content-Type: application/json" \
125-
-d @../config/index-mapping.json || echo "Index may already exist"

README.md

Lines changed: 57 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,156 +1,87 @@
1-
# Elasticsearch for JavaZone
1+
# JavaZone Elasticsearch Integration
22

3-
Elasticsearch deployment on AWS Fargate with EFS persistent storage.
3+
Complete Elasticsearch integration for JavaZone - all in one repository!
44

5-
## Architecture
5+
## 🎯 What This Deploys
66

7-
- **Single Fargate task** running Elasticsearch 8.11
8-
- **EFS volume** for persistent data storage
9-
- **Service Discovery** for stable DNS: `elasticsearch.javazone.internal:9200`
10-
- **1 vCPU, 2GB RAM** (sufficient for ~10K talks)
7+
**AWS (via Terraform):**
8+
- SQS queues (main + DLQ)
9+
- webhook-receiver Lambda (API Gateway)
10+
- es-indexer-worker Lambda (SQS triggered)
1111

12-
## Deployment
12+
**Coolify (manual):**
13+
- Elasticsearch 8.11.0
1314

14-
### 1. Deploy Infrastructure
15+
**Cost: ~$2-5/month AWS + $0 Coolify = ~$2-5/month total**
1516

16-
```bash
17-
cd terraform
18-
19-
cp terraform.tfvars.example terraform.tfvars
20-
# Edit with your values
17+
---
2118

22-
terraform init
23-
terraform apply
24-
```
19+
## 🚀 Quick Start
2520

26-
**What this creates:**
27-
- ECS Cluster and Fargate task
28-
- EFS file system for data persistence
29-
- Security groups
30-
- Service discovery (optional DNS name)
31-
- SSM parameter for password
21+
### 1. Deploy Elasticsearch on Coolify
3222

33-
**Cost:** ~$35-45/month (Fargate + EFS)
23+
1. Coolify → New Resource → Docker Image
24+
2. Image: `elasticsearch:8.11.0`
25+
3. Environment:
26+
```
27+
discovery.type=single-node
28+
xpack.security.enabled=true
29+
ELASTIC_PASSWORD=bi75Xtl3KPXI4CS7QRU8TrFRpF3mV1qX
30+
ES_JAVA_OPTS=-Xms1g -Xmx1g
31+
```
32+
4. Volume: `/data/elasticsearch``/usr/share/elasticsearch/data`
33+
5. Port: `9200`
34+
6. Deploy
3435

35-
### 2. Wait for Elasticsearch to Start
36+
7. Create index:
37+
```bash
38+
curl -X PUT "http://your-es-url:9200/javazone_talks" \
39+
-u elastic:bi75Xtl3KPXI4CS7QRU8TrFRpF3mV1qX \
40+
-H "Content-Type: application/json" \
41+
-d @config/index-mapping.json
42+
```
3643

37-
```bash
38-
# Check task status
39-
aws ecs list-tasks --cluster elasticsearch-javazone --region eu-central-1
40-
41-
# Get task IP (if not using service discovery)
42-
aws ecs describe-tasks \
43-
--cluster elasticsearch-javazone \
44-
--tasks <task-arn> \
45-
--region eu-central-1 | grep "privateIpv4Address"
46-
```
44+
8. Update GitHub secret with your ES URL:
45+
```bash
46+
gh secret set ELASTICSEARCH_URL --body "http://your-elasticsearch-domain:9200"
47+
```
4748

48-
### 3. Create Index
49+
---
4950

50-
If using service discovery:
51-
```bash
52-
ES_URL="http://elasticsearch.javazone.internal:9200"
53-
```
51+
### 2. Deploy AWS Infrastructure (GitHub Actions)
5452

55-
Otherwise:
56-
```bash
57-
ES_URL="http://<task-private-ip>:9200"
58-
```
53+
Push to `main` or manually trigger workflow:
5954

60-
Create the index:
61-
```bash
62-
curl -X PUT "$ES_URL/javazone_talks" \
63-
-u elastic:<your-password> \
64-
-H "Content-Type: application/json" \
65-
-d @../config/index-mapping.json
66-
```
55+
https://github.com/javaBin/elasticsearch-javazone/actions
6756

68-
Verify:
69-
```bash
70-
curl -u elastic:<password> "$ES_URL/javazone_talks"
71-
curl -u elastic:<password> "$ES_URL/_cluster/health"
72-
```
57+
Deploys: SQS + 2 Lambdas (~2 minutes)
7358

74-
## Access from Other Services
59+
---
7560

76-
### With Service Discovery (Recommended)
77-
```
78-
ELASTICSEARCH_URL=http://elasticsearch.javazone.internal:9200
79-
```
61+
### 3. Configure Moresleep
8062

81-
Use this in:
82-
- es-indexer-worker terraform.tfvars
83-
- libum configuration
63+
Use webhook URL from GitHub Actions output:
8464

85-
### Without Service Discovery
86-
Use the task's private IP (changes on restart):
87-
```
88-
ELASTICSEARCH_URL=http://10.0.x.x:9200
65+
```properties
66+
WEBHOOK_ENABLED=true
67+
WEBHOOK_ENDPOINT=<url-from-output>
68+
WEBHOOK_SECRET=7faa5e7879e189dfdeab497f647a88e15abcd7be4c2209f318465e764547d258
8969
```
9070

91-
## Monitoring
71+
Redeploy moresleep.
9272

93-
View task logs in AWS ECS Console:
94-
- ECS → Clusters → elasticsearch-javazone → Tasks → View logs tab
73+
---
9574

96-
Check cluster health:
97-
```bash
98-
curl -u elastic:<password> "$ES_URL/_cluster/health"
99-
```
100-
101-
Check document count:
102-
```bash
103-
curl -u elastic:<password> "$ES_URL/javazone_talks/_count"
104-
```
105-
106-
## Data Persistence
107-
108-
Data is stored on EFS and persists across task restarts. To completely reset:
75+
## ✅ Testing
10976

77+
Create a talk → Check ES within 10 seconds:
11078
```bash
111-
# Stop service
112-
aws ecs update-service \
113-
--cluster elasticsearch-javazone \
114-
--service elasticsearch-javazone \
115-
--desired-count 0
116-
117-
# Delete EFS data (requires EC2 instance or Fargate task with EFS mounted)
118-
# Then restart service
119-
aws ecs update-service \
120-
--cluster elasticsearch-javazone \
121-
--service elasticsearch-javazone \
122-
--desired-count 1
79+
curl -u elastic:pass "http://your-es-url:9200/javazone_talks/_search?q=test"
12380
```
12481

125-
## Cost Estimate
126-
127-
- **Fargate**: ~$25-30/month (1 vCPU, 2GB, always running)
128-
- **EFS**: ~$10-15/month (5-10GB data)
129-
- **SSM**: Free
130-
- **Service Discovery**: Free
131-
132-
**Total: ~$35-45/month**
133-
134-
## Scaling
135-
136-
For higher load (unlikely needed):
137-
- Increase `task_cpu` and `task_memory` in terraform.tfvars
138-
- Apply and restart
139-
140-
For production HA:
141-
- Deploy multiple tasks
142-
- Use Application Load Balancer
143-
- Multiple AZ deployment
144-
145-
But for 10K talks, single task is sufficient.
146-
147-
## Backup
148-
149-
EFS data is persistent, but consider:
150-
- EFS automatic backups (AWS Backup)
151-
- Elasticsearch snapshot repository
152-
- Periodic manual snapshots
82+
---
15383

154-
## Sample Queries
84+
**Total setup time: ~10 minutes**
85+
**Monthly cost: ~$2-5**
15586

156-
See `config/sample-queries.sh` for common Elasticsearch queries.
87+
Perfect! 🎉

terraform/main.tf

Lines changed: 18 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -213,89 +213,23 @@ resource "aws_lambda_event_source_mapping" "sqs_trigger" {
213213
}
214214

215215
################################################################################
216-
# OpenSearch Domain
216+
# Elasticsearch on Coolify
217+
################################################################################
218+
#
219+
# Elasticsearch is deployed on Coolify (external to this Terraform)
220+
#
221+
# Setup in Coolify:
222+
# 1. Deploy elasticsearch:8.11.0 container
223+
# 2. Set environment variables:
224+
# - discovery.type=single-node
225+
# - xpack.security.enabled=true
226+
# - ELASTIC_PASSWORD=<use var.elasticsearch_password>
227+
# - ES_JAVA_OPTS=-Xms1g -Xmx1g
228+
# 3. Expose port 9200
229+
# 4. Add persistent volume for /usr/share/elasticsearch/data
230+
# 5. Note the URL (e.g., http://elasticsearch.your-domain.com:9200)
231+
# 6. Create index using config/index-mapping.json
232+
#
233+
# Cost: Depends on your Coolify hosting (~$0-10/month)
217234
################################################################################
218-
219-
# Security Group for OpenSearch
220-
resource "aws_security_group" "opensearch" {
221-
name = "opensearch-javazone"
222-
description = "OpenSearch for JavaZone"
223-
vpc_id = var.vpc_id
224-
225-
ingress {
226-
from_port = 443
227-
to_port = 443
228-
protocol = "tcp"
229-
cidr_blocks = var.allowed_cidr_blocks
230-
description = "HTTPS for OpenSearch"
231-
}
232-
233-
egress {
234-
from_port = 0
235-
to_port = 0
236-
protocol = "-1"
237-
cidr_blocks = ["0.0.0.0/0"]
238-
}
239-
}
240-
241-
# OpenSearch Domain
242-
resource "aws_opensearch_domain" "javazone" {
243-
domain_name = "javazone-talks"
244-
engine_version = "OpenSearch_2.11"
245-
246-
cluster_config {
247-
instance_type = "t3.small.search" # ~$0.036/hour = ~$26/month
248-
instance_count = 1
249-
zone_awareness_enabled = false
250-
}
251-
252-
ebs_options {
253-
ebs_enabled = true
254-
volume_size = 10 # GB - plenty for 10K talks
255-
volume_type = "gp3"
256-
}
257-
258-
vpc_options {
259-
subnet_ids = [var.es_subnet_ids[0]] # Single AZ for cost savings
260-
security_group_ids = [aws_security_group.opensearch.id]
261-
}
262-
263-
advanced_security_options {
264-
enabled = true
265-
internal_user_database_enabled = true
266-
master_user_options {
267-
master_user_name = var.elasticsearch_username
268-
master_user_password = var.elasticsearch_password
269-
}
270-
}
271-
272-
encrypt_at_rest {
273-
enabled = true
274-
}
275-
276-
node_to_node_encryption {
277-
enabled = true
278-
}
279-
280-
domain_endpoint_options {
281-
enforce_https = true
282-
tls_security_policy = "Policy-Min-TLS-1-2-2019-07"
283-
}
284-
285-
access_policies = jsonencode({
286-
Version = "2012-10-17"
287-
Statement = [{
288-
Effect = "Allow"
289-
Principal = {
290-
AWS = "*"
291-
}
292-
Action = "es:*"
293-
Resource = "arn:aws:es:${var.aws_region}:*:domain/javazone-talks/*"
294-
}]
295-
})
296-
297-
tags = {
298-
Name = "javazone-talks"
299-
}
300-
}
301235

0 commit comments

Comments
 (0)