Skip to content

Commit 4597132

Browse files
authored
feat: add Terraform infrastructure setup (#2082)
1 parent 6a9e47e commit 4597132

33 files changed

+748
-8
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Terraform Infrastructure Review Checklist
2+
3+
## Structure & Organization
4+
5+
### Module Structure
6+
7+
- [ ] Each module has separate `main.tf`, `variables.tf`, `outputs.tf`, and `provider.tf` files
8+
- [ ] Module dependencies are clearly defined and minimal
9+
- [ ] Modules are reusable across environments (preview, staging, prod)
10+
11+
### Directory Layout
12+
13+
- [ ] Clear separation between modules (`modules/`) and environments (`environments/`)
14+
- [ ] Consistent file naming conventions across all modules and environments
15+
- [ ] No hardcoded environment-specific values in modules
16+
17+
## Configuration Standards
18+
19+
### Provider Configuration
20+
21+
- [ ] All modules specify required providers with correct source (`cloudflare/cloudflare`)
22+
- [ ] Provider version constraints are consistent across modules (`~> 5.0`)
23+
- [ ] No legacy provider references (`hashicorp/cloudflare`)
24+
25+
### Variable Management
26+
27+
- [ ] All variables have proper descriptions and type definitions
28+
- [ ] Input validation rules are implemented where appropriate
29+
- [ ] Variables follow naming conventions (snake_case)
30+
- [ ] `terraform.tfvars.example` files exist and are up-to-date
31+
32+
### Resource Naming
33+
34+
- [ ] Resources use consistent naming: `${var.project_name}-${var.environment}`
35+
- [ ] Names comply with Cloudflare resource naming requirements
36+
- [ ] No hardcoded resource names
37+
38+
## Security & Best Practices
39+
40+
### State Management
41+
42+
- [ ] Backend configuration is appropriate for each environment:
43+
- Preview: Local backend
44+
- Staging/Prod: Remote backend (S3)
45+
- [ ] State files are not committed to version control
46+
- [ ] Backend encryption is enabled for remote state
47+
48+
### Secrets & Sensitive Data
49+
50+
- [ ] No hardcoded API keys, tokens, or sensitive values
51+
- [ ] Sensitive outputs are marked as `sensitive = true`
52+
- [ ] `terraform.tfvars` files are git-ignored
53+
54+
### Access Control
55+
56+
- [ ] Cloudflare account ID validation is in place
57+
- [ ] Resource permissions follow least-privilege principle
58+
59+
## Environment-Specific Configuration
60+
61+
### Environment Consistency
62+
63+
- [ ] All environments use the same module versions
64+
- [ ] Environment-specific differences are minimal and documented
65+
- [ ] Module calls are consistent across environments
66+
67+
### Resource Allocation
68+
69+
- [ ] Preview environment has appropriate resource limits
70+
- [ ] Production environment includes additional resources (KV namespace)
71+
- [ ] Staging environment matches production configuration
72+
73+
## Testing & Validation
74+
75+
### Code Quality
76+
77+
- [ ] Terraform formatting is consistent (`terraform fmt`)
78+
- [ ] Configuration is valid (`terraform validate`)
79+
- [ ] No unused variables or outputs
80+
- [ ] Clear documentation for complex logic
81+
82+
### Deployment Testing
83+
84+
- [ ] `terraform plan` runs successfully for all environments
85+
- [ ] Module interdependencies work correctly
86+
- [ ] Resource creation order is optimized
87+
88+
## Monitoring & Maintenance
89+
90+
### Documentation
91+
92+
- [ ] Module purposes and usage are documented
93+
- [ ] Environment setup instructions are clear
94+
- [ ] Variable requirements are documented
95+
96+
### Version Management
97+
98+
- [ ] Provider versions are pinned appropriately
99+
- [ ] Module versions are tracked if using external modules
100+
- [ ] Upgrade paths are documented
101+
102+
## Deployment Readiness
103+
104+
### Infrastructure as Code
105+
106+
- [ ] All infrastructure is defined in Terraform
107+
- [ ] Manual changes are avoided
108+
- [ ] Drift detection strategies are in place
109+
110+
### Automation
111+
112+
- [ ] CI/CD pipeline integration is considered
113+
- [ ] Automated testing for infrastructure changes
114+
- [ ] Rollback procedures are documented
115+
116+
---
117+
118+
## Review Commands
119+
120+
```bash
121+
# Navigate to environment
122+
cd infra/environments/{preview|staging|prod}
123+
124+
# Basic validation
125+
terraform fmt -check
126+
terraform validate
127+
terraform plan
128+
129+
# Security checks
130+
terraform providers
131+
grep -r "hardcoded" .
132+
grep -r "TODO\|FIXME" .
133+
134+
# State inspection
135+
terraform state list
136+
terraform show
137+
```

.github/workflows/main.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,19 @@ jobs:
4747
if: ${{ github.event_name == 'pull_request' }}
4848
- run: bun lint
4949
if: ${{ github.event_name == 'pull_request' }}
50+
5051
- run: bun --filter app build
5152
- run: bun tsc --build
5253
# - run: bun --filter app test
5354
# if: ${{ github.event_name == 'pull_request' }}
5455
# - run: bun --filter edge test
5556
# if: ${{ github.event_name == 'pull_request' }}
5657

58+
# Validate Terraform configuration and formatting
59+
- uses: hashicorp/setup-terraform@v3
60+
- run: terraform fmt -check -recursive infra/
61+
# - run: terraform validate infra/environments/preview/
62+
5763
# Compile
5864
- run: bun run build
5965

.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ node_modules/
4040
# https://developers.cloudflare.com/workers/wrangler/
4141
.wrangler/
4242

43+
# Terraform
44+
# https://github.com/github/gitignore/blob/main/Terraform.gitignore
45+
*.tfstate
46+
*.tfstate.*
47+
.terraform/
48+
.terraform.lock.hcl
49+
*.tfvars
50+
*.tfvars.json
51+
override.tf
52+
override.tf.json
53+
*_override.tf
54+
*_override.tf.json
55+
.terraformrc
56+
terraform.rc
57+
4358
# TanStack Router
4459
# Generated route tree files should not be committed
4560
*/lib/routeTree.gen.ts

.prettierignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
# TypeScript
1414
/tsconfig.base.json
1515

16+
# Terraform
17+
.terraform/
18+
1619
# Misc
1720
/.husky
1821
*.hbs
19-

.vscode/extensions.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"esbenp.prettier-vscode",
99
"github.copilot",
1010
"github.vscode-github-actions",
11+
"hashicorp.terraform",
1112
"mikestead.dotenv",
1213
"oven.bun-vscode",
1314
"rphlmr.vscode-drizzle-orm",

README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,21 @@ Designed for developers who value both speed and quality, this template provides
2323
---
2424

2525
This project was bootstrapped with [React Starter Kit](https://github.com/kriasoft/react-starter-kit).
26-
Be sure to join our [Discord channel](https://discord.com/invite/2nKEnKq) for assistance.
26+
Be sure to join our [Discord channel](https://discord.gg/2nKEnKq) for assistance.
2727

2828
## Monorepo Architecture
2929

3030
This starter kit uses a thoughtfully organized monorepo structure that promotes code reuse and maintainability:
3131

32-
`├──`[`app/`](./app) — React frontend with Vite, TanStack Router, and Tailwind CSS<br>
33-
`├──`[`api/`](./api) — tRPC API server powered by Hono framework<br>
34-
`├──`[`edge/`](./edge) — Cloudflare Workers entry point for edge deployment<br>
35-
`├──`[`core/`](./core) — Shared TypeScript types and utilities<br>
36-
`├──`[`db/`](./db) — Database schemas, migrations, and seed data<br>
37-
`├──`[`scripts/`](./scripts) — Build automation and development tools<br>
32+
- [`app/`](./app) — React frontend with Vite, TanStack Router, and Tailwind CSS
33+
- [`api/`](./api) — tRPC API server powered by Hono framework
34+
- [`edge/`](./edge) — Cloudflare Workers entry point for edge deployment
35+
- [`core/`](./core) — Shared TypeScript types, utilities, and WebSocket communication
36+
- [`db/`](./db) — Database schemas, migrations, and seed data
37+
- [`docs/`](./docs) — VitePress documentation site
38+
- [`infra/`](./infra) — Terraform infrastructure configurations for multi-environment deployment
39+
- [`scripts/`](./scripts) — Build automation and development tools
40+
- [`app/scripts/`](./app/scripts) — ShadCN UI component management utilities
3841

3942
**Why Monorepo?** This structure enables seamless code sharing between frontend and backend, ensures type consistency across your entire stack, and simplifies dependency management. When you update a type definition, both client and server stay in sync automatically.
4043

infra/README.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Infrastructure
2+
3+
Terraform configuration for deploying this application to a cloud provider.
4+
5+
## Structure
6+
7+
- `environments/` - Environment-specific configurations (`preview`, `staging`, `prod`)
8+
- `modules/` - Reusable Terraform modules for database and storage
9+
10+
## Modules
11+
12+
### Database (`modules/db`)
13+
14+
- Creates Cloudflare D1 (or, Neon) database for each environment
15+
- Names: `{project-name}-{environment}`
16+
17+
### Storage (`modules/storage`)
18+
19+
- Creates R2 buckets for file storage
20+
- Main bucket: `{project-name}-{environment}`
21+
- Uploads bucket: `{project-name}-uploads-{environment}`
22+
23+
## Environments
24+
25+
Each environment includes:
26+
27+
- `main.tf` - Module instantiation
28+
- `variables.tf` - Input variables
29+
- `outputs.tf` - Output values
30+
- `provider.tf` - Provider configuration
31+
- `backend.tf` - Remote state configuration
32+
- `terraform.tfvars.example` - Example variables
33+
- `terraform.tfvars` - Environment-specific variables
34+
35+
## Usage
36+
37+
```bash
38+
# Navigate to environment
39+
cd environments/preview
40+
41+
# Copy and configure variables
42+
cp terraform.tfvars.example terraform.tfvars
43+
# Edit terraform.tfvars with your values
44+
45+
# Initialize and apply
46+
terraform init
47+
terraform plan
48+
terraform apply
49+
```
50+
51+
## Requirements
52+
53+
- Terraform >= 1.12
54+
- Cloudflare account with API token
55+
- Required variables: `project_name` (lowercase, hyphens only), `cloudflare_account_id`
56+
57+
## Development Setup
58+
59+
For the best development experience with Terraform files:
60+
61+
- **VS Code**: Install the HashiCorp Terraform extension (included in project recommendations)
62+
- **Formatting**: Run `terraform fmt -recursive` to format all .tf files
63+
- **Validation**: Use `terraform validate` to check syntax before applying
64+
65+
## Security
66+
67+
### API Token Permissions
68+
69+
Your Cloudflare API token needs the following permissions:
70+
71+
- **Zone:Zone:Read** (for domain management)
72+
- **Zone:Zone Settings:Edit** (for configuration)
73+
- **Account:Cloudflare D1:Edit** (for database creation)
74+
- **Account:Cloudflare R2:Edit** (for storage buckets)
75+
76+
### Secrets Management
77+
78+
- Keep `terraform.tfvars` files secure and never commit them to version control
79+
- The `.gitignore` should include `*.tfvars` (except `.example` files)
80+
- Store sensitive values in environment variables when possible
81+
82+
## State Management
83+
84+
This configuration uses remote state storage for team collaboration:
85+
86+
- State files are stored in Cloudflare R2 (configured in `backend.tf`)
87+
- Each environment maintains separate state files
88+
- Initialize with `terraform init` to download remote state
89+
- State locking prevents concurrent modifications
90+
91+
## Outputs
92+
93+
After successful deployment, use outputs to configure your application:
94+
95+
```bash
96+
# Get database ID for wrangler.jsonc
97+
terraform output database_id
98+
99+
# Get R2 bucket names for environment variables
100+
terraform output storage_bucket_name
101+
terraform output uploads_bucket_name
102+
```
103+
104+
Add these values to your application's environment configuration.
105+
106+
## Troubleshooting
107+
108+
### Common Issues
109+
110+
**Authentication Error**
111+
112+
```
113+
Error: Authentication error (10000)
114+
```
115+
116+
- Verify your Cloudflare API token has correct permissions
117+
- Check `CLOUDFLARE_API_TOKEN` environment variable is set
118+
119+
**Resource Already Exists**
120+
121+
```
122+
Error: resource already exists
123+
```
124+
125+
- Check if resources exist in Cloudflare dashboard
126+
- Import existing resources: `terraform import <resource> <id>`
127+
128+
**State Lock Error**
129+
130+
```
131+
Error: state locked
132+
```
133+
134+
- Another user may be running terraform
135+
- Force unlock (use carefully): `terraform force-unlock <lock-id>`
136+
137+
**Invalid Project Name**
138+
139+
```
140+
Error: invalid project name
141+
```
142+
143+
- Use only lowercase letters, numbers, and hyphens
144+
- Must start with a letter, max 63 characters
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Preview environment uses local backend for simplicity
2+
# For production use, consider using S3 or Terraform Cloud

infra/environments/preview/main.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Preview Environment Configuration
2+
3+
module "db" {
4+
source = "../../modules/db"
5+
6+
project_name = var.project_name
7+
environment = "preview"
8+
account_id = var.cloudflare_account_id
9+
}
10+
11+
module "storage" {
12+
source = "../../modules/storage"
13+
14+
project_name = var.project_name
15+
environment = "preview"
16+
account_id = var.cloudflare_account_id
17+
}

0 commit comments

Comments
 (0)