Skip to content

Commit 09aca64

Browse files
committed
update docs
1 parent 3e54c50 commit 09aca64

File tree

3 files changed

+155
-138
lines changed

3 files changed

+155
-138
lines changed

terraform/aws/QUICKSTART.md

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,17 @@ cp terraform.tfvars.example terraform.tfvars
2222
vim terraform.tfvars
2323
```
2424

25-
Set required parameters:
25+
Uncomment and set all required parameters:
2626
- `ssh_key_name` - your AWS SSH key name
27-
- `grafana_password` - custom password (optional, defaults to "demo")
27+
- `aws_region` - AWS region
28+
- `environment` - environment name
29+
- `instance_type` - EC2 instance type (e.g., t3.medium)
30+
- `data_volume_size` - data disk size in GiB
31+
- `data_volume_type` / `root_volume_type` - volume types (gp3, st1, sc1)
32+
- `allowed_ssh_cidr` / `allowed_cidr_blocks` - CIDR blocks for access
33+
- `use_elastic_ip` - allocate Elastic IP (true/false)
34+
- `grafana_password` - Grafana admin password
35+
- `postgres_ai_version` - git branch/tag (optional, defaults to "main")
2836

2937
## Add monitoring instances
3038

@@ -45,12 +53,14 @@ monitoring_instances = [
4553
## Deploy
4654

4755
```bash
48-
# Validate
49-
./validate.sh
50-
51-
# Deploy
56+
# Initialize and validate
5257
terraform init
58+
terraform validate
59+
60+
# Review changes
5361
terraform plan
62+
63+
# Deploy
5464
terraform apply
5565

5666
# Get access info
@@ -63,10 +73,10 @@ terraform output ssh_command
6373
```bash
6474
# Grafana dashboard
6575
open $(terraform output -raw grafana_url)
66-
# Login: monitor / demo (or your custom password)
76+
# Login: monitor / <password from terraform.tfvars>
6777

6878
# SSH
69-
ssh -i ~/.ssh/postgres-ai-key.pem ubuntu@$(terraform output -raw public_ip)
79+
ssh -i ~/.ssh/postgres-ai-key.pem ubuntu@$(terraform output -raw external_ip)
7080
```
7181

7282
## Operations
@@ -95,3 +105,17 @@ ssh ubuntu@IP "sudo systemctl status postgres-ai"
95105
ssh ubuntu@IP "sudo docker ps"
96106
```
97107

108+
## Security notes
109+
110+
Credentials (passwords, connection strings) are stored in `terraform.tfstate` in plain text. For one-off/dev deployments this is acceptable if you clean up after `terraform destroy`:
111+
112+
```bash
113+
terraform destroy
114+
rm -rf .terraform/ terraform.tfstate*
115+
```
116+
117+
For production deployments, consider:
118+
- Using environment variables: `export TF_VAR_grafana_password=...`
119+
- Remote state with encryption (S3 + encryption)
120+
- Configuring monitoring instances manually after deployment
121+

terraform/aws/README.md

Lines changed: 123 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -8,98 +8,100 @@ Single EC2 instance with Docker Compose.
88

99
Terraform creates:
1010
- VPC with public subnet
11-
- EC2 instance (t3.medium, Ubuntu 22.04 LTS)
12-
- EBS volume (50 GiB gp3, encrypted)
11+
- EC2 instance (Ubuntu 22.04 LTS)
12+
- EBS volumes (configurable types: gp3, st1, sc1, encrypted)
1313
- Security Group (SSH + Grafana ports)
1414
- Elastic IP (optional)
1515

16-
On first boot, EC2 instance clones this repository and runs `docker-compose up` to start all monitoring services.
16+
On first boot, EC2 instance clones the specified version of this repository and runs `docker-compose up` to start all monitoring services.
1717

1818
## Quick start
1919

2020
See [QUICKSTART.md](QUICKSTART.md) for step-by-step guide.
2121

22-
## Configuration
22+
### Validation
2323

24-
### Minimal setup
24+
```bash
25+
# Check prerequisites
26+
terraform version
27+
aws sts get-caller-identity
28+
29+
# Validate configuration
30+
terraform init
31+
terraform validate
32+
terraform plan
33+
```
2534

26-
```hcl
27-
# terraform.tfvars
28-
ssh_key_name = "postgres-ai-key"
35+
## Configuration
2936

