Skip to content

Commit efb8201

Browse files
committed
(fix) Coder now configured and installed as part of initial deploy
1 parent 96b89c9 commit efb8201

File tree

10 files changed

+376
-18
lines changed

10 files changed

+376
-18
lines changed

CLAUDE.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,12 @@ This is a **Terraform-based Infrastructure as Code (IaC)** project that deploys
4747
# Deploy development environment with specific template
4848
./scripts/lifecycle/setup.sh --env=dev --template=python-django-crewai
4949

50-
# Deploy production with monitoring and HA
50+
# Deploy production with monitoring and HA (template optional)
5151
./scripts/lifecycle/setup.sh --env=prod --enable-monitoring --enable-ha
5252

53+
# Deploy Coder without templates (templates can be added later)
54+
./scripts/lifecycle/setup.sh --env=dev
55+
5356
# Dry run to preview changes
5457
./scripts/lifecycle/setup.sh --env=staging --dry-run
5558

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,12 @@ gh run watch
189189

190190
### What Happens Next?
191191
- **Infrastructure Creation**: Kubernetes cluster, database, and networking (~10 min)
192-
- **Coder Installation**: Platform deployment and configuration (~5 min)
193-
- **Template Deployment**: Your selected workspace template (if specified)
192+
- **Coder Installation**: Platform deployment and configuration (~5 min) - **Automatic**
193+
- **Template Deployment**: Your selected workspace template (if specified) - **Optional**
194194
- **Access Details**: URLs and credentials will be displayed upon completion
195195

196+
> **Note**: Coder is automatically deployed and ready to use regardless of whether you specify a template. Templates are optional and can be added later if not specified during initial deployment.
197+
196198
## 🏗️ Multi-Environment Architecture
197199

198200
| Environment | Monthly Cost | Use Case | Resources |

docs/TEMPLATES.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
This document provides a comprehensive listing of all available Coder workspace templates in this project. These templates can be used with the `--template` parameter in deployment scripts and GitHub Actions.
44

5+
## Template Deployment Behavior
6+
7+
**Important**: Templates are **optional** during deployment. The system behavior is:
8+
9+
- **With Template**: Deploys Coder + automatically installs the specified template
10+
- **Without Template**: Deploys Coder ready for use, templates can be added later
11+
- **Result**: You always get a fully functional Coder environment regardless of template selection
12+
13+
Templates are workspace blueprints that define the development environment (languages, tools, IDE configuration) for users to create workspaces from.
14+
515
## Overview
616

717
The project includes **21 workspace templates** organized into **6 categories**, providing development environments for modern web development, AI-enhanced workflows, data science, mobile development, and DevOps practices.
@@ -60,12 +70,14 @@ on:
6070
type: choice
6171
options: [dev, staging, prod]
6272
template:
63-
description: 'Template to deploy'
64-
required: true
65-
type: choice
66-
options: [
67-
'claude-flow-base', 'claude-flow-enterprise', 'dotnet-core', 'go-fiber', 'java-spring', 'php-symfony-neuron', 'python-django-crewai', 'ruby-rails', 'rust-actix', 'jupyter-python', 'r-studio', 'docker-compose', 'kubernetes-helm', 'terraform-ansible', 'angular', 'react-typescript', 'svelte-kit', 'vue-nuxt', 'flutter', 'ionic', 'react-native'
68-
]
73+
description: 'Template to deploy (optional - leave blank to deploy Coder without templates)'
74+
required: false
75+
type: string
76+
# Alternative: Use choice with empty option
77+
# type: choice
78+
# options: [
79+
# '', 'claude-flow-base', 'claude-flow-enterprise', 'dotnet-core', 'go-fiber', 'java-spring', 'php-symfony-neuron', 'python-django-crewai', 'ruby-rails', 'rust-actix', 'jupyter-python', 'r-studio', 'docker-compose', 'kubernetes-helm', 'terraform-ansible', 'angular', 'react-typescript', 'svelte-kit', 'vue-nuxt', 'flutter', 'ionic', 'react-native'
80+
# ]
6981

