claude-agent-framework 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +128 -0
  2. package/bin/claude-framework +3 -0
  3. package/framework/agents/design-lead.md +240 -0
  4. package/framework/agents/product-owner.md +179 -0
  5. package/framework/agents/tech-lead.md +226 -0
  6. package/framework/commands/ayuda.md +127 -0
  7. package/framework/commands/a/303/261adir.md +98 -0
  8. package/framework/commands/backup.md +397 -0
  9. package/framework/commands/cambiar.md +110 -0
  10. package/framework/commands/cloud.md +457 -0
  11. package/framework/commands/code.md +142 -0
  12. package/framework/commands/debug.md +334 -0
  13. package/framework/commands/deploy.md +383 -0
  14. package/framework/commands/deshacer.md +120 -0
  15. package/framework/commands/estado.md +218 -0
  16. package/framework/commands/explica.md +227 -0
  17. package/framework/commands/feature.md +120 -0
  18. package/framework/commands/git.md +427 -0
  19. package/framework/commands/historial.md +202 -0
  20. package/framework/commands/learn.md +408 -0
  21. package/framework/commands/movil.md +245 -0
  22. package/framework/commands/nuevo.md +118 -0
  23. package/framework/commands/plan.md +134 -0
  24. package/framework/commands/prd.md +113 -0
  25. package/framework/commands/probar.md +148 -0
  26. package/framework/commands/revisar.md +208 -0
  27. package/framework/commands/seeds.md +230 -0
  28. package/framework/commands/seguridad.md +226 -0
  29. package/framework/commands/tasks.md +157 -0
  30. package/framework/skills/architecture/algorithms.md +970 -0
  31. package/framework/skills/architecture/clean-code.md +1080 -0
  32. package/framework/skills/architecture/design-patterns.md +1984 -0
  33. package/framework/skills/architecture/functional-programming.md +972 -0
  34. package/framework/skills/architecture/solid.md +991 -0
  35. package/framework/skills/cloud/cloud-aws.md +848 -0
  36. package/framework/skills/cloud/cloud-azure.md +931 -0
  37. package/framework/skills/cloud/cloud-gcp.md +848 -0
  38. package/framework/skills/cloud/message-queues.md +1229 -0
  39. package/framework/skills/core/accessibility.md +401 -0
  40. package/framework/skills/core/api.md +474 -0
  41. package/framework/skills/core/authentication.md +306 -0
  42. package/framework/skills/core/authorization.md +388 -0
  43. package/framework/skills/core/background-jobs.md +341 -0
  44. package/framework/skills/core/caching.md +473 -0
  45. package/framework/skills/core/code-review.md +341 -0
  46. package/framework/skills/core/controllers.md +290 -0
  47. package/framework/skills/core/cua.md +285 -0
  48. package/framework/skills/core/documentation.md +472 -0
  49. package/framework/skills/core/file-uploads.md +351 -0
  50. package/framework/skills/core/hotwire-native.md +296 -0
  51. package/framework/skills/core/hotwire.md +278 -0
  52. package/framework/skills/core/i18n.md +334 -0
  53. package/framework/skills/core/imports-exports.md +750 -0
  54. package/framework/skills/core/infrastructure.md +337 -0
  55. package/framework/skills/core/models.md +228 -0
  56. package/framework/skills/core/notifications.md +672 -0
  57. package/framework/skills/core/payments.md +581 -0
  58. package/framework/skills/core/performance.md +361 -0
  59. package/framework/skills/core/rails-scaffold.md +131 -0
  60. package/framework/skills/core/search.md +518 -0
  61. package/framework/skills/core/security.md +565 -0
  62. package/framework/skills/core/seeds.md +307 -0
  63. package/framework/skills/core/seo.md +542 -0
  64. package/framework/skills/core/testing.md +393 -0
  65. package/framework/skills/core/views.md +260 -0
  66. package/framework/skills/core/websockets.md +564 -0
  67. package/framework/skills/data/advanced-sql.md +1204 -0
  68. package/framework/skills/data/nosql.md +1141 -0
  69. package/framework/skills/devops/containers-advanced.md +1237 -0
  70. package/framework/skills/devops/debugging.md +834 -0
  71. package/framework/skills/devops/git-workflow.md +752 -0
  72. package/framework/skills/devops/networking.md +932 -0
  73. package/framework/skills/devops/shell-scripting.md +1132 -0
  74. package/framework/sub-agents/architecture-patterns-agent.md +1450 -0
  75. package/framework/sub-agents/cloud-agent.md +677 -0
  76. package/framework/sub-agents/data.md +504 -0
  77. package/framework/sub-agents/debugging-agent.md +554 -0
  78. package/framework/sub-agents/devops.md +483 -0
  79. package/framework/sub-agents/docs.md +176 -0
  80. package/framework/sub-agents/frontend-dev.md +349 -0
  81. package/framework/sub-agents/git-workflow-agent.md +697 -0
  82. package/framework/sub-agents/integrations.md +630 -0
  83. package/framework/sub-agents/native-dev.md +434 -0
  84. package/framework/sub-agents/qa.md +138 -0
  85. package/framework/sub-agents/rails-dev.md +375 -0
  86. package/framework/sub-agents/security.md +526 -0
  87. package/framework/sub-agents/ui.md +437 -0
  88. package/framework/sub-agents/ux.md +284 -0
  89. package/framework/templates/api-spec.md +500 -0
  90. package/framework/templates/component-spec.md +248 -0
  91. package/framework/templates/feature.json +13 -0
  92. package/framework/templates/model-spec.md +318 -0
  93. package/framework/templates/prd-template.md +80 -0
  94. package/framework/templates/task-plan.md +122 -0
  95. package/framework/templates/task-user-story.md +52 -0
  96. package/framework/templates/technical-spec.md +260 -0
  97. package/framework/templates/user-story.md +95 -0
  98. package/package.json +42 -0
  99. package/project-templates/CLAUDE.md +42 -0
  100. package/project-templates/contexts/architecture.md +25 -0
  101. package/project-templates/contexts/conventions.md +46 -0
  102. package/project-templates/contexts/design-system.md +47 -0
  103. package/project-templates/contexts/requirements.md +38 -0
  104. package/project-templates/contexts/stack.md +30 -0
  105. package/project-templates/history/active/models.md +11 -0
  106. package/project-templates/history/changelog.md +15 -0
  107. package/project-templates/workspace/.gitkeep +0 -0
  108. package/src/cli.js +52 -0
  109. package/src/init.js +104 -0
  110. package/src/status.js +75 -0
  111. package/src/update.js +88 -0
