grada-run 0.0.2 → 0.32.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 (231) hide show
  1. package/.github/workflows/deploy-docs.yml +37 -0
  2. package/.github/workflows/iac-validation.yml +303 -0
  3. package/.github/workflows/publish.yml +68 -0
  4. package/.github/workflows/sync-bedrock-models.yml +57 -0
  5. package/.github/workflows/test.yml +43 -0
  6. package/.muserules +31 -0
  7. package/LICENSE +21 -0
  8. package/README.md +193 -3
  9. package/apps/docs/.astro/collections/docs.schema.json +644 -0
  10. package/apps/docs/.astro/content-assets.mjs +4 -0
  11. package/apps/docs/.astro/content-modules.mjs +4 -0
  12. package/apps/docs/.astro/content.d.ts +179 -0
  13. package/apps/docs/.astro/data-store.json +1 -0
  14. package/apps/docs/.astro/dev.json +14 -0
  15. package/apps/docs/.astro/settings.json +5 -0
  16. package/apps/docs/.astro/types.d.ts +2 -0
  17. package/apps/docs/astro.config.mjs +97 -0
  18. package/apps/docs/package.json +17 -0
  19. package/apps/docs/src/content/docs/adrs/0001-s3-native-state-locking.md +37 -0
  20. package/apps/docs/src/content/docs/adrs/0002-eject-mechanism-pure-iac.md +39 -0
  21. package/apps/docs/src/content/docs/adrs/0003-sync-ai-context-strategy.md +48 -0
  22. package/apps/docs/src/content/docs/adrs/0004-iac-driven-diagnostic-context.md +37 -0
  23. package/apps/docs/src/content/docs/adrs/0005-ecs-fargate-alb-runtime-target.md +38 -0
  24. package/apps/docs/src/content/docs/adrs/0006-github-oidc-no-stored-keys.md +37 -0
  25. package/apps/docs/src/content/docs/adrs/0007-framework-detection-with-fallback.md +37 -0
  26. package/apps/docs/src/content/docs/adrs/0008-secrets-names-in-git-values-in-aws.md +37 -0
  27. package/apps/docs/src/content/docs/adrs/0009-regenerate-with-backup-on-rerun.md +37 -0
  28. package/apps/docs/src/content/docs/adrs/0010-advisory-only-security-scans.md +37 -0
  29. package/apps/docs/src/content/docs/cli/add.md +84 -0
  30. package/apps/docs/src/content/docs/cli/apply.md +32 -0
  31. package/apps/docs/src/content/docs/cli/db.md +200 -0
  32. package/apps/docs/src/content/docs/cli/destroy.md +31 -0
  33. package/apps/docs/src/content/docs/cli/diagnose.md +37 -0
  34. package/apps/docs/src/content/docs/cli/doctor.md +28 -0
  35. package/apps/docs/src/content/docs/cli/domain.md +57 -0
  36. package/apps/docs/src/content/docs/cli/drift.md +40 -0
  37. package/apps/docs/src/content/docs/cli/eject.md +29 -0
  38. package/apps/docs/src/content/docs/cli/exec.md +49 -0
  39. package/apps/docs/src/content/docs/cli/gc.md +37 -0
  40. package/apps/docs/src/content/docs/cli/init.md +72 -0
  41. package/apps/docs/src/content/docs/cli/logs.md +39 -0
  42. package/apps/docs/src/content/docs/cli/rollback.md +51 -0
  43. package/apps/docs/src/content/docs/cli/secrets.md +73 -0
  44. package/apps/docs/src/content/docs/cli/sleep.md +53 -0
  45. package/apps/docs/src/content/docs/cli/status.md +34 -0
  46. package/apps/docs/src/content/docs/cli/sync-ai.md +27 -0
  47. package/apps/docs/src/content/docs/guides/architecture.md +87 -0
  48. package/apps/docs/src/content/docs/guides/aws-credentials.md +72 -0
  49. package/apps/docs/src/content/docs/guides/background-workers.md +45 -0
  50. package/apps/docs/src/content/docs/guides/cicd-pipeline.md +64 -0
  51. package/apps/docs/src/content/docs/guides/database-connections.md +64 -0
  52. package/apps/docs/src/content/docs/guides/docker-compose.md +37 -0
  53. package/apps/docs/src/content/docs/guides/dockerfiles.md +46 -0
  54. package/apps/docs/src/content/docs/guides/ephemeral-pr-previews.md +39 -0
  55. package/apps/docs/src/content/docs/guides/examples.md +50 -0
  56. package/apps/docs/src/content/docs/guides/frameworks.md +88 -0
  57. package/apps/docs/src/content/docs/guides/headless.md +75 -0
  58. package/apps/docs/src/content/docs/guides/quickstart.md +52 -0
  59. package/apps/docs/src/content/docs/guides/rerun-init.md +43 -0
  60. package/apps/docs/src/content/docs/guides/secrets-management.md +83 -0
  61. package/apps/docs/src/content/docs/guides/understanding-your-bill.md +63 -0
  62. package/apps/docs/src/content/docs/index.mdx +103 -0
  63. package/apps/docs/src/content/docs/migrations/astro-vercel-to-aws.md +55 -0
  64. package/apps/docs/src/content/docs/migrations/heroku-procfile-to-aws.md +41 -0
  65. package/apps/docs/src/content/docs/migrations/nextjs-vercel-to-aws.md +51 -0
  66. package/apps/docs/src/content/docs/migrations/sveltekit-vercel-to-aws.md +63 -0
  67. package/apps/docs/src/content/docs/roadmap.md +97 -0
  68. package/apps/docs/src/content/docs/testing-strategy.md +32 -0
  69. package/apps/docs/src/content.config.ts +7 -0
  70. package/apps/docs/src/custom.css +14 -0
  71. package/apps/docs/tsconfig.json +6 -0
  72. package/bin/cli.js +140 -0
  73. package/package.json +105 -7
  74. package/scripts/sync-bedrock-models.js +22 -0
  75. package/scripts/test-iac.js +261 -0
  76. package/specs/add-redis-sqs-bedrock.md +128 -0
  77. package/specs/add-storage-dynamodb.md +106 -0
  78. package/specs/bedrock-model-catalog.md +131 -0
  79. package/specs/ci-pipeline.md +17 -0
  80. package/specs/cost-transparency.md +115 -0
  81. package/specs/custom-domains-and-ses.md +153 -0
  82. package/specs/database-suite-expansion.md +151 -0
  83. package/specs/db-connect.md +69 -0
  84. package/specs/db-lifecycle-migrations.md +159 -0
  85. package/specs/dependency-aware-init.md +176 -0
  86. package/specs/deploy-stack-to-grada-run-rebrand.md +45 -0
  87. package/specs/deployment-safety.md +170 -0
  88. package/specs/diagnose.md +16 -0
  89. package/specs/docs-hub.md +16 -0
  90. package/specs/dx-polish.md +46 -0
  91. package/specs/exec.md +25 -0
  92. package/specs/finops-cron-drift.md +161 -0
  93. package/specs/gc.md +26 -0
  94. package/specs/integration-suite.md +16 -0
  95. package/specs/logs.md +32 -0
  96. package/specs/rollback-live-polling.md +40 -0
  97. package/specs/secrets-pull-audit.md +51 -0
  98. package/specs/serverless-lambda-target.md +133 -0
  99. package/specs/status.md +31 -0
  100. package/specs/telemetry-and-spawn-hardening.md +69 -0
  101. package/specs/telemetry-hardening.md +35 -0
  102. package/src/commands/add.js +1111 -0
  103. package/src/commands/apply.js +214 -0
  104. package/src/commands/db/backup.js +229 -0
  105. package/src/commands/db/connect.js +304 -0
  106. package/src/commands/db/enable-vector.js +344 -0
  107. package/src/commands/db/import.js +604 -0
  108. package/src/commands/db/migrate.js +477 -0
  109. package/src/commands/db/restore.js +361 -0
  110. package/src/commands/db.js +87 -0
  111. package/src/commands/destroy.js +217 -0
  112. package/src/commands/diagnose.js +460 -0
  113. package/src/commands/doctor.js +109 -0
  114. package/src/commands/domain.js +685 -0
  115. package/src/commands/drift.js +243 -0
  116. package/src/commands/eject.js +127 -0
  117. package/src/commands/exec.js +222 -0
  118. package/src/commands/gc.js +250 -0
  119. package/src/commands/init.js +649 -0
  120. package/src/commands/logs.js +256 -0
  121. package/src/commands/rollback.js +323 -0
  122. package/src/commands/secrets.js +485 -0
  123. package/src/commands/sleep.js +347 -0
  124. package/src/commands/status.js +309 -0
  125. package/src/commands/sync-ai.js +115 -0
  126. package/src/commands/wake.js +337 -0
  127. package/src/core/parser.js +126 -0
  128. package/src/core/telemetry.js +244 -0
  129. package/src/data/bedrock-models.json +896 -0
  130. package/src/utils/addons.js +126 -0
  131. package/src/utils/ai-rules.js +59 -0
  132. package/src/utils/args.js +91 -0
  133. package/src/utils/aws.js +178 -0
  134. package/src/utils/backup.js +69 -0
  135. package/src/utils/bedrock-catalog.js +511 -0
  136. package/src/utils/capabilities.js +500 -0
  137. package/src/utils/command.js +65 -0
  138. package/src/utils/db-tunnel.js +164 -0
  139. package/src/utils/detector.js +298 -0
  140. package/src/utils/dockerCompose.js +65 -0
  141. package/src/utils/domains.js +73 -0
  142. package/src/utils/ecs-runner.js +289 -0
  143. package/src/utils/ecs.js +92 -0
  144. package/src/utils/frameworks.js +55 -0
  145. package/src/utils/generator.js +527 -0
  146. package/src/utils/hcl.js +426 -0
  147. package/src/utils/lambda-ecr.js +185 -0
  148. package/src/utils/prompts.js +278 -0
  149. package/src/utils/rds.js +131 -0
  150. package/src/utils/resolvers.js +174 -0
  151. package/src/utils/sleep-state.js +140 -0
  152. package/src/utils/sleep-targets.js +139 -0
  153. package/src/utils/system.js +42 -0
  154. package/src/utils/terraform.js +70 -0
  155. package/src/utils/visualizer.js +381 -0
  156. package/src/utils/warnings.js +49 -0
  157. package/templates/README.md +150 -0
  158. package/templates/docker/django.Dockerfile +40 -0
  159. package/templates/docker/go.Dockerfile +23 -0
  160. package/templates/docker/nestjs.Dockerfile +33 -0
  161. package/templates/docker/nextjs.Dockerfile +55 -0
  162. package/templates/docker/node.Dockerfile +24 -0
  163. package/templates/docker/nuxt.Dockerfile +47 -0
  164. package/templates/docker/python.Dockerfile +38 -0
  165. package/templates/docker/rails.Dockerfile +59 -0
  166. package/templates/docker/static.Dockerfile +32 -0
  167. package/templates/docker/svelte.Dockerfile +52 -0
  168. package/templates/github/deploy-lambda.yml +120 -0
  169. package/templates/github/deploy.yml +138 -0
  170. package/templates/github/drift.yml +112 -0
  171. package/templates/github/preview-lambda.yml +86 -0
  172. package/templates/github/preview.yml +69 -0
  173. package/templates/github/teardown.yml +43 -0
  174. package/templates/terraform/addons/bedrock.tf +34 -0
  175. package/templates/terraform/addons/cron-lambda.tf +78 -0
  176. package/templates/terraform/addons/cron.tf +101 -0
  177. package/templates/terraform/addons/dynamodb.tf +73 -0
  178. package/templates/terraform/addons/redis.tf +64 -0
  179. package/templates/terraform/addons/s3.tf +143 -0
  180. package/templates/terraform/addons/ses.tf +73 -0
  181. package/templates/terraform/addons/sqs.tf +67 -0
  182. package/templates/terraform/backend.tf +22 -0
  183. package/templates/terraform/cloudfront-lambda.tf +80 -0
  184. package/templates/terraform/cloudfront.tf +80 -0
  185. package/templates/terraform/database-aurora-postgresql.tf +92 -0
  186. package/templates/terraform/database-mysql.tf +72 -0
  187. package/templates/terraform/database.tf +71 -0
  188. package/templates/terraform/main-lambda.tf +229 -0
  189. package/templates/terraform/main.tf +296 -0
  190. package/templates/terraform/network.tf +95 -0
  191. package/templates/terraform/oidc.tf +64 -0
  192. package/templates/terraform/secrets.tf +31 -0
  193. package/templates/terraform/worker.tf +69 -0
  194. package/tests/__snapshots__/generator.test.js.snap +9633 -0
  195. package/tests/add.test.js +2037 -0
  196. package/tests/ai.test.js +94 -0
  197. package/tests/apply.test.js +488 -0
  198. package/tests/args.test.js +86 -0
  199. package/tests/aws.test.js +244 -0
  200. package/tests/capabilities.test.js +307 -0
  201. package/tests/cli.test.js +29 -0
  202. package/tests/command.test.js +100 -0
  203. package/tests/commands-import.test.js +74 -0
  204. package/tests/db.test.js +2704 -0
  205. package/tests/destroy.test.js +391 -0
  206. package/tests/detector.test.js +79 -0
  207. package/tests/diagnose.test.js +779 -0
  208. package/tests/doctor.test.js +202 -0
  209. package/tests/domain.test.js +899 -0
  210. package/tests/drift.test.js +243 -0
  211. package/tests/ecs.test.js +130 -0
  212. package/tests/eject.test.js +65 -0
  213. package/tests/exec.test.js +380 -0
  214. package/tests/gc.test.js +496 -0
  215. package/tests/generator.test.js +794 -0
  216. package/tests/headless.test.js +562 -0
  217. package/tests/lambda-ecr.test.js +185 -0
  218. package/tests/logs.test.js +447 -0
  219. package/tests/parser.test.js +160 -0
  220. package/tests/rds.test.js +244 -0
  221. package/tests/resolvers.test.js +282 -0
  222. package/tests/rollback.test.js +692 -0
  223. package/tests/secrets.test.js +752 -0
  224. package/tests/sleep-wake.test.js +1016 -0
  225. package/tests/status.test.js +370 -0
  226. package/tests/system.test.js +70 -0
  227. package/tests/telemetry.test.js +520 -0
  228. package/tests/terraform.test.js +84 -0
  229. package/tests/visualizer.test.js +496 -0
  230. package/vitest.config.js +9 -0
  231. package/index.js +0 -2