7082
jobs:
7183
deploy:

docs/USAGE.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,45 @@ Deploy your first development environment:
6868
# 🎉 Environment ready at: https://coder-dev.your-domain.com
6969
```
7070

71+
### Understanding the Deployment Process
72+
73+
The deployment system automatically handles both infrastructure and application deployment:
74+
75+
#### **What Gets Deployed Automatically**
76+
-**Kubernetes Cluster** - Fully configured with auto-scaling
77+
-**PostgreSQL Database** - Managed database with backups
78+
-**Coder Application** - Ready-to-use development platform
79+
-**Networking & Security** - Load balancer, ingress, SSL certificates
80+
-**Admin User** - Automatically created with secure credentials
81+
82+
#### **Template Deployment Behavior**
83+
84+
**With Template Specified** (`--template=template-name`):
85+
```bash
86+
./scripts/lifecycle/setup.sh --env=dev --template=python-django-crewai
87+
# Result: Coder + Python Django CrewAI template ready for workspace creation
88+
```
89+
90+
**Without Template** (template left blank or omitted):
91+
```bash
92+
./scripts/lifecycle/setup.sh --env=dev
93+
# Result: Coder deployed and ready, templates can be added later
94+
```
95+
96+
#### **Adding Templates Later**
97+
If you deployed without a template, you can add them anytime:
98+
99+
```bash
100+
# Add a specific template after deployment
101+
./scripts/lifecycle/setup.sh --env=dev --template=react-typescript --auto-approve
102+
103+
# Or manually via Coder CLI
104+
export KUBECONFIG=<(terraform output -raw kubeconfig)
105+
coder templates create my-template --directory=./templates/frontend/react-typescript
106+
```
107+
108+
> **Key Point**: Your Coder environment is fully functional immediately after deployment, regardless of whether you specify a template. Templates are workspace blueprints that can be managed independently.
109+
71110
## Environment Management
72111

73112
### Development Environment

environments/dev/main.tf

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,58 @@ module "security" {
143143
depends_on = [module.scaleway_cluster]
144144
}
145145

146+
# Coder Deployment Module
147+
module "coder_deployment" {
148+
source = "../../modules/coder-deployment"
149+
150+
namespace = "coder"
151+
environment = local.environment
152+
coder_version = "2.6.0"
153+
database_url = module.postgresql.connection_string
154+
access_url = module.networking.access_url
155+
wildcard_access_url = module.networking.wildcard_access_url
156+
service_account_name = "coder"
157+
158+
# Development-specific resource limits
159+
resources = {
160+
limits = {
161+
cpu = "1000m"
162+
memory = "2Gi"
163+
}
164+
requests = {
165+
cpu = "250m"
166+
memory = "512Mi"
167+
}
168+
}
169+
170+
# Storage configuration
171+
storage_class = "scw-bssd"
172+
storage_size = "5Gi"
173+
174+
# Enable monitoring for development
175+
monitoring_enabled = local.monitoring_config.enable_monitoring
176+
177+
# Workspace configuration
178+
workspace_traffic_policy = "subdomain"
179+
enable_terraform = true
180+
181+
# Ingress configuration based on domain setup
182+
ingress_enabled = local.domain_name != ""
183+
ingress_class = "nginx"
184+
tls_enabled = local.domain_name != ""
185+
186+
tags = merge(var.tags, {
187+
Environment = local.environment
188+
})
189+
190+
depends_on = [
191+
module.scaleway_cluster,
192+
module.postgresql,
193+
module.networking,
194+
module.security
195+
]
196+
}
197+
146198
# Import variables from shared configuration
147199
variable "scaleway_zone" {
148200
description = "Scaleway zone"

environments/dev/outputs.tf

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,10 @@ output "cost_estimation" {
6666
output "quick_setup_commands" {
6767
description = "Commands to complete the setup"
6868
value = {
69-
get_kubeconfig = "export KUBECONFIG=<(terraform output -raw kubeconfig)"
70-
install_coder = "./scripts/install-coder.sh --env=dev"
71-
access_url = module.networking.access_url != null ? module.networking.access_url : "https://${module.networking.load_balancer_ip}"
69+
get_kubeconfig = "export KUBECONFIG=<(terraform output -raw kubeconfig)"
70+
deploy_templates = "./scripts/lifecycle/setup.sh --env=dev --template=<template-name> --auto-approve"
71+
access_url = module.networking.access_url != null ? module.networking.access_url : "https://${module.networking.load_balancer_ip}"
72+
coder_admin_info = "Coder is deployed and running. Access admin credentials from Kubernetes secrets."
7273
}
7374
}
7475

@@ -77,4 +78,20 @@ output "kubeconfig" {
7778
description = "Kubeconfig for accessing the cluster"
7879
value = module.scaleway_cluster.kubeconfig
7980
sensitive = true
81+
}
82+
83+
# Direct outputs for GitHub Actions workflow
84+
output "load_balancer_ip" {
85+
description = "Load balancer IP address"
86+
value = module.networking.load_balancer_ip
87+
}
88+
89+
output "access_url" {
90+
description = "Main access URL for Coder"
91+
value = module.networking.access_url
92+
}
93+
94+
output "admin_username" {
95+
description = "Coder admin username"
96+
value = "admin" # Default admin username
8097
}

environments/prod/main.tf

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,124 @@ module "security" {
229229
depends_on = [module.scaleway_cluster]
230230
}
231231

232+
# Coder Deployment Module - Production Configuration
233+
module "coder_deployment" {
234+
source = "../../modules/coder-deployment"
235+
236+
namespace = "coder"
237+
environment = local.environment
238+
coder_version = "2.6.0"
239+
database_url = module.postgresql.connection_string
240+
access_url = module.networking.access_url
241+
wildcard_access_url = module.networking.wildcard_access_url
242+
service_account_name = "coder"
243+
244+
# Production-grade resource limits
245+
resources = {
246+
limits = {
247+
cpu = "4000m"
248+
memory = "8Gi"
249+
}
250+
requests = {
251+
cpu = "1000m"
252+
memory = "2Gi"
253+
}
254+
}
255+
256+
# High availability configuration
257+
replica_count = 2
258+
259+
# Storage configuration
260+
storage_class = "scw-bssd"
261+
storage_size = "50Gi"
262+
263+
# Enable monitoring for production
264+
monitoring_enabled = local.monitoring_config.enable_monitoring
265+
266+
# Workspace configuration
267+
workspace_traffic_policy = "subdomain"
268+
enable_terraform = true
269+
270+
# Production security settings (restricted)
271+
pod_security_context = {
272+
run_as_non_root = true
273+
run_as_user = 1000
274+
run_as_group = 1000
275+
fs_group = 1000
276+
}
277+
278+
security_context = {
279+
allow_privilege_escalation = false
280+
run_as_non_root = true
281+
run_as_user = 1000
282+
capabilities = {
283+
drop = ["ALL"]
284+
}
285+
read_only_root_filesystem = true
286+
}
287+
288+
# Enhanced health checks for production
289+
health_check_config = {
290+
liveness_probe = {
291+
initial_delay_seconds = 120
292+
period_seconds = 30
293+
timeout_seconds = 10
294+
failure_threshold = 3
295+
}
296+
readiness_probe = {
297+
initial_delay_seconds = 30
298+
period_seconds = 10
299+
timeout_seconds = 5
300+
failure_threshold = 5
301+
}
302+
}
303+
304+
# Ingress configuration based on domain setup
305+
ingress_enabled = local.domain_name != ""
306+
ingress_class = "nginx"
307+
tls_enabled = local.domain_name != ""
308+
309+
# Production ingress annotations with security and performance optimizations
310+
ingress_annotations = {
311+
"nginx.ingress.kubernetes.io/proxy-body-size" = "0"
312+
"nginx.ingress.kubernetes.io/proxy-read-timeout" = "86400"
313+
"nginx.ingress.kubernetes.io/proxy-send-timeout" = "86400"
314+
"nginx.ingress.kubernetes.io/ssl-redirect" = "true"
315+
"nginx.ingress.kubernetes.io/force-ssl-redirect" = "true"
316+
"nginx.ingress.kubernetes.io/rate-limit" = "200"
317+
"nginx.ingress.kubernetes.io/rate-limit-window" = "1m"
318+
"nginx.ingress.kubernetes.io/rate-limit-rps" = "5"
319+
"cert-manager.io/cluster-issuer" = "letsencrypt-prod"
320+
"nginx.ingress.kubernetes.io/proxy-buffer-size" = "16k"
321+
"nginx.ingress.kubernetes.io/proxy-buffers" = "8 16k"
322+
"nginx.ingress.kubernetes.io/enable-modsecurity" = "true"
323+
"nginx.ingress.kubernetes.io/enable-owasp-core-rules" = "true"
324+
}
325+
326+
# Production environment variables
327+
environment_variables = {
328+
"CODER_PROMETHEUS_ENABLE" = "true"
329+
"CODER_PPROF_ENABLE" = "true"
330+
"CODER_VERBOSE" = "false"
331+
"CODER_SWAGGER_ENABLE" = "false"
332+
"CODER_RATE_LIMIT_API" = "512"
333+
"CODER_EXPERIMENTS" = "workspace_batch_actions,deployment_health_page"
334+
"CODER_MAX_SESSION_EXPIRY" = "168h" # 7 days
335+
"CODER_DISABLE_SESSION_EXPIRY_REFRESH" = "false"
336+
}
337+
338+
tags = merge(var.tags, {
339+
Environment = local.environment
340+
})
341+
342+
depends_on = [
343+
module.scaleway_cluster,
344+
module.postgresql,
345+
module.networking,
346+
module.security
347+
]
348+
}
349+
232350
# Import variables from shared configuration
233351
variable "scaleway_zone" {
234352
description = "Scaleway zone"

environments/prod/outputs.tf

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,10 @@ output "production_checklist" {
9595
output "quick_setup_commands" {
9696
description = "Commands to complete the setup"
9797
value = {
98-
get_kubeconfig = "export KUBECONFIG=<(terraform output -raw kubeconfig)"
99-
install_coder = "./scripts/install-coder.sh --env=prod"
100-
access_url = module.networking.access_url != null ? module.networking.access_url : "https://${module.networking.load_balancer_ip}"
98+
get_kubeconfig = "export KUBECONFIG=<(terraform output -raw kubeconfig)"
99+
deploy_templates = "./scripts/lifecycle/setup.sh --env=prod --template=<template-name> --auto-approve"
100+
access_url = module.networking.access_url != null ? module.networking.access_url : "https://${module.networking.load_balancer_ip}"
101+
coder_admin_info = "Coder is deployed and running. Access admin credentials from Kubernetes secrets."
101102
}
102103
}
103104

@@ -106,4 +107,20 @@ output "kubeconfig" {
106107
description = "Kubeconfig for accessing the cluster"
107108
value = module.scaleway_cluster.kubeconfig
108109
sensitive = true
110+
}
111+
112+
# Direct outputs for GitHub Actions workflow
113+
output "load_balancer_ip" {
114+
description = "Load balancer IP address"
115+
value = module.networking.load_balancer_ip
116+
}
117+
118+
output "access_url" {
119+
description = "Main access URL for Coder"
120+
value = module.networking.access_url
121+
}
122+
123+
output "admin_username" {
124+
description = "Coder admin username"
125+
value = "admin" # Default admin username
109126
}

0 commit comments

Comments
 (0)