Skip to content

Commit 3178be7

Browse files
CopilotChaosbit
andcommitted
Add .NET Aspire-inspired backend architecture and IaC tools to devcontainer
Co-authored-by: Chaosbit <[email protected]>
1 parent b84e74c commit 3178be7

File tree

14 files changed

+540
-5
lines changed

14 files changed

+540
-5
lines changed

.devcontainer/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ This repository includes a VS Code Dev Container configuration that provides a c
88
- **Node.js 18**: For frontend development and testing
99
- **.NET 8 SDK**: For backend API development
1010
- **Git & GitHub CLI**: For version control operations
11+
- **Terraform**: For infrastructure as code management
12+
- **Azure CLI**: For Azure cloud deployments
1113
- **Python 3**: For development scripts and utilities
1214
- **SQLite**: For local database development
1315

@@ -17,6 +19,9 @@ This repository includes a VS Code Dev Container configuration that provides a c
1719
- **Jest Test Explorer**: For running and debugging unit tests
1820
- **Playwright**: For end-to-end testing
1921
- **Tailwind CSS**: For CSS IntelliSense
22+
- **Terraform**: For infrastructure as code support
23+
- **Azure CLI**: For Azure cloud integration
24+
- **Azure Resource Groups**: For Azure resource management
2025

2126
### Development Tools
2227
- **Jest**: For unit testing (globally installed)
@@ -52,6 +57,12 @@ This repository includes a VS Code Dev Container configuration that provides a c
5257
# Check .NET
5358
dotnet --version
5459