@@ -0,0 +1,848 @@
1
+ # Skill: Google Cloud Platform (GCP) para Rails
2
+
3
+ ## Purpose
4
+
5
+ Configurar, desplegar y gestionar aplicaciones Rails en Google Cloud Platform, aprovechando los servicios cloud para escalabilidad, rendimiento y seguridad.
6
+
7
+ ## Cloud Run
8
+
9
+ ### Desplegar Rails en Cloud Run
10
+
11
+ ```dockerfile
12
+ # Dockerfile
13
+ FROM ruby:3.3.0-slim
14
+
15
+ # Instalar dependencias
16
+ RUN apt-get update -qq && \
17
+ apt-get install -y build-essential libpq-dev nodejs npm && \
18
+ npm install -g yarn && \
19
+ rm -rf /var/lib/apt/lists/*
20
+
21
+ WORKDIR /app
22
+
23
+ # Copiar Gemfile primero para cache de layers
24
+ COPY Gemfile Gemfile.lock ./
25
+ RUN bundle config set --local deployment 'true' && \
26
+ bundle config set --local without 'development test' && \
27
+ bundle install --jobs 4
28
+
29
+ # Copiar aplicación
30
+ COPY . .
31
+
32
+ # Precompilar assets
33
+ ARG RAILS_MASTER_KEY
34
+ ENV RAILS_ENV=production
35
+ ENV SECRET_KEY_BASE=dummy
36
+ RUN bundle exec rails assets:precompile
37
+
38
+ # Puerto (Cloud Run usa $PORT)
39
+ EXPOSE 8080
40
+
41
+ # Comando
42
+ CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
43
+ ```
44
+
45
+ ```ruby
46
+ # config/puma.rb
47
+ port ENV.fetch("PORT") { 8080 }
48
+ environment ENV.fetch("RAILS_ENV") { "production" }
49
+
50
+ # Cloud Run: single process, multiple threads
51
+ threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
52
+ threads threads_count, threads_count
53
+
54
+ preload_app!
55
+ ```
56
+
57
+ ```bash
58
+ # Build y push a Container Registry
59
+ gcloud builds submit --tag gcr.io/mi-proyecto/rails-app
60
+
61
+ # Desplegar en Cloud Run
62
+ gcloud run deploy rails-app \
63
+ --image gcr.io/mi-proyecto/rails-app \
64
+ --platform managed \
65
+ --region us-central1 \
66
+ --allow-unauthenticated \
67
+ --set-env-vars "RAILS_ENV=production" \
68
+ --set-secrets "DATABASE_URL=database-url:latest,SECRET_KEY_BASE=secret-key-base:latest" \
69
+ --memory 512Mi \
70
+ --cpu 1 \
71
+ --min-instances 0 \
72
+ --max-instances 10 \
73
+ --concurrency 80
74
+ ```
75
+
76
+ ### Cloud Run con Cloud SQL
77
+
78
+ ```bash
79
+ # Desplegar con conexión a Cloud SQL
80
+ gcloud run deploy rails-app \
81
+ --image gcr.io/mi-proyecto/rails-app \
82
+ --add-cloudsql-instances mi-proyecto:us-central1:rails-db \
83
+ --set-env-vars "RAILS_ENV=production" \
84
+ --set-secrets "DATABASE_URL=database-url:latest"
85
+ ```
86
+
87
+ ```yaml
88
+ # config/database.yml para Cloud Run + Cloud SQL
89
+ production:
90
+ adapter: postgresql
91
+ encoding: unicode
92
+ pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
93
+ # Cloud Run usa socket Unix para Cloud SQL
94
+ host: /cloudsql/<%= ENV["CLOUD_SQL_CONNECTION_NAME"] %>
95
+ database: <%= ENV["DB_NAME"] %>
96
+ username: <%= ENV["DB_USER"] %>
97
+ password: <%= ENV["DB_PASSWORD"] %>
98
+ ```
99
+
100
+ ### Autoscaling Configuration
101
+
102
+ ```yaml
103
+ # service.yaml para Cloud Run
104
+ apiVersion: serving.knative.dev/v1
105
+ kind: Service
106
+ metadata:
107
+ name: rails-app
108
+ spec:
109
+ template:
110
+ metadata:
111
+ annotations:
112
+ autoscaling.knative.dev/minScale: "1"
113
+ autoscaling.knative.dev/maxScale: "100"
114
+ autoscaling.knative.dev/target: "80"
115
+ run.googleapis.com/cpu-throttling: "false"
116
+ spec:
117
+ containerConcurrency: 80
118
+ timeoutSeconds: 300
119
+ containers:
120
+ - image: gcr.io/mi-proyecto/rails-app
121
+ ports:
122
+ - containerPort: 8080
123
+ resources:
124
+ limits:
125
+ cpu: "2"
126
+ memory: 1Gi
127
+ ```
128
+
129
+ ## Compute Engine
130
+
131
+ ### Crear VM para Rails
132
+
133
+ ```bash
134
+ # Crear instancia
135
+ gcloud compute instances create rails-server \
136
+ --zone=us-central1-a \
137
+ --machine-type=e2-medium \
138
+ --image-family=ubuntu-2204-lts \
139
+ --image-project=ubuntu-os-cloud \
140
+ --boot-disk-size=20GB \
141
+ --tags=http-server,https-server
142
+
143
+ # Crear regla de firewall
144
+ gcloud compute firewall-rules create allow-rails \
145
+ --allow tcp:3000 \
146
+ --target-tags=http-server
147
+
148
+ # Conectar por SSH
149
+ gcloud compute ssh rails-server --zone=us-central1-a
150
+ ```
151
+
152
+ ### Startup Script para Rails
153
+
154
+ ```bash
155
+ #!/bin/bash
156
+ # startup-script.sh
157
+
158
+ # Instalar dependencias
159
+ apt-get update
160
+ apt-get install -y git curl build-essential libssl-dev zlib1g-dev \
161
+ libpq-dev nodejs npm
162
+
163
+ # Instalar rbenv
164
+ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
165
+ export PATH="$HOME/.rbenv/bin:$PATH"
166
+ eval "$(rbenv init -)"
167
+ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
168
+
169
+ # Instalar Ruby
170
+ rbenv install 3.3.0
171
+ rbenv global 3.3.0
172
+
173
+ # Instalar bundler
174
+ gem install bundler
175
+
176
+ # Clonar y configurar app
177
+ git clone https://github.com/tu-usuario/rails-app.git /opt/rails-app
178
+ cd /opt/rails-app
179
+ bundle install --deployment --without development test
180
+ RAILS_ENV=production rails db:migrate
181
+ RAILS_ENV=production rails assets:precompile
182
+ ```
183
+
184
+ ### Managed Instance Groups
185
+
186
+ ```bash
187
+ # Crear template de instancia
188
+ gcloud compute instance-templates create rails-template \
189
+ --machine-type=e2-medium \
190
+ --image-family=ubuntu-2204-lts \
191
+ --image-project=ubuntu-os-cloud \
192
+ --metadata-from-file startup-script=startup-script.sh \
193
+ --tags=http-server,https-server
194
+
195
+ # Crear managed instance group
196
+ gcloud compute instance-groups managed create rails-mig \
197
+ --base-instance-name=rails \
198
+ --template=rails-template \
199
+ --size=2 \
200
+ --zone=us-central1-a
201
+
202
+ # Configurar autoscaling
203
+ gcloud compute instance-groups managed set-autoscaling rails-mig \
204
+ --zone=us-central1-a \
205
+ --max-num-replicas=10 \
206
+ --min-num-replicas=2 \
207
+ --target-cpu-utilization=0.7
208
+ ```
209
+
210
+ ## Cloud Storage
211
+
212
+ ### Configurar Active Storage
213
+
214
+ ```ruby
215
+ # Gemfile
216
+ gem "google-cloud-storage", require: false
217
+
218
+ # config/storage.yml
219
+ google:
220
+ service: GCS
221
+ project: <%= ENV["GCP_PROJECT_ID"] %>
222
+ credentials: <%= Rails.root.join("config/gcs-credentials.json") %>
223
+ bucket: <%= ENV.fetch("GCS_BUCKET") { "mi-app-#{Rails.env}" } %>
224
+
225
+ # Para producción con ADC (Application Default Credentials)
226
+ google_production:
227
+ service: GCS
228
+ project: <%= ENV["GCP_PROJECT_ID"] %>
229
+ bucket: <%= ENV["GCS_BUCKET"] %>
230
+ # Sin credentials - usa ADC
231
+
232
+ # config/environments/production.rb
233
+ config.active_storage.service = :google_production
234
+ ```
235
+
236
+ ### Signed URLs
237
+
238
+ ```ruby
239
+ # app/services/gcs_signer.rb
240
+ class GcsSigner
241
+ def initialize
242
+ @storage = Google::Cloud::Storage.new(
243
+ project_id: ENV["GCP_PROJECT_ID"]
244
+ )
245
+ @bucket = @storage.bucket(ENV["GCS_BUCKET"])
246
+ end
247
+
248
+ # URL para subir
249
+ def signed_upload_url(filename, content_type:, expires_in: 15.minutes)
250
+ @bucket.signed_url(
251
+ filename,
252
+ method: "PUT",
253
+ content_type: content_type,
254
+ expires: expires_in.to_i,
255
+ version: :v4
256
+ )
257
+ end
258
+
259
+ # URL para descargar
260
+ def signed_download_url(filename, expires_in: 1.hour, disposition: nil)
261
+ options = {
262
+ method: "GET",
263
+ expires: expires_in.to_i,
264
+ version: :v4
265
+ }
266
+
267
+ if disposition
268
+ options[:query] = {
269
+ "response-content-disposition" => disposition
270
+ }
271
+ end
272
+
273
+ @bucket.signed_url(filename, **options)
274
+ end
275
+
276
+ # URL para streaming de video
277
+ def signed_streaming_url(filename, expires_in: 4.hours)
278
+ @bucket.signed_url(
279
+ filename,
280
+ method: "GET",
281
+ expires: expires_in.to_i,
282
+ version: :v4,
283
+ headers: { "Range" => "bytes=0-" }
284
+ )
285
+ end
286
+ end
287
+ ```
288
+
289
+ ### CORS Configuration
290
+
291
+ ```json
292
+ [
293
+ {
294
+ "origin": ["https://miapp.com", "http://localhost:3000"],
295
+ "method": ["GET", "PUT", "POST", "DELETE"],
296
+ "responseHeader": ["Content-Type", "Content-Range"],
297
+ "maxAgeSeconds": 3600
298
+ }
299
+ ]
300
+ ```
301
+
302
+ ```bash
303
+ # Aplicar configuración CORS
304
+ gsutil cors set cors.json gs://mi-bucket
305
+ ```
306
+
307
+ ## Cloud SQL
308
+
309
+ ### Crear instancia PostgreSQL
310
+
311
+ ```bash
312
+ # Crear instancia
313
+ gcloud sql instances create rails-db \
314
+ --database-version=POSTGRES_15 \
315
+ --tier=db-f1-micro \
316
+ --region=us-central1 \
317
+ --storage-type=SSD \
318
+ --storage-size=10GB \
319
+ --backup-start-time=03:00
320
+
321
+ # Crear base de datos
322
+ gcloud sql databases create rails_production \
323
+ --instance=rails-db
324
+
325
+ # Crear usuario
326
+ gcloud sql users create railsuser \
327
+ --instance=rails-db \
328
+ --password=SecurePassword123
329
+ ```
330
+
331
+ ### Configurar Rails
332
+
333
+ ```yaml
334
+ # config/database.yml
335
+ production:
336
+ adapter: postgresql
337
+ encoding: unicode
338
+ pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
339
+ database: <%= ENV["DB_NAME"] %>
340
+ username: <%= ENV["DB_USER"] %>
341
+ password: <%= ENV["DB_PASSWORD"] %>
342
+
343
+ # Conexión directa (con Cloud SQL Proxy)
344
+ host: 127.0.0.1
345
+ port: 5432
346
+
347
+ # O con socket (Cloud Run)
348
+ # host: /cloudsql/proyecto:region:instancia
349
+ ```
350
+
351
+ ### Cloud SQL Proxy
352
+
353
+ ```bash
354
+ # Descargar proxy
355
+ curl -o cloud-sql-proxy https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy/v2.8.0/cloud-sql-proxy.linux.amd64
356
+ chmod +x cloud-sql-proxy
357
+
358
+ # Iniciar proxy
359
+ ./cloud-sql-proxy mi-proyecto:us-central1:rails-db &
360
+
361
+ # Para desarrollo local con credenciales
362
+ ./cloud-sql-proxy --credentials-file=service-account.json mi-proyecto:us-central1:rails-db
363
+ ```
364
+
365
+ ### Backups y Restauración
366
+
367
+ ```bash
368
+ # Crear backup on-demand
369
+ gcloud sql backups create \
370
+ --instance=rails-db \
371
+ --description="Pre-deploy backup"
372
+
373
+ # Listar backups
374
+ gcloud sql backups list --instance=rails-db
375
+
376
+ # Restaurar backup
377
+ gcloud sql backups restore BACKUP_ID \
378
+ --restore-instance=rails-db \
379
+ --backup-instance=rails-db
380
+
381
+ # Clonar instancia
382
+ gcloud sql instances clone rails-db rails-db-clone
383
+ ```
384
+
385
+ ### Read Replicas
386
+
387
+ ```bash
388
+ # Crear réplica
389
+ gcloud sql instances create rails-db-replica \
390
+ --master-instance-name=rails-db \
391
+ --region=us-central1
392
+ ```
393
+
394
+ ```ruby
395
+ # config/database.yml con réplica
396
+ production:
397
+ primary:
398
+ adapter: postgresql
399
+ database: rails_production
400
+ host: /cloudsql/mi-proyecto:us-central1:rails-db
401
+
402
+ primary_replica:
403
+ adapter: postgresql
404
+ database: rails_production
405
+ host: /cloudsql/mi-proyecto:us-central1:rails-db-replica
406
+ replica: true
407
+ ```
408
+
409
+ ## Cloud Functions
410
+
411
+ ### HTTP Function para Webhooks
412
+
413
+ ```ruby
414
+ # app.rb (para Cloud Functions con Ruby)
415
+ require "functions_framework"
416
+ require "json"
417
+
418
+ FunctionsFramework.http "webhook_handler" do |request|
419
+ payload = JSON.parse(request.body.read)
420
+
421
+ # Procesar webhook
422
+ case payload["event"]
423
+ when "payment.completed"
424
+ # Publicar a Pub/Sub para procesamiento async
425
+ pubsub = Google::Cloud::Pubsub.new
426
+ topic = pubsub.topic("payment-events")
427
+ topic.publish(payload.to_json)
428
+ end
429
+
430
+ { status: "received" }.to_json
431
+ rescue JSON::ParserError
432
+ [400, {}, ["Invalid JSON"]]
433
+ end
434
+ ```
435
+
436
+ ```bash
437
+ # Desplegar función
438
+ gcloud functions deploy webhook-handler \
439
+ --runtime ruby32 \
440
+ --trigger-http \
441
+ --allow-unauthenticated \
442
+ --entry-point webhook_handler
443
+ ```
444
+
445
+ ### Pub/Sub Trigger
446
+
447
+ ```ruby
448
+ # background_function.rb
449
+ require "functions_framework"
450
+ require "json"
451
+ require "base64"
452
+
453
+ FunctionsFramework.cloud_event "process_payment" do |event|
454
+ data = JSON.parse(Base64.decode64(event.data["message"]["data"]))
455
+
456
+ # Procesar el pago
457
+ PaymentProcessor.new(data).process
458
+
459
+ puts "Processed payment: #{data['id']}"
460
+ end
461
+ ```
462
+
463
+ ## GKE (Google Kubernetes Engine)
464
+
465
+ ### Crear Cluster
466
+
467
+ ```bash
468
+ # Crear cluster autopilot
469
+ gcloud container clusters create-auto rails-cluster \
470
+ --region=us-central1
471
+
472
+ # O cluster standard
473
+ gcloud container clusters create rails-cluster \
474
+ --zone=us-central1-a \
475
+ --num-nodes=3 \
476
+ --machine-type=e2-medium
477
+
478
+ # Obtener credenciales
479
+ gcloud container clusters get-credentials rails-cluster \
480
+ --zone=us-central1-a
481
+ ```
482
+
483
+ ### Deployment
484
+
485
+ ```yaml
486
+ # kubernetes/deployment.yaml
487
+ apiVersion: apps/v1
488
+ kind: Deployment
489
+ metadata:
490
+ name: rails-app
491
+ spec:
492
+ replicas: 3
493
+ selector:
494
+ matchLabels:
495
+ app: rails-app
496
+ template:
497
+ metadata:
498
+ labels:
499
+ app: rails-app
500
+ spec:
501
+ serviceAccountName: rails-app-sa
502
+ containers:
503
+ - name: rails-app
504
+ image: gcr.io/mi-proyecto/rails-app:latest
505
+ ports:
506
+ - containerPort: 8080
507
+ env:
508
+ - name: RAILS_ENV
509
+ value: production
510
+ - name: DATABASE_URL
511
+ valueFrom:
512
+ secretKeyRef:
513
+ name: rails-secrets
514
+ key: database-url
515
+ resources:
516
+ requests:
517
+ memory: "256Mi"
518
+ cpu: "100m"
519
+ limits:
520
+ memory: "512Mi"
521
+ cpu: "500m"
522
+ livenessProbe:
523
+ httpGet:
524
+ path: /up
525
+ port: 8080
526
+ initialDelaySeconds: 30
527
+ readinessProbe:
528
+ httpGet:
529
+ path: /up
530
+ port: 8080
531
+ initialDelaySeconds: 5
532
+ - name: cloud-sql-proxy
533
+ image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.8.0
534
+ args:
535
+ - "--structured-logs"
536
+ - "mi-proyecto:us-central1:rails-db"
537
+ securityContext:
538
+ runAsNonRoot: true
539
+ ---
540
+ apiVersion: v1
541
+ kind: Service
542
+ metadata:
543
+ name: rails-app-service
544
+ spec:
545
+ type: LoadBalancer
546
+ ports:
547
+ - port: 80
548
+ targetPort: 8080
549
+ selector:
550
+ app: rails-app
551
+ ```
552
+
553
+ ## Cloud CDN
554
+
555
+ ### Configurar con Load Balancer
556
+
557
+ ```bash
558
+ # Crear backend bucket para assets
559
+ gsutil mb gs://rails-assets-cdn
560
+
561
+ # Hacer público
562
+ gsutil iam ch allUsers:objectViewer gs://rails-assets-cdn
563
+
564
+ # Crear backend bucket
565
+ gcloud compute backend-buckets create rails-assets-backend \
566
+ --gcs-bucket-name=rails-assets-cdn \
567
+ --enable-cdn
568
+
569
+ # Crear URL map
570
+ gcloud compute url-maps create rails-lb \
571
+ --default-service=rails-backend-service
572
+
573
+ # Agregar path para assets
574
+ gcloud compute url-maps add-path-matcher rails-lb \
575
+ --path-matcher-name=assets \
576
+ --default-service=rails-backend-service \
577
+ --backend-bucket-path-rules="/assets/*=rails-assets-backend"
578
+ ```
579
+
580
+ ```ruby
581
+ # config/environments/production.rb
582
+ config.asset_host = ENV["CDN_HOST"]
583
+ # Ejemplo: "https://storage.googleapis.com/rails-assets-cdn"
584
+ ```
585
+
586
+ ### Cloud Armor (WAF)
587
+
588
+ ```bash
589
+ # Crear política de seguridad
590
+ gcloud compute security-policies create rails-security-policy
591
+
592
+ # Regla para bloquear países
593
+ gcloud compute security-policies rules create 1000 \
594
+ --security-policy=rails-security-policy \
595
+ --expression="origin.region_code == 'XX'" \
596
+ --action=deny-403
597
+
598
+ # Regla para rate limiting
599
+ gcloud compute security-policies rules create 2000 \
600
+ --security-policy=rails-security-policy \
601
+ --expression="true" \
602
+ --action=rate-based-ban \
603
+ --rate-limit-threshold-count=1000 \
604
+ --rate-limit-threshold-interval-sec=60 \
605
+ --ban-duration-sec=600
606
+ ```
607
+
608
+ ## Cloud DNS
609
+
610
+ ### Configurar Zona
611
+
612
+ ```bash
613
+ # Crear zona
614
+ gcloud dns managed-zones create mi-zona \
615
+ --dns-name=midominio.com. \
616
+ --description="Zona DNS para mi app"
617
+
618
+ # Agregar registro A
619
+ gcloud dns record-sets create app.midominio.com. \
620
+ --zone=mi-zona \
621
+ --type=A \
622
+ --ttl=300 \
623
+ --rrdatas=34.xx.xx.xx
624
+
625
+ # Agregar CNAME
626
+ gcloud dns record-sets create www.midominio.com. \
627
+ --zone=mi-zona \
628
+ --type=CNAME \
629
+ --ttl=300 \
630
+ --rrdatas=app.midominio.com.
631
+ ```
632
+
633
+ ## IAM
634
+
635
+ ### Service Account para Rails
636
+
637
+ ```bash
638
+ # Crear service account
639
+ gcloud iam service-accounts create rails-app-sa \
640
+ --display-name="Rails Application"
641
+
642
+ # Asignar roles mínimos
643
+ gcloud projects add-iam-policy-binding mi-proyecto \
644
+ --member="serviceAccount:rails-app-sa@mi-proyecto.iam.gserviceaccount.com" \
645
+ --role="roles/cloudsql.client"
646
+
647
+ gcloud projects add-iam-policy-binding mi-proyecto \
648
+ --member="serviceAccount:rails-app-sa@mi-proyecto.iam.gserviceaccount.com" \
649
+ --role="roles/storage.objectAdmin"
650
+
651
+ gcloud projects add-iam-policy-binding mi-proyecto \
652
+ --member="serviceAccount:rails-app-sa@mi-proyecto.iam.gserviceaccount.com" \
653
+ --role="roles/secretmanager.secretAccessor"
654
+
655
+ # Generar key (para desarrollo local)
656
+ gcloud iam service-accounts keys create key.json \
657
+ --iam-account=rails-app-sa@mi-proyecto.iam.gserviceaccount.com
658
+ ```
659
+
660
+ ## Memorystore (Redis)
661
+
662
+ ### Configurar
663
+
664
+ ```bash
665
+ # Crear instancia Redis
666
+ gcloud redis instances create rails-redis \
667
+ --size=1 \
668
+ --region=us-central1 \
669
+ --redis-version=redis_7_0
670
+
671
+ # Obtener host
672
+ gcloud redis instances describe rails-redis \
673
+ --region=us-central1 \
674
+ --format="value(host)"
675
+ ```
676
+
677
+ ```ruby
678
+ # config/environments/production.rb
679
+ config.cache_store = :redis_cache_store, {
680
+ url: "redis://#{ENV['REDIS_HOST']}:6379/0"
681
+ }
682
+
683
+ config.session_store :redis_store,
684
+ servers: ["redis://#{ENV['REDIS_HOST']}:6379/1"],
685
+ expire_after: 1.day
686
+ ```
687
+
688
+ ## Secret Manager
689
+
690
+ ### Usar Secrets
691
+
692
+ ```bash
693
+ # Crear secret
694
+ echo -n "mi-valor-secreto" | gcloud secrets create my-secret \
695
+ --data-file=-
696
+
697
+ # Agregar versión
698
+ echo -n "nuevo-valor" | gcloud secrets versions add my-secret \
699
+ --data-file=-
700
+
701
+ # Acceder a secret
702
+ gcloud secrets versions access latest --secret=my-secret
703
+ ```
704
+
705
+ ```ruby
706
+ # config/initializers/gcp_secrets.rb
707
+ if Rails.env.production?
708
+ require "google/cloud/secret_manager"
709
+
710
+ client = Google::Cloud::SecretManager.secret_manager_service
711
+
712
+ secrets = %w[DATABASE_URL SECRET_KEY_BASE REDIS_HOST]
713
+
714
+ secrets.each do |secret_name|
715
+ begin
716
+ name = "projects/#{ENV['GCP_PROJECT_ID']}/secrets/#{secret_name.downcase.tr('_', '-')}/versions/latest"
717
+ version = client.access_secret_version(name: name)
718
+ ENV[secret_name] = version.payload.data unless ENV[secret_name].present?
719
+ rescue Google::Cloud::NotFoundError
720
+ Rails.logger.warn "Secret #{secret_name} not found"
721
+ end
722
+ end
723
+ end
724
+ ```
725
+
726
+ ## Cloud Logging / Monitoring
727
+
728
+ ### Configurar Logging
729
+
730
+ ```ruby
731
+ # config/environments/production.rb
732
+ if ENV["K_SERVICE"].present? # Cloud Run
733
+ require "google/cloud/logging"
734
+
735
+ logging = Google::Cloud::Logging.new
736
+ resource = Google::Cloud::Logging::Middleware.build_monitored_resource
737
+
738
+ config.logger = ActiveSupport::Logger.new(
739
+ Google::Cloud::Logging::Logger.new(
740
+ logging,
741
+ "rails-app",
742
+ resource
743
+ )
744
+ )
745
+ end
746
+ ```
747
+
748
+ ### Structured Logging
749
+
750
+ ```ruby
751
+ # app/lib/json_logger.rb
752
+ class JsonLogger < ActiveSupport::Logger
753
+ def format_message(severity, timestamp, progname, msg)
754
+ {
755
+ severity: severity,
756
+ timestamp: timestamp.iso8601,
757
+ message: msg,
758
+ progname: progname
759
+ }.to_json + "\n"
760
+ end
761
+ end
762
+
763
+ # config/environments/production.rb
764
+ config.logger = JsonLogger.new(STDOUT)
765
+ ```
766
+
767
+ ### Custom Metrics
768
+
769
+ ```ruby
770
+ # app/services/cloud_monitoring.rb
771
+ class CloudMonitoring
772
+ def initialize
773
+ @client = Google::Cloud::Monitoring.metric_service
774
+ @project_name = "projects/#{ENV['GCP_PROJECT_ID']}"
775
+ end
776
+
777
+ def record_metric(metric_type, value, labels = {})
778
+ series = Google::Cloud::Monitoring::V3::TimeSeries.new(
779
+ metric: {
780
+ type: "custom.googleapis.com/rails/#{metric_type}",
781
+ labels: labels
782
+ },
783
+ resource: {
784
+ type: "global",
785
+ labels: { project_id: ENV["GCP_PROJECT_ID"] }
786
+ },
787
+ points: [{
788
+ interval: { end_time: Google::Protobuf::Timestamp.new(seconds: Time.current.to_i) },
789
+ value: { double_value: value }
790
+ }]
791
+ )
792
+
793
+ @client.create_time_series(name: @project_name, time_series: [series])
794
+ end
795
+ end
796
+ ```
797
+
798
+ ## Costos y Optimización
799
+
800
+ ### Calculadora
801
+
802
+ ```markdown
803
+ ## Estimación mensual para app Rails pequeña-mediana
804
+
805
+ | Servicio | Configuración | Costo/mes |
806
+ |----------|--------------|-----------|
807
+ | Cloud Run | 1M requests, 512Mi | ~$20 |
808
+ | Cloud SQL | db-f1-micro | ~$10 |
809
+ | Memorystore | 1GB Redis | ~$35 |
810
+ | Cloud Storage | 50GB | ~$1 |
811
+ | Cloud CDN | 100GB | ~$8 |
812
+ | Secret Manager | 10 secrets | ~$0.06 |
813
+ | **Total** | | **~$75/mes** |
814
+
815
+ ## Optimizaciones:
816
+ - Cloud Run: min-instances=0 para desarrollo
817
+ - Committed Use Discounts (1-3 años)
818
+ - Preemptible VMs para workers
819
+ - Cloud Storage Nearline para backups
820
+ ```
821
+
822
+ ### Committed Use Discounts
823
+
824
+ ```bash
825
+ # Ver recomendaciones
826
+ gcloud recommender recommendations list \
827
+ --project=mi-proyecto \
828
+ --location=us-central1 \
829
+ --recommender=google.compute.commitment.UsageCommitmentRecommender
830
+ ```
831
+
832
+ ## Checklist de Deployment
833
+
834
+ - [ ] Proyecto GCP creado
835
+ - [ ] APIs habilitadas (Cloud Run, SQL, Storage, etc.)
836
+ - [ ] Service Account con roles mínimos
837
+ - [ ] Cloud SQL instancia creada
838
+ - [ ] Cloud Storage bucket configurado
839
+ - [ ] Secret Manager con secrets
840
+ - [ ] Container Registry con imagen
841
+ - [ ] Cloud Run service desplegado
842
+ - [ ] Cloud SQL Proxy o conexión configurada
843
+ - [ ] Load Balancer + CDN (opcional)
844
+ - [ ] Cloud DNS configurado
845
+ - [ ] SSL/TLS con certificado managed
846
+ - [ ] Cloud Logging habilitado
847
+ - [ ] Alertas en Cloud Monitoring
848
+ - [ ] Backups automáticos verificados