@@ -0,0 +1,14 @@
1
+ {
2
+ "pid": 23981,
3
+ "port": 4321,
4
+ "url": "http://127.0.0.1:4321",
5
+ "urls": {
6
+ "local": [
7
+ "http://127.0.0.1:4321/"
8
+ ],
9
+ "network": [],
10
+ "networkInterfaceNames": []
11
+ },
12
+ "background": false,
13
+ "startedAt": "2026-09-24T10:12:19.581Z"
14
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "_variables": {
3
+ "lastUpdateCheck": 1789924675360
4
+ }
5
+ }
@@ -0,0 +1,2 @@
1
+ /// <reference types="astro/client" />
2
+ /// <reference path="content.d.ts" />
@@ -0,0 +1,97 @@
1
+ import { defineConfig } from 'astro/config';
2
+ import starlight from '@astrojs/starlight';
3
+
4
+ // https://starlight.astro.build/reference/configuration/
5
+ export default defineConfig({
6
+ site: 'https://grada-run.github.io',
7
+ base: '/grada',
8
+ redirects: {
9
+ '/adrs/001-initial-architecture/': '/grada/adrs/0001-s3-native-state-locking/',
10
+ },
11
+ integrations: [
12
+ starlight({
13
+ title: 'Grada',
14
+ description: 'Provision production-ready AWS infrastructure and CI/CD pipelines in seconds.',
15
+ customCss: ['./src/custom.css'],
16
+ social: [
17
+ { icon: 'github', label: 'GitHub', href: 'https://github.com/grada-run/grada' },
18
+ ],
19
+ editLink: {
20
+ baseUrl: 'https://github.com/grada-run/grada/edit/main/apps/docs/',
21
+ },
22
+ lastUpdated: true,
23
+ sidebar: [
24
+ {
25
+ label: 'Deployment Guides',
26
+ collapsed: true,
27
+ items: [
28
+ { label: 'Quickstart (5 minutes)', slug: 'guides/quickstart' },
29
+ { label: 'Stack Architecture', slug: 'guides/architecture' },
30
+ { label: 'CI/CD Pipeline & First Deploy', slug: 'guides/cicd-pipeline' },
31
+ { label: 'Supported Frameworks', slug: 'guides/frameworks' },
32
+ { label: 'Reference Implementations & Examples', slug: 'guides/examples' },
33
+ { label: 'Dockerfiles & Containers', slug: 'guides/dockerfiles' },
34
+ { label: 'Docker Compose', slug: 'guides/docker-compose' },
35
+ { label: 'Background Workers', slug: 'guides/background-workers' },
36
+ { label: 'Managed Database Connections', slug: 'guides/database-connections' },
37
+ { label: 'Secrets Management', slug: 'guides/secrets-management' },
38
+ { label: 'Ephemeral PR Previews', slug: 'guides/ephemeral-pr-previews' },
39
+ { label: 'Understanding Your AWS Bill', slug: 'guides/understanding-your-bill' },
40
+ { label: 'Troubleshooting AWS Credentials', slug: 'guides/aws-credentials' },
41
+ { label: 'Re-running Init Safely', slug: 'guides/rerun-init' },
42
+ { label: 'Headless Mode & Automation', slug: 'guides/headless' },
43
+ ],
44
+ },
45
+ {
46
+ label: 'CLI Reference',
47
+ collapsed: true,
48
+ items: [
49
+ { label: 'npx grada-run (init)', slug: 'cli/init' },
50
+ { label: 'apply', slug: 'cli/apply' },
51
+ { label: 'destroy', slug: 'cli/destroy' },
52
+ { label: 'secrets', slug: 'cli/secrets' },
53
+ { label: 'diagnose', slug: 'cli/diagnose' },
54
+ { label: 'logs', slug: 'cli/logs' },
55
+ { label: 'status', slug: 'cli/status' },
56
+ { label: 'rollback', slug: 'cli/rollback' },
57
+ { label: 'exec', slug: 'cli/exec' },
58
+ { label: 'db', slug: 'cli/db' },
59
+ { label: 'gc', slug: 'cli/gc' },
60
+ { label: 'doctor', slug: 'cli/doctor' },
61
+ { label: 'eject', slug: 'cli/eject' },
62
+ { label: 'sync-ai', slug: 'cli/sync-ai' },
63
+ { label: 'add', slug: 'cli/add' },
64
+ { label: 'domain', slug: 'cli/domain' },
65
+ { label: 'sleep & wake', slug: 'cli/sleep' },
66
+ { label: 'drift', slug: 'cli/drift' },
67
+ ],
68
+ },
69
+ {
70
+ label: 'Platform Migrations',
71
+ collapsed: true,
72
+ items: [
73
+ { label: 'Vercel (Next.js)', slug: 'migrations/nextjs-vercel-to-aws' },
74
+ { label: 'Heroku (Procfile)', slug: 'migrations/heroku-procfile-to-aws' },
75
+ { label: 'Vercel (Astro)', slug: 'migrations/astro-vercel-to-aws' },
76
+ { label: 'Vercel (SvelteKit)', slug: 'migrations/sveltekit-vercel-to-aws' },
77
+ ],
78
+ },
79
+ {
80
+ label: 'Project Details',
81
+ collapsed: true,
82
+ items: [
83
+ { label: 'Roadmap', slug: 'roadmap' },
84
+ { label: 'Testing Strategy', slug: 'testing-strategy' },
85
+ ],
86
+ },
87
+ {
88
+ label: 'Architecture (ADRs)',
89
+ collapsed: true,
90
+ items: [
91
+ { autogenerate: { directory: 'adrs' } }
92
+ ],
93
+ },
94
+ ],
95
+ }),
96
+ ],
97
+ });
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "docs",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "astro dev",
8
+ "build": "astro build",
9
+ "preview": "astro preview"
10
+ },
11
+ "dependencies": {
12
+ "@astrojs/starlight": "^0.42.2",
13
+ "astro": "^7.3.3",
14
+ "js-yaml": "^4.3.2",
15
+ "sharp": "^0.34.2"
16
+ }
17
+ }
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: "S3 Native State Locking"
3
+ description: "Use S3-native locking for Terraform remote state without DynamoDB."
4
+ ---
5
+
6
+ * **Status:** Accepted
7
+ * **Date:** 2026-08-15 (Retroactive)
8
+
9
+ ## Context and Problem Statement
10
+
11
+ When deploying infrastructure via Terraform across local developer workstations and automated CI/CD pipelines, remote state management is required to prevent race conditions, state drift, and concurrent apply corruption.
12
+
13
+ Traditionally, managing Terraform remote state on AWS required provisioning both an S3 bucket (for storage) and a dedicated DynamoDB table (for state locking). This added operational overhead, increased the baseline AWS resource footprint, and required developers to manage extra IAM permissions solely for locking metadata.
14
+
15
+ ## Decision Drivers
16
+
17
+ * **Simplicity:** Minimize the number of AWS resources a user has to provision and manage day-to-day.
18
+ * **Cost Efficiency:** Eliminate unnecessary idle infrastructure costs (e.g., DynamoDB provisioned capacity).
19
+ * **Reliability:** Guarantee that concurrent CI/CD pipeline runs and local CLI executions cannot corrupt Terraform state files.
20
+
21
+ ## Considered Options
22
+
23
+ 1. **S3 + DynamoDB Table:** The traditional HashiCorp recommendation for remote state locking.
24
+ 2. **S3 Native State Locking:** Utilizing S3's native conditional write support for state locking directly within the S3 bucket backend.
25
+ 3. **Third-Party State Backends:** (e.g., Terraform Cloud) — rejected to preserve zero-vendor-lock-in and keep execution local to the user's AWS account.
26
+
27
+ ## Decision Outcome
28
+
29
+ **Chosen Option:** Use an encrypted Amazon S3 bucket as the remote state backend leveraging Terraform's native S3 state locking capabilities.
30
+
31
+ ### Positive Consequences
32
+ * **Zero Maintenance:** Users do not have to monitor, manage, or pay for an extra DynamoDB table.
33
+ * **Tighter Security:** Simplifies the IAM policy scope required for the `grada` state bucket helper, adhering strictly to least privilege.
34
+ * **Frictionless Onboarding:** Streamlines the bootstrapping experience during the initial `npx grada-run` run.
35
+
36
+ ### Negative Consequences
37
+ * Relies on modern Terraform backend behavior that supports S3 native locks. Edge cases involving highly outdated, legacy Terraform CLI versions are not supported.
@@ -0,0 +1,39 @@
1
+ ---
2
+ title: "Eject Mechanism for Pure IaC"
3
+ description: "Keep generated Terraform and leave the CLI with the eject mechanism."
4
+ ---
5
+
6
+ * **Status:** Accepted
7
+ * **Date:** 2026-08-20 (Retroactive)
8
+
9
+ ## Context and Problem Statement
10
+
11
+ `grada` abstracts away the complexity of writing raw Terraform for ECS Fargate, ALBs, CloudFront, OIDC, and Secrets Manager. However, a primary reason senior platform teams hesitate to adopt deployment generators is the fear of **tool lock-in**. Teams need a guarantee that if their architecture outgrows the CLI, or if they wish to take 100% manual control of the codebase, they can do so without starting from scratch.
12
+
13
+ ## Decision Drivers
14
+
15
+ * **Zero Vendor Lock-In:** Uphold the foundational promise that developers permanently own their infrastructure code.
16
+ * **Auditability & Freedom:** Provide teams with an unambiguous "escape hatch" to sever ties with `grada` management metadata while maintaining a perfectly functioning infrastructure pipeline.
17
+
18
+ ## Considered Options
19
+
20
+ 1. **No Eject Command:** Require users to manually delete `ManagedBy` tags and untangle state/workflows by hand.
21
+ 2. **Submodule / Framework Wrapper:** Keep the Terraform code hidden inside a remote module (rejected, as it violates the core premise of transparent, readable IaC).
22
+ 3. **Explicit `eject` Command:** Build a dedicated `npx grada-run eject` utility that strips all CLI metadata and tracking tags, leaving behind clean, standard Terraform and GitHub Actions files.
23
+
24
+ ## Decision Outcome
25
+
26
+ **Chosen Option:** Implement an explicit `npx grada-run eject` command as a core feature.
27
+
28
+ ### Technical Implementation Details
29
+ When invoked, `eject`:
30
+ * Removes or sanitizes internal `ManagedBy = "grada"` default tags across all generated files.
31
+ * Preserves all generated `.tf`, `Dockerfile`, and `.github/workflows/` files safely in place.
32
+ * Detaches the project from the CLI entirely, leaving valid Terraform code that can be managed directly via the `terraform` or `opentofu` binaries.
33
+
34
+ ### Positive Consequences
35
+ * Builds trust with engineers and security teams who refuse black-box wrappers.
36
+ * Eliminates friction during adoption; users know they can safely leave at any time.
37
+
38
+ ### Negative Consequences
39
+ * Ejected repositories permanently lose access to automated security patches, template updates, or CLI-driven drift synchronization.
@@ -0,0 +1,48 @@
1
+ ---
2
+ title: "AI Context Synchronization Strategy"
3
+ description: "Sync IaC context into AI coding assistants with sync-ai."
4
+ ---
5
+
6
+ * **Status:** Accepted
7
+ * **Date:** 2026-09-02 (Retroactive)
8
+
9
+ ## Context and Problem Statement
10
+
11
+ Modern engineering teams heavily utilize AI coding assistants (Cursor, GitHub Copilot, Windsurf, Claude Code, etc.) in their local IDEs. However, when dealing with Infrastructure-as-Code (IaC), AI models frequently hallucinate invalid Terraform syntax, recommend destructive manual AWS CLI commands, or ignore critical project-specific constraints like unprivileged container ports and OIDC auth flows.
12
+
13
+ Furthermore, automatically writing instruction files into user repositories carries a high risk of clobbering a team's existing, carefully crafted agent prompts.
14
+
15
+ ## Decision Drivers
16
+
17
+ * **Hallucination Mitigation:** Provide structured, deterministic instructions to IDE AI assistants to ensure they generate valid Terraform and safe workflows.
18
+ * **Non-Destructive Integration:** Guarantee that existing `.cursorrules`, `CLAUDE.md`, or shared workspace instruction files are never accidentally overwritten or destroyed.
19
+ * **Multi-Tool Support:** Support the highly fragmented landscape of AI coding tools without forcing users into a specific IDE.
20
+
21
+ ## Considered Options
22
+
23
+ 1. **Single Global Instruction File:** Only support `.cursorrules` (rejected as too narrow for modern multi-tool teams).
24
+ 2. **Blind Overwrite of Agent Files:** Replace existing AI rule files with `grada` defaults (rejected due to the unacceptable risk of destroying user configuration).
25
+ 3. **Isolated Rule Files + Delimited Block Injection (`sync-ai`):** Create dedicated files where supported (e.g., `grada.mdc`), and safely inject delimited, managed markdown blocks into existing shared instruction files where necessary.
26
+
27
+ ## Decision Outcome
28
+
29
+ **Chosen Option:** Build a dedicated `npx grada-run sync-ai` command and a non-destructive auto-injection engine.
30
+
31
+ ### Supported Targets
32
+ The engine intelligently maps instructions to the following environments:
33
+ * **Cursor:** `.cursor/rules/grada.mdc`
34
+ * **Roo Code / Roo-Cline:** `.roo/rules/grada.md`
35
+ * **Trae:** `.trae/rules/project_rules.md` (managed block injection)
36
+ * **Continue:** `.prompts/grada.prompt`
37
+ * **Windsurf:** `.windsurfrules` (managed block injection)
38
+ * **GitHub Copilot:** `.github/copilot-instructions.md` (managed block injection)
39
+ * **Claude Code:** `CLAUDE.md` (managed block injection)
40
+ * **Goose:** `.goosehints`
41
+ * **Aider:** `.aider.conf.yml` / `.aider.model.settings.yml`
42
+
43
+ ### Positive Consequences
44
+ * Dramatically reduces AI-induced infrastructure errors and dangerous AWS CLI recommendations.
45
+ * Safe, idempotent execution allows teams to run `npx grada-run sync-ai` whenever their architecture parameters (like AWS region or ports) change, without fear of losing their own prompts.
46
+
47
+ ### Negative Consequences
48
+ * Requires ongoing maintenance of parser logic and block delimiters as AI coding assistant vendors rapidly change their configuration file specifications.
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: "IaC-Driven Diagnostic Context (Stateless CLI)"
3
+ description: "Let diagnose fetch CloudWatch and ECS context without local state."
4
+ ---
5
+
6
+ * **Status:** Accepted
7
+ * **Date:** 2026-09-19
8
+
9
+ ## Context and Problem Statement
10
+
11
+ To provide a seamless developer experience, the `grada diagnose` command needs to automatically fetch CloudWatch logs and ECS task failures without requiring the user to manually input their AWS Region, Cluster Name, or Log Group.
12
+
13
+ We needed a mechanism to persist or infer the deployment context locally so the CLI knows where to look for errors.
14
+
15
+ ## Decision Drivers
16
+
17
+ * **Statelessness:** The CLI should avoid managing internal database files or proprietary local state files that can fall out of sync with actual infrastructure.
18
+ * **Single Source of Truth:** Terraform is already the declarative source of truth for the project's infrastructure.
19
+ * **Ecosystem Compatibility:** Developers often delete node_modules or switch laptops; context retrieval must survive typical Git workflows.
20
+
21
+ ## Considered Options
22
+
23
+ 1. **Local State File:** Create a `.grada/context.json` file upon generation. (Rejected: creates state drift and pollutes version control).
24
+ 2. **AWS Tag Querying:** Use the AWS SDK to query all clusters for a specific tag. (Rejected: too slow, requires broad IAM `ListClusters` permissions, and fails if multiple environments exist).
25
+ 3. **IaC Parsing (Stateless):** Parse the generated `terraform/main.tf` to extract the AWS Region and infer the cluster name from the local directory structure.
26
+
27
+ ## Decision Outcome
28
+
29
+ **Chosen Option:** IaC Parsing (Stateless). The `diagnose` command reads the AWS Region directly via regex from `terraform/main.tf` and constructs standard AWS resource names based on the current working directory.
30
+
31
+ ### Positive Consequences
32
+ * The CLI remains entirely stateless. If the Terraform files exist, the diagnostics work.
33
+ * Enforces the architectural philosophy that the generated IaC is the ultimate source of truth.
34
+ * Zero additional files are added to the user's repository.
35
+
36
+ ### Negative Consequences
37
+ * If a user manually alters the `region` string inside `main.tf` using non-standard formatting, the regex parser may fail to detect it, falling back to a default region.
@@ -0,0 +1,38 @@
1
+ ---
2
+ title: "ECS Fargate and ALB as the Single Runtime Target"
3
+ description: "Run every supported framework on ECS Fargate behind an application load balancer."
4
+ ---
5
+
6
+ * **Status:** Accepted
7
+ * **Date:** 2026-09-24 (Retroactive)
8
+
9
+ ## Context and Problem Statement
10
+
11
+ `grada` promises that any supported framework deploys with one command. Every framework-specific Dockerfile, health-check rule, Terraform module (`templates/terraform/`), and diagnostic runbook only works if there is exactly one production runtime to target.
12
+
13
+ We needed to pick a single AWS compute and ingress combination that covers long-running web servers, workers, and static sites without per-framework infrastructure branches.
14
+
15
+ ## Decision Drivers
16
+
17
+ * **Uniformity:** One set of Terraform modules, one container contract, one diagnostic story for all frameworks.
18
+ * **No-ops fit:** Users choosing this tool do not run an infra team; the runtime must be serverless and scale to zero operational burden.
19
+ * **Health-checkability:** The load balancer must probe container health so failed deploys surface as ALB signals, not silent black holes.
20
+
21
+ ## Considered Options
22
+
23
+ 1. **AWS Lambda / App Runner per framework.** (Rejected: request/response and timeout limits exclude long-running servers and workers; would force framework-specific branches.)
24
+ 2. **EC2 / self-managed clusters.** (Rejected: reintroduces the server management the tool exists to remove.)
25
+ 3. **ECS Fargate + Application Load Balancer.** Containers stay portable across frameworks; ALB gives path-based health checks, listener rules (translated from `vercel.json`), and zero-downtime rolling deploys.
26
+
27
+ ## Decision Outcome
28
+
29
+ **Chosen Option:** ECS Fargate + ALB for all dynamic workloads. Every generated project provisions the same cluster/service/ALB shape; only the image contents and container port vary per framework.
30
+
31
+ ### Positive Consequences
32
+ * Framework support reduces to Dockerfile + port + bind-address requirements (`src/utils/detector.js`, `src/utils/warnings.js`).
33
+ * `diagnose` can assume ALB health-check semantics for every project.
34
+ * Static sites reuse the same pipeline with an Nginx image instead of a framework server.
35
+
36
+ ### Negative Consequences
37
+ * Cold-start-sensitive or GPU workloads are out of scope; the tool cannot serve them without a second runtime target.
38
+ * Users pay Fargate minimums even for idle preview environments.
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: "GitHub OIDC Authentication, No Stored AWS Keys"
3
+ description: "Authenticate CI/CD with short-lived OIDC tokens instead of long-lived AWS keys."
4
+ ---
5
+
6
+ * **Status:** Accepted
7
+ * **Date:** 2026-09-24 (Retroactive)
8
+
9
+ ## Context and Problem Statement
10
+
11
+ The generated workflow (`templates/github/deploy.yml`) must authenticate to AWS on every run to sync Terraform and deploy containers. The conventional approach — storing `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` as GitHub secrets — creates rotation burden and a leak surface: any secret exfiltrated from CI grants durable AWS access.
12
+
13
+ We needed an authentication mechanism with no long-lived credential to store, rotate, or leak.
14
+
15
+ ## Decision Drivers
16
+
17
+ * **Zero-secret CI:** Nothing credential-shaped should live in the repository or GitHub secret store.
18
+ * **Least privilege:** Each run should receive credentials scoped to that run only.
19
+ * **First-deploy fit:** Setup must work on a fresh AWS account without pre-provisioned IAM users.
20
+
21
+ ## Considered Options
22
+
23
+ 1. **Long-lived IAM user keys in GitHub Secrets.** (Rejected: rotation burden, durable blast radius on leak, contradicts the zero-secret philosophy.)
24
+ 2. **GitHub OIDC federation.** The workflow declares `id-token: write`, and Terraform (`templates/terraform/oidc.tf`) registers GitHub as an OIDC identity provider with a per-project role. Each run mints a short-lived token; there is nothing to rotate.
25
+ 3. **User-supplied role assumption.** (Rejected as default: pushes IAM setup onto the first-deploy path; kept possible via `create_oidc_provider = false` for accounts that already federate GitHub.)
26
+
27
+ ## Decision Outcome
28
+
29
+ **Chosen Option:** GitHub OIDC federation by default. Generation creates the provider (unless one exists) and a `<project>-github-actions-role`; the workflow assumes it every run.
30
+
31
+ ### Positive Consequences
32
+ * No AWS keys exist anywhere in CI: nothing to rotate, nothing durable to leak.
33
+ * The weekly drift-convergence cron reuses the same mechanism with no extra setup.
34
+
35
+ ### Negative Consequences
36
+ * First `apply` must create the OIDC provider, adding one IAM dependency to the happy path.
37
+ * Accounts with restrictive IAM policies may need an admin to approve provider creation.
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: "Framework Auto-Detection with Graceful Fallback"
3
+ description: "Detect the framework from repo signals and fall back to static instead of failing."
4
+ ---
5
+
6
+ * **Status:** Accepted
7
+ * **Date:** 2026-09-24 (Retroactive)
8
+
9
+ ## Context and Problem Statement
10
+
11
+ Setup must preselect the right framework preset without interrogating the user about files they may not understand — but repository signals are unreliable: `package.json` may be malformed, `vercel.json` may be empty, and unknown stacks must still produce a working project.
12
+
13
+ We needed detection rules that are helpful when signals exist and harmless when they do not.
14
+
15
+ ## Decision Drivers
16
+
17
+ * **Never block generation:** A strange repo must still scaffold; a wrong guess the user can override beats a fatal error.
18
+ * **Deterministic precedence:** Overlapping signals (e.g. `express` inside a NestJS app) must resolve the same way every run.
19
+ * **Advance warning:** Framework-specific runtime requirements (bind address, build output, adapter) should surface before infrastructure exists, not after the first 502.
20
+
21
+ ## Considered Options
22
+
23
+ 1. **Interactive-only selection.** (Rejected: slow, and headless/CI generation needs a non-interactive path.)
24
+ 2. **Strict detection, fail on ambiguity.** (Rejected: malformed or partial configs would block scaffolding entirely.)
25
+ 3. **Precedence-ordered detection with silent ignore + static fallback.** Checks run top-down (`src/utils/detector.js`); malformed configs are treated as absent, never fatal; anything unmatched falls back to `static`. Post-detection checks (`src/utils/warnings.js`) flag fixable issues with copy-paste remedies.
26
+
27
+ ## Decision Outcome
28
+
29
+ **Chosen Option:** Precedence-ordered detection with graceful fallback. Both `dependencies` and `devDependencies` are searched; empty or malformed signal files are ignored; headless mode without `--framework` resolves the same way.
30
+
31
+ ### Positive Consequences
32
+ * `npx grada-run` succeeds on repos the tool has never seen, producing a deployable static project the user can refine.
33
+ * Warnings arrive with exact fixes at setup time, when they are cheapest to apply.
34
+
35
+ ### Negative Consequences
36
+ * A wrong-but-plausible guess (e.g. Express detected inside a larger framework) silently generates the wrong preset until the user notices.
37
+ * Detection rules must be maintained alongside the ecosystem or they rot into misdetection.
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: "Secrets Contract: Names in Git, Values in AWS"
3
+ description: "Commit secret key names to Terraform while values live only in Secrets Manager."
4
+ ---
5
+
6
+ * **Status:** Accepted
7
+ * **Date:** 2026-09-24 (Retroactive)
8
+
9
+ ## Context and Problem Statement
10
+
11
+ Deployed containers need environment secrets, but committing `.env` contents would leak credentials into git history, and baking values into CI configuration would spread them across logs and workflow files. At the same time, Terraform must know *which* variables exist to wire them into the ECS task definition.
12
+
13
+ We needed a split that keeps values out of version control while keeping the variable set declarative and reviewable.
14
+
15
+ ## Decision Drivers
16
+
17
+ * **Zero plaintext in git:** No secret value may ever be committed, including in history-friendly JSON files.
18
+ * **Declarative wiring:** The task definition must be built from a committed, diffable source so secret rotation is a normal code review.
19
+ * **Day-2 ergonomics:** Adding a variable vs. changing a value must have obviously different, safe procedures.
20
+
21
+ ## Considered Options
22
+
23
+ 1. **Commit `.env` and inject at build time.** (Rejected: values enter git history permanently and leak into image layers and CI logs.)
24
+ 2. **Names-only contract.** `secrets push` uploads values to the `<project>-secrets` vault and writes only key *names* to `terraform/secret_keys.json`, which is committed. Terraform maps each name into the task definition; ECS resolves values from Secrets Manager at runtime.
25
+ 3. **Fully external management.** (Rejected: forces users onto out-of-band secret workflows on day one instead of the guided push/pull/audit loop.)
26
+
27
+ ## Decision Outcome
28
+
29
+ **Chosen Option:** Names-only contract. Key-set changes require committing `secret_keys.json` and redeploying (the task definition is rebuilt); value-only changes take a rolling ECS restart with no redeploy.
30
+
31
+ ### Positive Consequences
32
+ * `secret_keys.json` diffs in pull requests show exactly which variables were added or removed, with zero leak risk.
33
+ * `secrets pull` / `secrets audit` close the onboarding and rotation loops without ever printing values into CI.
34
+
35
+ ### Negative Consequences
36
+ * Forgetting to commit `secret_keys.json` after adding a variable produces a deploy that silently lacks it — a failure mode users must learn once.
37
+ * Secret values remain invisible to code review by design, so a wrong value can only be caught at runtime.
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: "Regenerate from Scratch with Backup on Re-Run"
3
+ description: "Re-running init backs up generated files and regenerates instead of merging."
4
+ ---
5
+
6
+ * **Status:** Accepted
7
+ * **Date:** 2026-09-24 (Retroactive)
8
+
9
+ ## Context and Problem Statement
10
+
11
+ Users re-run `npx grada-run` to change region, size, or framework — but by then the target directory contains previously generated `terraform/`, `Dockerfile`, and workflow files, possibly hand-edited. Merging new output into edited files risks silent half-applied configurations that are worse than either version.
12
+
13
+ We needed re-runs to be safe, predictable, and recoverable.
14
+
15
+ ## Decision Drivers
16
+
17
+ * **Predictability:** Post-run state must equal what generation produces for the new inputs — no merge ghosts.
18
+ * **Recoverability:** Hand edits and previous outputs must never be destroyed without a way back.
19
+ * **Explicitness:** The user must always know exactly what moved and what to do next.
20
+
21
+ ## Considered Options
22
+
23
+ 1. **Three-way merge with user files.** (Rejected: generated IaC has no stable merge grammar; conflicts would be resolved by guessing.)
24
+ 2. **Refuse to overwrite.** (Rejected: makes legitimate reconfiguration (region, size, framework) a manual file-deletion chore.)
25
+ 3. **Backup and regenerate.** On conflict (`src/utils/backup.js`), offer Backup & Regenerate: move existing outputs to `.bak` files (additionally git-ignored so clutter never reaches GitHub), regenerate from scratch, and print the exact next steps.
26
+
27
+ ## Decision Outcome
28
+
29
+ **Chosen Option:** Backup and regenerate. Setup never merges; it backs up, regenerates, and reports.
30
+
31
+ ### Positive Consequences
32
+ * Re-runs are idempotent in effect: same inputs always yield the same tree.
33
+ * No user file is ever destroyed; recovery is a file copy away.
34
+
35
+ ### Negative Consequences
36
+ * Hand edits to generated files are silently forked into `.bak` copies the user must reconcile manually.
37
+ * Repeated re-runs accumulate `.bak` clutter locally (mitigated by git-ignoring the pattern).
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: "Advisory-Only Security Scans in the Pipeline"
3
+ description: "Trivy scans report vulnerabilities without blocking builds or deploys."
4
+ ---
5
+
6
+ * **Status:** Accepted
7
+ * **Date:** 2026-09-24 (Retroactive)
8
+
9
+ ## Context and Problem Statement
10
+
11
+ The generated pipeline scans both Terraform (`CRITICAL,HIGH`) and the built container image on every deploy. Failing the build on findings would enforce security posture — but base-image and transitive-dependency findings routinely arrive faster than fixes, which would turn the deployment pipeline into a lottery where routine pushes fail for reasons outside the user's code.
12
+
13
+ We needed scans to inform without holding deploys hostage.
14
+
15
+ ## Decision Drivers
16
+
17
+ * **Deploy velocity:** A routine push must not fail because an upstream base image published a CVE overnight.
18
+ * **Visibility:** Findings must still land where the team looks, on every run, not rot in a dashboard nobody opens.
19
+ * **Reversibility:** The day the signal is clean enough to gate on, flipping the default must be a one-line change.
20
+
21
+ ## Considered Options
22
+
23
+ 1. **Blocking scans (`exit-code: 1`).** (Rejected: couples deploy success to upstream vulnerability disclosure timing; guarantees false-positive outages.)
24
+ 2. **No scans.** (Rejected: surrenders the IaC and image visibility the pipeline is well placed to provide.)
25
+ 3. **Advisory scans (`exit-code: 0`).** Trivy runs on every deploy for both IaC and image; results land in the GitHub step summary; the build proceeds regardless.
26
+
27
+ ## Decision Outcome
28
+
29
+ **Chosen Option:** Advisory-only scans. Every finding is reported in the step summary; none blocks the rollout.
30
+
31
+ ### Positive Consequences
32
+ * Deploys never fail for third-party CVEs; security signal accumulates without operational pain.
33
+ * Teams adopt the pipeline without fearing day-one red builds from pre-existing findings.
34
+
35
+ ### Negative Consequences
36
+ * Genuinely critical misconfigurations ship unless a human reads the summary — the signal only works if someone looks.
37
+ * Without a ratchet (e.g. fail only on *new* findings), vulnerability debt can grow silently.
@@ -0,0 +1,84 @@
1
+ ---
2
+ title: add
3
+ description: Provision modular cloud addons like private S3 storage, DynamoDB tables, Valkey caching, SQS queues, Bedrock AI access, SES email, or scheduled cron jobs.
4
+ ---
5
+
6
+ Provision modular Day-2 cloud primitives without writing Terraform, configuring IAM policies, or opening the AWS Management Console.
7
+
8
+ ## What it does
9
+
10
+ - `storage:s3` creates a private S3 bucket (encrypted, CloudFront OAC, CORS ready for presigned browser uploads) and injects `S3_BUCKET_NAME` and `S3_CDN_URL` into your container.
11
+ - `db:dynamodb` creates a `PAY_PER_REQUEST` DynamoDB table (no fixed hourly instance cost) with Point-in-Time Recovery, a free VPC Gateway Endpoint, and injects `DYNAMODB_TABLE_NAME` into your container.
12
+ - `db:redis` provisions a cost-optimized ElastiCache for Valkey 8.0 node (Redis-protocol compatible) isolated in your VPC, reachable only from your ECS tasks or Lambda function, and injects `REDIS_URL` into your container.
13
+ - `queue:sqs` creates an SQS queue with long polling and a Dead-Letter Queue, and injects `SQS_QUEUE_URL` and `SQS_DLQ_URL` into your container. If your project has a background worker service, it also wires scale-to-zero auto-scaling driven by queue depth. On `--target lambda` projects the queue ships without a consumer (no worker service exists) — poll from function code or wire an event source mapping yourself.
14
+ - `ai:bedrock` grants your container least-privilege permission to invoke Amazon Bedrock foundation models (no static AWS keys) and injects `BEDROCK_MODEL_ID` into your container. Run it interactively to pick a provider and model from the catalog, or pass `--model <id>` directly.
15
+ - `email:ses` provisions Amazon SES for transactional email: a domain identity, DKIM signing, a `mail.` subdomain for bounce handling with SPF, a DMARC baseline, least-privilege `ses:SendEmail` permissions locked to your sender domain, and `SES_FROM_EMAIL` / `SES_REGION` in your container. With `--zone-id` it creates the verification, DKIM, MX, SPF, and DMARC records in Route 53 automatically; otherwise it outputs the records to add at your DNS provider. If you already ran `domain add`, the domain (and zone) is picked up automatically. The identity, DKIM, MAIL FROM, and DNS records are scoped to the production workspace as account-wide singletons, so PR previews never duplicate or delete them — preview containers inherit sending permission through their own task role.
16
+ - `cron` creates an EventBridge Scheduler schedule that runs a one-off Fargate task from your app's task definition on a `cron(...)` or `rate(...)` expression, with least-privilege `ecs:RunTask` + `iam:PassRole` permissions. One schedule per project: `--name` customizes it, and re-running with `--force` replaces it in place. On `--target lambda` projects the schedule invokes the function directly with a JSON payload carrying the command — handle scheduled events in application code.
17
+ - Every addon attaches least-privilege IAM policies to your task role, so your application code can use the AWS SDK with no extra configuration.
18
+ - Addon files live in `terraform/` (`s3.tf`, `dynamodb.tf`, `redis.tf`, `sqs.tf`, `bedrock.tf`, `ses.tf`, `cron.tf`), so `destroy` tears them down and `eject` keeps them automatically. PR-preview workspaces get isolated per-workspace resources. If your project has a `worker.tf` background service, addon environment variables are injected there too.
19
+ - Emits an `add_run` telemetry event recording the capability and outcome.
20
+
21
+ > **Bedrock model access:** AWS requires you to enable model access in the Bedrock console before your first `InvokeModel` call — including in the regions behind your `us.*` cross-region inference profile. IAM permissions alone are not enough. Anthropic models additionally require a one-time First Time Use (FTU) form in the Bedrock console.
22
+
23
+ > **SES sandbox:** new AWS accounts start in the SES sandbox and can only send to verified addresses. Request production access in the SES console (a short use-case form, usually approved within a day) before sending to real users.
24
+
25
+ ## Usage
26
+
27
+ ```bash
28
+ npx grada-run add storage:s3
29
+ npx grada-run add db:dynamodb
30
+ npx grada-run add db:dynamodb --partition-key userId
31
+ npx grada-run add db:redis
32
+ npx grada-run add queue:sqs
33
+ npx grada-run add ai:bedrock
34
+ npx grada-run add ai:bedrock --model us.anthropic.claude-haiku-4-5-20251001-v1:0
35
+ npx grada-run add ai:bedrock --list-models
36
+ npx grada-run add ai:bedrock --refresh
37
+ npx grada-run add email:ses --domain example.com
38
+ npx grada-run add email:ses --domain example.com --zone-id Z1234567890ABC
39
+ npx grada-run add cron --schedule "cron(0 2 * * ? *)" --cmd "npm run cron"
40
+ npx grada-run add storage:s3 --force
41
+ ```
42
+
43
+ After adding, run `grada apply` (or commit and push to trigger CI) to provision the resource.
44
+
45
+ To switch Bedrock models later, just run `grada add ai:bedrock` again (interactively) or with a new `--model <id>` — the model reference updates in place across `bedrock.tf`, `main.tf`, and `worker.tf` without needing `--force`.
46
+
47
+ ## Flags
48
+
49
+ | Flag | Description |
50
+ | ---- | ----------- |
51
+ | `--region <region>` | Explicit AWS region override. |
52
+ | `--project-name <name>` | Explicit project name override (defaults to the name in `terraform/main.tf`, then the directory name). |
53
+ | `--partition-key <key>` | DynamoDB partition key name (default `id`). Letters, numbers, underscore, hyphen, and dot only. Only applies to `db:dynamodb`. |
54
+ | `--model <id>` | Bedrock model or inference profile ID (default `us.anthropic.claude-sonnet-4-6`). Only applies to `ai:bedrock`. |
55
+ | `--list-models` | Print the Bedrock model catalog (works offline, no project required). Only applies to `ai:bedrock`. |
56
+ | `--refresh` | Refresh the Bedrock model catalog from live AWS data before listing or provisioning. Only applies to `ai:bedrock`. |
57
+ | `--domain <domain>` | Domain for the SES identity (defaults to your `domain add` domain, or prompts interactively). Only applies to `email:ses`. |
58
+ | `--from-email <email>` | Default sender address (default `noreply@<domain>`). Must belong to the SES domain. Only applies to `email:ses`. |
59
+ | `--zone-id <id>` | Route 53 hosted zone ID for automatic DKIM/SPF/DMARC records. Only applies to `email:ses`. |
60
+ | `--schedule <expr>` | EventBridge Scheduler expression, e.g. `cron(0 2 * * ? *)` or `rate(1 hour)` (default `cron(0 0 * * ? *)`). Only applies to `cron`. |
61
+ | `--cmd <command>` | Command to run inside the scheduled container (default `npm run cron`; also accepts `--cron-command`). Only applies to `cron`. |
62
+ | `--name <job>` | Job slug customizing the schedule name (default `daily-job`). Only applies to `cron`. |
63
+ | `--timezone <tz>` | IANA timezone for the schedule expression (default `UTC`). Only applies to `cron`. |
64
+ | `--force` | Overwrite the existing addon file (also accepts `--force=false`). Without it, re-adding refuses to clobber your edits. |
65
+
66
+ Requires a project initialized with `grada` (`terraform/main.tf` must exist).
67
+
68
+ ## Cost & Billing Drivers
69
+
70
+ - `storage:s3`: $0/mo fixed baseline; billed per GB stored ($0.023/GB-mo), S3 PUT/GET requests, and CloudFront egress.
71
+ - `db:dynamodb`: $0/mo fixed instance baseline (the VPC Gateway Endpoint is free); billed per read/write request, table storage ($0.25/GB-mo), and PITR continuous backups ($0.20/GB-mo once data is written).
72
+ - `db:redis`: ~$9.49/mo fixed baseline ($0.013/hr Valkey 8.0 `cache.t4g.micro`); $0 intra-AZ VPC transfer. Each open PR preview runs its own node while the PR is open.
73
+ - `queue:sqs`: $0/mo fixed baseline; first 1M requests/mo free, then $0.40 per million requests.
74
+ - `ai:bedrock`: $0/mo fixed baseline; billed per 1K input/output tokens on `InvokeModel` calls.
75
+ - `email:ses`: $0/mo fixed baseline; $0.10 per 1,000 emails sent.
76
+ - `cron`: $0/mo fixed baseline (first 14M EventBridge Scheduler invocations/mo free); billed only for Fargate seconds while the cron task runs (per-invocation Lambda billing on `--target lambda`).
77
+
78
+ `grada add` prints the cost impact, refreshes the estimate in your `README.md` (or `DEPLOYMENT.md`), and `grada apply` lists active addons in its pre-flight preview. Reference rates are us-east-2; actual charges vary by region and usage.
79
+
80
+ ## See also
81
+
82
+ - [apply](/grada/cli/apply/)
83
+ - [destroy](/grada/cli/destroy/)
84
+ - [domain](/grada/cli/domain/) (serve your app from the same domain SES sends from)