30-
# Optional: Set custom Grafana password (defaults to 'demo')
31-
# grafana_password = "YourSecurePassword123!"
32-
```
37+
### Required parameters
3338

34-
### Minimal production setup
39+
All parameters in `terraform.tfvars` must be explicitly set (uncommented):
3540

3641
```hcl
3742
# terraform.tfvars
3843
3944
# REQUIRED PARAMETERS
40-
ssh_key_name = "your-key-name"
41-
42-
# AWS SETTINGS
43-
aws_region = "us-east-1"
44-
environment = "production"
45-
instance_type = "t3.medium"
46-
47-
# STORAGE
48-
data_volume_size = 50 # GiB
45+
ssh_key_name = "your-key-name"
46+
aws_region = "us-east-1"
47+
environment = "production"
48+
instance_type = "t3.medium"
49+
data_volume_size = 50
50+
data_volume_type = "gp3" # gp3 (SSD), st1 (HDD), sc1 (HDD)
51+
root_volume_type = "gp3"
52+
allowed_ssh_cidr = ["203.0.113.0/24"]
53+
allowed_cidr_blocks = ["203.0.113.0/24"]
54+
use_elastic_ip = true
55+
grafana_password = "YourSecurePassword123!"
56+
```
4957

50-
# SECURITY (restrict access!)
51-
allowed_ssh_cidr = ["0.0.0.0/0"] # WARNING: Allows access from anywhere
52-
allowed_cidr_blocks = ["0.0.0.0/0"] # WARNING: Allows access from anywhere
58+
### Optional parameters
5359

54-
# OPTIONAL PARAMETERS
55-
# grafana_password = "YourSecurePassword123!" # Defaults to 'demo'
56-
# postgres_ai_api_key = "your-api-key" # For uploading reports
57-
# enable_demo_db = false # true for testing
58-
# use_elastic_ip = true # Stable IP address
60+
```hcl
61+
# OPTIONAL (have defaults)
62+
postgres_ai_api_key = "your-api-key" # For uploading reports
63+
enable_demo_db = false # Demo database (default: true)
64+
postgres_ai_version = "main" # Git branch/tag (default: "main")
5965
6066
monitoring_instances = [
6167
{
62-
name = "main-db"
63-
conn_str = "postgresql://monitor:pass@db.example.com:5432/postgres"
68+
name = "main-db"
69+
conn_str = "postgresql://monitor:pass@db.example.com:5432/postgres"
6470
environment = "production"
65-
cluster = "main"
66-
node_name = "primary"
71+
cluster = "main"
72+
node_name = "primary"
6773
}
6874
]
6975
```
7076

71-
### Full configuration
77+
### Full example
7278

7379
```hcl
74-
# AWS
75-
aws_region = "us-east-1"
76-
environment = "production"
77-
instance_type = "t3.medium"
78-
79-
# Storage
80-
data_volume_size = 50
81-
82-
# Security (restrict access in production)
83-
allowed_ssh_cidr = ["203.0.113.0/24"]
84-
allowed_cidr_blocks = ["203.0.113.0/24"]
85-
86-
# Required
87-
ssh_key_name = "ssh-key"
88-
89-
# Optional
90-
grafana_password = "SecurePassword123!" # Defaults to 'demo'
91-
postgres_ai_api_key = "your-api-key"
92-
enable_demo_db = false
93-
use_elastic_ip = true
80+
# REQUIRED
81+
ssh_key_name = "postgres-ai-key"
82+
aws_region = "us-east-1"
83+
environment = "production"
84+
instance_type = "t3.medium"
85+
data_volume_size = 100
86+
data_volume_type = "gp3"
87+
root_volume_type = "gp3"
88+
allowed_ssh_cidr = ["203.0.113.0/24"]
89+
allowed_cidr_blocks = ["203.0.113.0/24"]
90+
use_elastic_ip = true
91+
grafana_password = "SecurePassword123!"
92+
93+
# OPTIONAL
94+
postgres_ai_api_key = "your-api-key"
95+
enable_demo_db = false
96+
postgres_ai_version = "v0.9"
9497
95-
# Monitoring instances
9698
monitoring_instances = [
9799
{
98-
name = "prod-db"
99-
conn_str = "postgresql://monitor:pass@db.example.com:5432/postgres"
100+
name = "prod-db"
101+
conn_str = "postgresql://monitor:pass@db.example.com:5432/postgres"
100102
environment = "production"
101-
cluster = "main"
102-
node_name = "primary"
103+
cluster = "main"
104+
node_name = "primary"
103105
}
104106
]
105107
```
@@ -111,7 +113,7 @@ monitoring_instances = [
111113
```bash
112114
terraform output ssh_command
113115
# Or directly:
114-
ssh -i ~/.ssh/postgres-ai-key.pem ubuntu@$(terraform output -raw public_ip)
116+
ssh -i ~/.ssh/postgres-ai-key.pem ubuntu@$(terraform output -raw external_ip)
115117
```
116118

117119
### Service management
@@ -132,14 +134,19 @@ sudo systemctl restart postgres-ai
132134

133135
### Add monitoring instance
134136

135-
Method 1: Update terraform.tfvars and run `terraform apply`
137+
Method 1: Update `terraform.tfvars` and apply changes:
138+
```bash
139+
# Edit terraform.tfvars, add to monitoring_instances array
140+
terraform apply
141+
# Automatically updates instances.yml and restarts pgwatch services
142+
```
136143

137-
Method 2: Manual configuration on server:
144+
Method 2: Manual configuration (avoids credentials in state):
138145
```bash
139146
ssh ubuntu@your-ip
140147
cd /home/postgres_ai/postgres_ai
141148
sudo -u postgres_ai vim instances.yml
142-
sudo docker-compose restart
149+
sudo -u postgres_ai ./postgres_ai update-config
143150
```
144151

145152
### Backup
@@ -247,16 +254,16 @@ ssh ubuntu@your-ip "sudo resize2fs /dev/nvme1n1"
247254
Choose instance type based on monitoring workload:
248255

249256
```hcl
250-
instance_type = "t3.medium" # 2 vCPU, 4 GiB RAM
257+
instance_type = "t3.small" # 2 vCPU, 2 GiB RAM
251258
```
252259

253260
Suitable for:
254-
- Monitoring 1-3 small databases
261+
- Monitoring 1-2 small databases
255262
- Dev/test environments
256263
- Proof of concept
257264

258265
```hcl
259-
instance_type = "t3.medium" # 2 vCPU, 8 GiB RAM (default)
266+
instance_type = "t3.medium" # 2 vCPU, 4 GiB RAM
260267
```
261268

262269
Suitable for:
@@ -271,6 +278,28 @@ Suitable for:
271278
- Monitoring 10+ databases
272279
- High-frequency metric collection
273280

281+
## Storage options
282+
283+
### Volume types
284+
285+
```hcl
286+
# SSD (recommended for production)
287+
data_volume_type = "gp3" # General Purpose SSD
288+
root_volume_type = "gp3"
289+
290+
# HDD (lower cost for testing)
291+
data_volume_type = "st1" # Throughput Optimized HDD (min 125 GiB)
292+
data_volume_type = "sc1" # Cold HDD (min 125 GiB)
293+
```
294+
295+
### Volume sizing
296+
297+
```hcl
298+
data_volume_size = 50 # Small deployments
299+
data_volume_size = 100 # Medium deployments
300+
data_volume_size = 500 # Large deployments
301+
```
302+
274303
## Custom domain
275304

276305
```bash
@@ -284,7 +313,7 @@ aws route53 change-resource-record-sets \
284313
"Name": "monitoring.example.com",
285314
"Type": "A",
286315
"TTL": 300,
287-
"ResourceRecords": [{"Value": "'"$(terraform output -raw public_ip)"'"}]
316+
"ResourceRecords": [{"Value": "'"$(terraform output -raw external_ip)"'"}]
288317
}
289318
}]
290319
}'
@@ -315,3 +344,30 @@ This deployment is appropriate for:
315344
- Teams with Linux administration skills
316345

317346
For production-critical systems requiring high availability, consider managed services (RDS, ECS Fargate) instead.
347+
348+
## Security considerations
349+
350+
### Credentials in Terraform state
351+
352+
All credentials (passwords, connection strings) are stored in plain text in `terraform.tfstate`. This is acceptable for:
353+
- Development and testing
354+
- One-off monitoring deployments
355+
- When state files are properly secured
356+
357+
For production deployments:
358+
- Use remote state with encryption (S3 + KMS)
359+
- Use environment variables: `export TF_VAR_grafana_password=...`
360+
- Configure monitoring instances manually after deployment (Method 2)
361+
- Store state in private repositories only
362+
363+
### IMDSv2
364+
365+
EC2 instances are configured to require IMDSv2 (Instance Metadata Service v2) for enhanced security against SSRF attacks.
366+
367+
### Cleanup
368+
369+
After destroying infrastructure, remove local state files:
370+
```bash
371+
terraform destroy
372+
rm -rf .terraform/ terraform.tfstate*
373+
```

0 commit comments

Comments
 (0)