60+
# Check Terraform
61+
terraform --version
62+
63+
# Check Azure CLI
64+
az --version
65+
5566
# Install dependencies
5667
npm install
5768
cd backend && dotnet restore && cd ..
@@ -86,6 +97,25 @@ dotnet run
8697
dotnet test
8798
```
8899

100+
### Infrastructure Management
101+
```bash
102+
# Navigate to terraform directory
103+
cd terraform
104+
105+
# Initialize Terraform
106+
terraform init
107+
108+
# Plan infrastructure changes
109+
terraform plan
110+
111+
# Apply infrastructure changes
112+
terraform apply
113+
114+
# Check Azure resources
115+
az account show
116+
az group list
117+
```
118+
89119
## Port Forwarding
90120

91121
The container automatically forwards these ports:
@@ -140,6 +170,14 @@ wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.
140170
sudo dpkg -i packages-microsoft-prod.deb
141171
sudo apt-get update && sudo apt-get install -y dotnet-sdk-8.0
142172

173+
# Install Terraform
174+
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
175+
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
176+
sudo apt update && sudo apt install terraform
177+
178+
# Install Azure CLI
179+
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
180+
143181
# Install dependencies
144182
npm install
145183
cd backend && dotnet restore

.devcontainer/devcontainer.json

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
"ms-vscode.test-adapter-converter",
1414
"hbenl.vscode-test-explorer",
1515
"ms-playwright.playwright",
16-
"ms-vscode.vscode-jest"
16+
"ms-vscode.vscode-jest",
17+
"HashiCorp.terraform",
18+
"ms-vscode.azurecli",
19+
"ms-azuretools.vscode-azureresourcegroups",
20+
"ms-azuretools.vscode-azureappservice"
1721
],
1822
"settings": {
1923
"terminal.integrated.defaultProfile.linux": "bash",
@@ -26,7 +30,7 @@
2630
}
2731
}
2832
},
29-
"forwardPorts": [8000, 5000, 3000],
33+
"forwardPorts": [8000, 5000, 3000, 15888],
3034
"portsAttributes": {
3135
"8000": {
3236
"label": "PWA Development Server",
@@ -39,9 +43,13 @@
3943
"3000": {
4044
"label": "Alternative Dev Server",
4145
"protocol": "http"
46+
},
47+
"15888": {
48+
"label": "Aspire Dashboard",
49+
"protocol": "https"
4250
}
4351
},
44-
"postCreateCommand": "npm install && cd backend && dotnet restore",
52+
"postCreateCommand": "npm install && cd backend && dotnet restore && dotnet workload install aspire",
4553
"remoteUser": "vscode",
4654
"features": {
4755
"ghcr.io/devcontainers/features/node:1": {
@@ -51,6 +59,12 @@
5159
"version": "8.0"
5260
},
5361
"ghcr.io/devcontainers/features/git:1": {},
54-
"ghcr.io/devcontainers/features/github-cli:1": {}
62+
"ghcr.io/devcontainers/features/github-cli:1": {},
63+
"ghcr.io/devcontainers/features/terraform:1": {
64+
"version": "latest"
65+
},
66+
"ghcr.io/devcontainers/features/azure-cli:1": {
67+
"version": "latest"
68+
}
5569
}
5670
}

backend/README.md

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
# .NET Aspire-Inspired Backend
2+
3+
This backend implementation uses .NET Aspire-inspired patterns for observability, health checks, and service orchestration while maintaining compatibility with standard .NET 8 tooling.
4+
5+
## Architecture
6+
7+
The backend consists of several projects organized in an Aspire-like structure:
8+
9+
### Projects
10+
11+
- **WorkoutApp.Api**: The main Web API project with controllers and business logic
12+
- **WorkoutApp.ServiceDefaults**: Shared service configuration for observability and health checks
13+
- **WorkoutApp.AppHost**: Simple orchestration host for development scenarios
14+
- **WorkoutApp.Tests**: Unit and integration tests
15+
16+
### Key Features
17+
18+
- **OpenTelemetry Integration**: Comprehensive observability with metrics, tracing, and logging
19+
- **Health Checks**: Built-in health endpoints for monitoring application status
20+
- **Service Defaults**: Standardized configuration for all services
21+
- **JWT Authentication**: Secure API authentication with proper validation
22+
- **Entity Framework**: SQLite for development, easily configurable for other databases
23+
24+
## Getting Started
25+
26+
### Prerequisites
27+
28+
- .NET 8.0 SDK
29+
- SQLite (included with .NET)
30+
31+
### Development Commands
32+
33+
```bash
34+
# Restore packages
35+
npm run backend:restore
36+
37+
# Build the solution
38+
npm run backend:build
39+
40+
# Run the API directly
41+
npm run backend:api
42+
43+
# Run the orchestration host (development)
44+
npm run backend:apphost
45+
46+
# Run tests
47+
npm run test:backend
48+
```
49+
50+
### Manual Commands
51+
52+
```bash
53+
cd backend
54+
55+
# Restore and build
56+
dotnet restore
57+
dotnet build
58+
59+
# Run the API service
60+
dotnet run --project WorkoutApp.Api
61+
62+
# Run the orchestration host
63+
dotnet run --project WorkoutApp.AppHost
64+
65+
# Run tests
66+
dotnet test
67+
```
68+
69+
## Service Defaults
70+
71+
The `WorkoutApp.ServiceDefaults` project provides:
72+
73+
### OpenTelemetry Configuration
74+
- **Metrics**: ASP.NET Core, HTTP Client, and Runtime metrics
75+
- **Tracing**: Request tracing across services
76+
- **Logging**: Structured logging with OpenTelemetry
77+
78+
### Health Checks
79+
- **/health**: Overall application health
80+
- **/alive**: Liveness probe (development only)
81+
82+
### HTTP Client Configuration
83+
- Standard timeout settings
84+
- Basic resilience patterns
85+
86+
## API Endpoints
87+
88+
The API provides the following endpoints:
89+
90+
### Authentication
91+
- `POST /api/auth/register` - User registration
92+
- `POST /api/auth/login` - User login
93+
94+
### Workouts
95+
- `GET /api/workouts` - Get user workouts
96+
- `POST /api/workouts` - Create new workout
97+
- `PUT /api/workouts/{id}` - Update workout
98+
- `DELETE /api/workouts/{id}` - Delete workout
99+
100+
### Statistics
101+
- `GET /api/statistics` - Get user statistics
102+
- `POST /api/statistics` - Update statistics
103+
104+
### Health & Monitoring
105+
- `GET /health` - Health check endpoint (development)
106+
- `GET /alive` - Liveness check (development)
107+
108+
## Configuration
109+
110+
### Database Connection
111+
112+
The default configuration uses SQLite:
113+
114+
```json
115+
{
116+
"ConnectionStrings": {
117+
"DefaultConnection": "Data Source=workout-app.db"
118+
}
119+
}
120+
```
121+
122+
### JWT Settings
123+
124+
Configure JWT authentication:
125+
126+
```json
127+
{
128+
"JwtSettings": {
129+
"Secret": "your-secret-key-here",
130+
"ExpirationInDays": 7
131+
}
132+
}
133+
```
134+
135+
### User Registration
136+
137+
Control user registration behavior:
138+
139+
```json
140+
{
141+
"UserRegistration": {
142+
"RequireApproval": false,
143+
"RequireReferralCode": false
144+
}
145+
}
146+
```
147+
148+
## Observability
149+
150+
### OpenTelemetry Exporter
151+
152+
To use OTLP exporter, set the environment variable:
153+
154+
```bash
155+
export OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4317
156+
```
157+
158+
### Metrics Available
159+
160+
- HTTP request duration and count
161+
- Database operation metrics
162+
- Runtime performance metrics
163+
- Custom application metrics
164+
165+
### Distributed Tracing
166+
167+
Traces are automatically created for:
168+
- HTTP requests
169+
- Database operations
170+
- External HTTP calls
171+
172+
## Development Tips
173+
174+
### Running with Hot Reload
175+
176+
```bash
177+
cd backend
178+
dotnet watch run --project WorkoutApp.Api
179+
```
180+
181+
### Database Migrations
182+
183+
The application automatically creates the database on startup. For production, consider using explicit migrations:
184+
185+
```bash
186+
dotnet ef migrations add InitialCreate --project WorkoutApp.Api
187+
dotnet ef database update --project WorkoutApp.Api
188+
```
189+
190+
### Testing
191+
192+
Run different test suites:
193+
194+
```bash
195+
# All tests
196+
dotnet test
197+
198+
# Specific test project
199+
dotnet test WorkoutApp.Tests
200+
201+
# With coverage
202+
dotnet test --collect:"XPlat Code Coverage"
203+
```
204+
205+
## Deployment
206+
207+
The backend can be deployed as:
208+
209+
1. **Single API Service**: Deploy only `WorkoutApp.Api`
210+
2. **Container**: Use the provided Dockerfile
211+
3. **Azure App Service**: Use the provided ARM templates
212+
4. **Container Orchestration**: Deploy as microservices
213+
214+
## Differences from Full .NET Aspire
215+
216+
This implementation provides Aspire-like benefits without requiring the full Aspire workload:
217+
218+
- **✅ Included**: OpenTelemetry, Health Checks, Service Configuration
219+
- **✅ Included**: Structured project organization
220+
- **❌ Not Included**: Full service discovery
221+
- **❌ Not Included**: Advanced resilience patterns
222+
- **❌ Not Included**: Aspire Dashboard integration
223+
224+
For production scenarios requiring full Aspire features, upgrade to the official .NET Aspire packages when they reach stable release.
225+
226+
## Troubleshooting
227+
228+
### Build Issues
229+
230+
If you encounter build issues:
231+
232+
```bash
233+
# Clean and rebuild
234+
dotnet clean
235+
dotnet restore
236+
dotnet build
237+
```
238+
239+
### Database Issues
240+
241+
If database connection fails:
242+
243+
1. Check SQLite file permissions
244+
2. Verify connection string in `appsettings.json`
245+
3. Delete `workout-app.db` to recreate database
246+
247+
### Authentication Issues
248+
249+
If JWT authentication fails:
250+
251+
1. Verify `JwtSettings:Secret` is configured
252+
2. Check token expiration settings
253+
3. Ensure proper Authorization header format: `Bearer <token>`

backend/WorkoutApp.Api/Program.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
var builder = WebApplication.CreateBuilder(args);
1010

11+
// Add Aspire service defaults (observability, health checks, service discovery)
12+
builder.AddServiceDefaults();
13+
1114
// Add services to the container.
1215

1316
builder.Services.AddControllers();
@@ -104,6 +107,9 @@
104107

105108
app.MapControllers();
106109

110+
// Map Aspire default endpoints (health checks)
111+
app.MapDefaultEndpoints();
112+
107113
app.Run();
108114

109115
// Make Program class accessible for integration tests

0 commit comments

Comments
 (0)