@vertile-ai/iac 0.0.1 → 0.1.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 (68) hide show
  1. package/README.md +73 -37
  2. package/docs/README.md +3 -2
  3. package/docs/index.html +2 -2
  4. package/docs/manifest.md +38 -5
  5. package/examples/bun-hono-api/README.md +9 -0
  6. package/examples/bun-hono-api/infrastructure/iac/iac.do.json +87 -0
  7. package/examples/bun-hono-api/infrastructure/iac/iac.json +107 -0
  8. package/examples/bun-hono-api/package.json +15 -0
  9. package/examples/bun-hono-api/src/index.ts +7 -0
  10. package/examples/go-api/README.md +8 -0
  11. package/examples/go-api/cmd/server/main.go +16 -0
  12. package/examples/go-api/go.mod +3 -0
  13. package/examples/go-api/infrastructure/iac/iac.do.json +90 -0
  14. package/examples/go-api/infrastructure/iac/iac.json +106 -0
  15. package/examples/next-monorepo/README.md +22 -0
  16. package/examples/next-monorepo/apps/admin/package.json +7 -0
  17. package/examples/next-monorepo/apps/web/package.json +7 -0
  18. package/examples/next-monorepo/infrastructure/iac/iac.aws.json +172 -0
  19. package/examples/next-monorepo/infrastructure/iac/iac.do.json +129 -0
  20. package/examples/{dynomic → next-monorepo}/infrastructure/iac/iac.json +102 -23
  21. package/examples/next-monorepo/infrastructure/iac/iac.vercel.json +109 -0
  22. package/examples/{dynomic → next-monorepo}/package.json +2 -2
  23. package/examples/node-api/README.md +8 -0
  24. package/examples/node-api/infrastructure/iac/iac.aws.json +132 -0
  25. package/examples/node-api/infrastructure/iac/iac.json +111 -0
  26. package/examples/node-api/package.json +12 -0
  27. package/examples/node-api/src/server.js +8 -0
  28. package/examples/python-fastapi-api/README.md +8 -0
  29. package/examples/python-fastapi-api/app/main.py +8 -0
  30. package/examples/python-fastapi-api/infrastructure/iac/iac.aws.json +129 -0
  31. package/examples/python-fastapi-api/infrastructure/iac/iac.json +113 -0
  32. package/examples/python-fastapi-api/pyproject.toml +10 -0
  33. package/examples/react-spa/README.md +8 -0
  34. package/examples/react-spa/index.html +2 -0
  35. package/examples/react-spa/infrastructure/iac/iac.aws.json +115 -0
  36. package/examples/react-spa/infrastructure/iac/iac.json +111 -0
  37. package/examples/react-spa/infrastructure/iac/iac.vercel.json +76 -0
  38. package/examples/react-spa/package.json +19 -0
  39. package/examples/react-spa/src/main.jsx +8 -0
  40. package/examples/sveltekit-web/README.md +9 -0
  41. package/examples/sveltekit-web/infrastructure/iac/iac.json +76 -0
  42. package/examples/sveltekit-web/infrastructure/iac/iac.vercel.json +74 -0
  43. package/examples/sveltekit-web/package.json +19 -0
  44. package/examples/sveltekit-web/src/routes/+page.svelte +3 -0
  45. package/examples/sveltekit-web/svelte.config.js +7 -0
  46. package/package.json +1 -1
  47. package/schema/iac.schema.json +83 -2
  48. package/src/apply.mjs +3 -4
  49. package/src/cli.mjs +1 -0
  50. package/src/core/context.mjs +4 -2
  51. package/src/core/deployments.mjs +39 -0
  52. package/src/core/env-files.mjs +38 -0
  53. package/src/core/env-source.mjs +5 -0
  54. package/src/core/hcl.mjs +2 -1
  55. package/src/core/manifest.mjs +15 -1
  56. package/src/core/render.mjs +19 -8
  57. package/src/core/vercel-manifests.mjs +5 -11
  58. package/src/plan.mjs +3 -4
  59. package/src/providers/aws/index.mjs +43 -24
  60. package/src/provision-env.mjs +72 -24
  61. package/src/render.mjs +3 -4
  62. package/src/shared.mjs +0 -4
  63. package/src/sync-env.mjs +33 -38
  64. package/examples/dynomic/README.md +0 -22
  65. package/examples/dynomic/apps/admin/package.json +0 -7
  66. package/examples/dynomic/apps/web/package.json +0 -7
  67. /package/examples/{dynomic → next-monorepo}/apps/admin/vercel.json +0 -0
  68. /package/examples/{dynomic → next-monorepo}/apps/web/vercel.json +0 -0
package/README.md CHANGED
@@ -24,7 +24,7 @@ Terraform and can be used offline.
24
24
  ```bash
25
25
  vertile-iac render --target=all --env=production
26
26
  vertile-iac plan --target=vercel --env=preview
27
- vertile-iac apply --target=aws --env=production --yes
27
+ vertile-iac apply --target=aws --deployment=prod --yes
28
28
 
29
29
  vertile-iac sync-env --repo-root ../noop --variants=local,staging,test
30
30
  vertile-iac env --repo-root ../noop --scope=all --targets=preview,production
@@ -34,6 +34,8 @@ vertile-iac domains --repo-root ../noop
34
34
 
35
35
  The `render`, `plan`, and `apply` commands read `infrastructure/iac/iac.json`
36
36
  and write generated Terraform workspaces to `.vertile/terraform/<target>/`.
37
+ When `--deployment=<name>` maps to a provider deployment, the workspace is
38
+ `.vertile/terraform/<target>/<deployment>/`.
37
39
 
38
40
  Apply is guarded. Non-interactive apply requires `--yes`, which passes
39
41
  Terraform `-auto-approve`.
@@ -55,12 +57,12 @@ The new Terraform flow expects the target project to have:
55
57
 
56
58
  ```text
57
59
  infrastructure/iac/iac.json
58
- infrastructure/shared/.env.development
59
- infrastructure/shared/.env.staging
60
- infrastructure/shared/.env.production
61
- infrastructure/<app-key>/.env.development
62
- infrastructure/<app-key>/.env.staging
63
- infrastructure/<app-key>/.env.production
60
+ .vertile-iac/env/shared/.env.development
61
+ .vertile-iac/env/shared/.env.staging
62
+ .vertile-iac/env/shared/.env.production
63
+ .vertile-iac/env/<app-key>/.env.development
64
+ .vertile-iac/env/<app-key>/.env.staging
65
+ .vertile-iac/env/<app-key>/.env.production
64
66
  ```
65
67
 
66
68
  Minimal `iac.json` example:
@@ -70,10 +72,26 @@ Minimal `iac.json` example:
70
72
  "$schema": "./node_modules/@vertile-ai/iac/schema/iac.schema.json",
71
73
  "version": 1,
72
74
  "project": { "name": "example" },
73
- "environments": ["development", "preview", "production"],
75
+ "environments": ["development", "uat", "production"],
74
76
  "providers": {
75
77
  "vercel": { "team": "example-team" },
76
- "aws": { "region": "us-east-1" },
78
+ "aws": {
79
+ "region": "us-east-1",
80
+ "deployments": {
81
+ "uat": {
82
+ "environment": "uat",
83
+ "region": "us-east-1",
84
+ "profile": "example-uat",
85
+ "tags": { "Stage": "uat" }
86
+ },
87
+ "prod": {
88
+ "environment": "production",
89
+ "region": "us-east-1",
90
+ "profile": "example-prod",
91
+ "tags": { "Stage": "prod" }
92
+ }
93
+ }
94
+ },
77
95
  "digitalocean": {}
78
96
  },
79
97
  "apps": [
@@ -86,7 +104,11 @@ Minimal `iac.json` example:
86
104
  }
87
105
  ],
88
106
  "env": {
89
- "sourceDir": "infrastructure",
107
+ "environments": {
108
+ "development": { "files": [".env.development"] },
109
+ "uat": { "files": [".env.uat"] },
110
+ "production": { "files": [".env.production"] }
111
+ },
90
112
  "sync": {
91
113
  "apps": ["web"]
92
114
  }
@@ -109,16 +131,13 @@ Provider-specific Terraform resources can be added under
109
131
  `providers.<target>.resources` as `{ "type", "name", "values" }` objects while
110
132
  the manifest schema stays narrow.
111
133
 
112
- The compatibility Vercel commands expect the target project to have:
134
+ Provider deployments map user-defined stage names such as `uat`, `nightly`, or
135
+ `prod` to logical environments and provider-specific inputs. AWS uses deployment
136
+ values for provider region/profile, generated workspace path, resource names,
137
+ and default tags. The logical environment still controls env file selection.
113
138
 
114
- ```text
115
- infrastructure/shared/.env.development
116
- infrastructure/shared/.env.staging
117
- infrastructure/shared/.env.production
118
- infrastructure/<project-key>/.env.development
119
- infrastructure/<project-key>/.env.staging
120
- infrastructure/<project-key>/.env.production
121
- ```
139
+ By default, Vercel env reconciliation reads `.env.*` files from
140
+ `.vertile-iac/env/shared` and `.vertile-iac/env/<project-key>`.
122
141
 
123
142
  When the old compatibility files exist, they are used directly:
124
143
 
@@ -132,26 +151,28 @@ When they do not exist, the Vercel commands derive equivalent manifests from
132
151
  `iac.json`:
133
152
 
134
153
  - `providers.vercel.teamSlug` or `providers.vercel.team` becomes the Vercel team.
135
- - `env.sourceDir` selects the env source folder and defaults to `infrastructure`.
154
+ - `env.sourceDir` selects the env source folder and defaults to `.vertile-iac/env`.
155
+ - `env.environments.<name>.files` maps logical environments to ordered env files.
136
156
  - `apps[].key`, `apps[].id` or `apps[].projectId`, and `apps[].name` become managed Vercel projects.
137
157
  - `apps[].rootDirectory`, `apps[].nodeVersion`, and
138
158
  `apps[].enableAffectedProjectsDeployments` become project settings.
139
159
  - `apps[].domains` and top-level `domains[]` become project domains.
140
160
 
141
- Vercel targets map to env files as follows:
161
+ Vercel targets map to logical environments as follows by default:
142
162
 
143
- - `development` -> `.env.development`
144
- - `preview` -> `.env.staging`
145
- - `production` -> `.env.production`
163
+ - `development` -> `development`
164
+ - `preview` -> `staging`
165
+ - `production` -> `production`
146
166
 
147
- Pure local env files such as `.env.local` are intentionally not synced to
148
- Vercel. The default manifest location can be overridden:
167
+ Those logical environments then resolve through `env.environments`. For example,
168
+ `staging` defaults to `.env.staging`, but can be configured as
169
+ `"staging": { "files": [".env.preview", ".env.staging"] }`.
170
+ The default manifest location can be overridden:
149
171
 
150
172
  ```bash
151
173
  vertile-iac env \
152
174
  --repo-root ../some-project \
153
- --manifest ./deploy/env-manifest.json \
154
- --infra-dir infrastructure
175
+ --manifest ./deploy/env-manifest.json
155
176
  ```
156
177
 
157
178
  ## Env File Sync
@@ -162,13 +183,17 @@ which reconciles Vercel remote environment variables.
162
183
 
163
184
  The boundary is:
164
185
 
165
- - `env.sourceDir` is the source tree, defaulting to `infrastructure`.
186
+ - `env.sourceDir` is the source tree, defaulting to `.vertile-iac/env`.
187
+ - `env.environments.<name>.files` declares ordered source files for any logical
188
+ environment, including custom names such as `uat`, `nightly`, or `qa`.
166
189
  - `env.sync.sharedKey` is the shared source folder, defaulting to `shared`.
167
190
  - `env.sync.apps` limits which `apps[]` are materialized locally. Without it,
168
191
  all apps are synced.
169
192
  - Each app reads from `<env.sourceDir>/<app.key>` by default.
170
193
  - Each app writes into `apps[].rootDirectory` by default.
171
194
  - `apps[].env.sourceKey` and `apps[].env.outputDir` override those defaults.
195
+ - When the same key exists in shared and app-specific files, the app-specific
196
+ value wins in generated package `.env.*` files.
172
197
  - `apps[].env.sharedPrefix` projects prefixed shared keys into one app, strips
173
198
  the prefix in that app's generated file, and keeps those prefixed keys out of
174
199
  other generated app env files.
@@ -178,7 +203,6 @@ Examples:
178
203
  ```json
179
204
  {
180
205
  "env": {
181
- "sourceDir": "infrastructure",
182
206
  "sync": {
183
207
  "apps": ["landing", "web-client", "web-server"],
184
208
  "sharedKey": "shared"
@@ -194,8 +218,9 @@ Examples:
194
218
  }
195
219
  ```
196
220
 
197
- Supported local sync variants are `local`, `staging`, `preview`, `production`,
198
- and `test`. `preview` is an alias for `.env.staging`.
221
+ Built-in local sync variants are `local`, `staging`, `preview`, `production`,
222
+ and `test`. Custom variants declared in `env.environments` can also be selected
223
+ with `--variants`, such as `--variants=uat,nightly`.
199
224
 
200
225
  ## Shared Options
201
226
 
@@ -204,7 +229,6 @@ and `test`. `preview` is an alias for `.env.staging`.
204
229
  - `--manifest <path>`: env manifest path.
205
230
  - `--project-settings <path>`: project settings manifest path.
206
231
  - `--project-domains <path>`: project domains manifest path.
207
- - `--infra-dir <path>`: override `env-manifest.json` `infraDir`.
208
232
  - `--token-file <path>`: token file, default `<repo-root>/.vercel.token`.
209
233
  - `--auto-create-keys <a,b>`: project keys allowed for Vercel auto-create.
210
234
  - `--auto-create-prefixes <a,b>`: project key prefixes allowed for Vercel auto-create.
@@ -212,6 +236,7 @@ and `test`. `preview` is an alias for `.env.staging`.
212
236
  - `--out <path>`: generated Terraform root, default `.vertile/terraform`.
213
237
  - `--target <name|all>`: `vercel`, `aws`, `digitalocean`, or `all`.
214
238
  - `--env <name>`: environment to render, plan, or apply, default `production`.
239
+ - `--deployment <name>`: provider deployment/stage name, such as `uat` or `prod`.
215
240
  - `--terraform-bin <path>`: Terraform executable for `plan`, default `terraform`.
216
241
  - `--yes`: allow non-interactive `apply` with Terraform auto-approve.
217
242
 
@@ -225,10 +250,21 @@ docs/index.html
225
250
 
226
251
  ## Examples
227
252
 
228
- `examples/dynomic` is a publishable fixture project that shows the current app
229
- shape for Vercel project settings, domains, preview/production env
230
- provisioning, local package env sync, portable resource concepts, provider
231
- overrides, and provider-specific escape hatch resources.
253
+ The `examples/` directory uses runtime-oriented fixture names so each project
254
+ shape is clear at a glance:
255
+
256
+ - `examples/node-api`
257
+ - `examples/bun-hono-api`
258
+ - `examples/react-spa`
259
+ - `examples/next-monorepo`
260
+ - `examples/sveltekit-web`
261
+ - `examples/python-fastapi-api`
262
+ - `examples/go-api`
263
+
264
+ Every example keeps a portable `infrastructure/iac/iac.json`. Examples with
265
+ provider-specific fields also include standalone provider variants such as
266
+ `iac.aws.json`, `iac.vercel.json`, or `iac.do.json` that can be passed with
267
+ `--iac-manifest`.
232
268
 
233
269
  ## Schema
234
270
 
package/docs/README.md CHANGED
@@ -27,6 +27,7 @@ Generated Terraform lives under:
27
27
 
28
28
  ```text
29
29
  .vertile/terraform/<provider>/
30
+ .vertile/terraform/<provider>/<deployment>/
30
31
  ```
31
32
 
32
33
  Users edit the manifest. Vertile AI IaC renders provider-specific infrastructure.
@@ -35,6 +36,6 @@ Users edit the manifest. Vertile AI IaC renders provider-specific infrastructure
35
36
 
36
37
  ```bash
37
38
  vertile-iac render --target=all --env=production
38
- vertile-iac plan --target=aws --env=production
39
- vertile-iac apply --target=aws --env=production --yes
39
+ vertile-iac plan --target=aws --deployment=prod
40
+ vertile-iac apply --target=aws --deployment=prod --yes
40
41
  ```
package/docs/index.html CHANGED
@@ -264,8 +264,8 @@
264
264
  <p>Crossplane makes Kubernetes the infrastructure control plane. Vertile AI IaC uses a Git repo and CLI as the control surface, which is lighter for solo builders and app-first teams.</p>
265
265
  <pre><code>pnpm add -D @vertile-ai/iac
266
266
  vertile-iac render --target=all --env=production
267
- vertile-iac plan --target=aws --env=production
268
- vertile-iac apply --target=aws --env=production --yes</code></pre>
267
+ vertile-iac plan --target=aws --deployment=prod
268
+ vertile-iac apply --target=aws --deployment=prod --yes</code></pre>
269
269
  </section>
270
270
  </main>
271
271
 
package/docs/manifest.md CHANGED
@@ -12,6 +12,7 @@ Generated Terraform is an implementation detail:
12
12
  .vertile/terraform/vercel/
13
13
  .vertile/terraform/aws/
14
14
  .vertile/terraform/digitalocean/
15
+ .vertile/terraform/<provider>/<deployment>/
15
16
  ```
16
17
 
17
18
  ## Minimal Manifest
@@ -21,10 +22,26 @@ Generated Terraform is an implementation detail:
21
22
  "$schema": "./node_modules/@vertile-ai/iac/schema/iac.schema.json",
22
23
  "version": 1,
23
24
  "project": { "name": "example" },
24
- "environments": ["development", "preview", "production"],
25
+ "environments": ["development", "uat", "production"],
25
26
  "providers": {
26
27
  "vercel": { "team": "example-team" },
27
- "aws": { "region": "us-east-1" },
28
+ "aws": {
29
+ "region": "us-east-1",
30
+ "deployments": {
31
+ "uat": {
32
+ "environment": "uat",
33
+ "region": "us-east-1",
34
+ "profile": "example-uat",
35
+ "tags": { "Stage": "uat" }
36
+ },
37
+ "prod": {
38
+ "environment": "production",
39
+ "region": "us-east-1",
40
+ "profile": "example-prod",
41
+ "tags": { "Stage": "prod" }
42
+ }
43
+ }
44
+ },
28
45
  "digitalocean": {}
29
46
  },
30
47
  "apps": [
@@ -41,7 +58,14 @@ Generated Terraform is an implementation detail:
41
58
  "databases": [{ "key": "appdb", "engine": "postgres" }],
42
59
  "queues": [{ "key": "jobs" }],
43
60
  "sandboxes": [{ "key": "runner" }],
44
- "clusters": [{ "key": "workers", "size": 2 }]
61
+ "clusters": [{ "key": "workers", "size": 2 }],
62
+ "env": {
63
+ "environments": {
64
+ "development": { "files": [".env.development"] },
65
+ "uat": { "files": [".env.uat"] },
66
+ "production": { "files": [".env.production"] }
67
+ }
68
+ }
45
69
  }
46
70
  ```
47
71
 
@@ -94,6 +118,15 @@ Provider-specific Terraform resources can be expressed under
94
118
  Use this as a bridge, not as the primary authoring model. The long-term goal is
95
119
  to promote common patterns into first-class portable concepts.
96
120
 
121
+ ## Environments And Deployments
122
+
123
+ Logical environments control env file selection. By default, env sources live in
124
+ `.vertile-iac/env/shared` and `.vertile-iac/env/<app-key>`.
125
+
126
+ Provider deployments map stage names such as `uat` or `prod` to a logical
127
+ environment plus provider-specific inputs. AWS uses deployment values for
128
+ region/profile, generated workspace path, resource names, and default tags.
129
+
97
130
  ## Supported Concepts
98
131
 
99
132
  | Concept | Vercel | AWS | DigitalOcean |
@@ -120,11 +153,11 @@ vertile-iac render --target=all --env=production
120
153
  Preview changes with Terraform:
121
154
 
122
155
  ```bash
123
- vertile-iac plan --target=aws --env=production
156
+ vertile-iac plan --target=aws --deployment=prod
124
157
  ```
125
158
 
126
159
  Apply changes with explicit non-interactive approval:
127
160
 
128
161
  ```bash
129
- vertile-iac apply --target=aws --env=production --yes
162
+ vertile-iac apply --target=aws --deployment=prod --yes
130
163
  ```
@@ -0,0 +1,9 @@
1
+ # Bun Hono API
2
+
3
+ Bun backend example using Hono-style project structure with an explicit
4
+ DigitalOcean variant.
5
+
6
+ ```bash
7
+ vertile-iac render --repo-root examples/bun-hono-api --target=all --deployment=prod
8
+ vertile-iac render --repo-root examples/bun-hono-api --iac-manifest infrastructure/iac/iac.do.json --target=digitalocean --env=production
9
+ ```
@@ -0,0 +1,87 @@
1
+ {
2
+ "$schema": "../../../../schema/iac.schema.json",
3
+ "version": 1,
4
+ "project": {
5
+ "key": "bun-hono-api",
6
+ "name": "bun-hono-api"
7
+ },
8
+ "environments": [
9
+ "development",
10
+ "test",
11
+ "uat",
12
+ "nightly",
13
+ "staging",
14
+ "preview",
15
+ "production"
16
+ ],
17
+ "providers": {
18
+ "digitalocean": {
19
+ "region": "sfo3",
20
+ "resources": [
21
+ {
22
+ "type": "digitalocean_project",
23
+ "name": "main",
24
+ "values": {
25
+ "name": "bun-hono-api"
26
+ }
27
+ }
28
+ ]
29
+ }
30
+ },
31
+ "apps": [
32
+ {
33
+ "key": "api",
34
+ "name": "bun-hono-api",
35
+ "framework": "bun",
36
+ "rootDirectory": "."
37
+ }
38
+ ],
39
+ "databases": [
40
+ {
41
+ "key": "appdb",
42
+ "engine": "postgres",
43
+ "providers": {
44
+ "digitalocean": {
45
+ "engine": "pg",
46
+ "version": "16",
47
+ "size": "db-s-1vcpu-1gb",
48
+ "nodeCount": 1
49
+ }
50
+ }
51
+ }
52
+ ],
53
+ "env": {
54
+ "environments": {
55
+ "development": {
56
+ "files": [
57
+ ".env.development"
58
+ ]
59
+ },
60
+ "test": {
61
+ "files": [
62
+ ".env.test"
63
+ ]
64
+ },
65
+ "uat": {
66
+ "files": [
67
+ ".env.uat"
68
+ ]
69
+ },
70
+ "nightly": {
71
+ "files": [
72
+ ".env.nightly"
73
+ ]
74
+ },
75
+ "staging": {
76
+ "files": [
77
+ ".env.staging"
78
+ ]
79
+ },
80
+ "production": {
81
+ "files": [
82
+ ".env.production"
83
+ ]
84
+ }
85
+ }
86
+ }
87
+ }
@@ -0,0 +1,107 @@
1
+ {
2
+ "$schema": "../../../../schema/iac.schema.json",
3
+ "version": 1,
4
+ "project": {
5
+ "key": "bun-hono-api",
6
+ "name": "bun-hono-api"
7
+ },
8
+ "environments": [
9
+ "development",
10
+ "test",
11
+ "uat",
12
+ "nightly",
13
+ "staging",
14
+ "preview",
15
+ "production"
16
+ ],
17
+ "providers": {
18
+ "aws": {
19
+ "region": "us-west-2",
20
+ "deployments": {
21
+ "dev": {
22
+ "environment": "development",
23
+ "region": "us-west-2",
24
+ "profile": "bun-hono-api-dev",
25
+ "tags": {
26
+ "Stage": "dev"
27
+ }
28
+ },
29
+ "uat": {
30
+ "environment": "uat",
31
+ "region": "us-west-2",
32
+ "profile": "bun-hono-api-uat",
33
+ "tags": {
34
+ "Stage": "uat"
35
+ }
36
+ },
37
+ "nightly": {
38
+ "environment": "nightly",
39
+ "region": "us-west-2",
40
+ "profile": "bun-hono-api-nightly",
41
+ "tags": {
42
+ "Stage": "nightly"
43
+ }
44
+ },
45
+ "prod": {
46
+ "environment": "production",
47
+ "region": "us-west-2",
48
+ "profile": "bun-hono-api-prod",
49
+ "tags": {
50
+ "Stage": "prod"
51
+ }
52
+ }
53
+ }
54
+ },
55
+ "digitalocean": {
56
+ "region": "sfo3"
57
+ }
58
+ },
59
+ "apps": [
60
+ {
61
+ "key": "api",
62
+ "name": "bun-hono-api",
63
+ "framework": "bun",
64
+ "rootDirectory": "."
65
+ }
66
+ ],
67
+ "databases": [
68
+ {
69
+ "key": "appdb",
70
+ "engine": "postgres"
71
+ }
72
+ ],
73
+ "env": {
74
+ "environments": {
75
+ "development": {
76
+ "files": [
77
+ ".env.development"
78
+ ]
79
+ },
80
+ "test": {
81
+ "files": [
82
+ ".env.test"
83
+ ]
84
+ },
85
+ "uat": {
86
+ "files": [
87
+ ".env.uat"
88
+ ]
89
+ },
90
+ "nightly": {
91
+ "files": [
92
+ ".env.nightly"
93
+ ]
94
+ },
95
+ "staging": {
96
+ "files": [
97
+ ".env.staging"
98
+ ]
99
+ },
100
+ "production": {
101
+ "files": [
102
+ ".env.production"
103
+ ]
104
+ }
105
+ }
106
+ }
107
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "bun-hono-api",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "bun run src/index.ts",
7
+ "iac:render": "vertile-iac render --repo-root . --target=all --deployment=prod"
8
+ },
9
+ "dependencies": {
10
+ "hono": "^4.0.0"
11
+ },
12
+ "devDependencies": {
13
+ "@vertile-ai/iac": "0.1.0"
14
+ }
15
+ }
@@ -0,0 +1,7 @@
1
+ import { Hono } from 'hono'
2
+
3
+ const app = new Hono()
4
+
5
+ app.get('/health', (context) => context.json({ ok: true, runtime: 'bun' }))
6
+
7
+ export default app
@@ -0,0 +1,8 @@
1
+ # Go API
2
+
3
+ Go HTTP backend example with AWS and DigitalOcean targets.
4
+
5
+ ```bash
6
+ vertile-iac render --repo-root examples/go-api --target=all --deployment=prod
7
+ vertile-iac render --repo-root examples/go-api --iac-manifest infrastructure/iac/iac.do.json --target=digitalocean --env=production
8
+ ```
@@ -0,0 +1,16 @@
1
+ package main
2
+
3
+ import (
4
+ "encoding/json"
5
+ "net/http"
6
+ )
7
+
8
+ func main() {
9
+ http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
10
+ _ = json.NewEncoder(w).Encode(map[string]any{
11
+ "ok": true,
12
+ "runtime": "go",
13
+ })
14
+ })
15
+ _ = http.ListenAndServe(":3000", nil)
16
+ }
@@ -0,0 +1,3 @@
1
+ module example.com/go-api
2
+
3
+ go 1.24
@@ -0,0 +1,90 @@
1
+ {
2
+ "$schema": "../../../../schema/iac.schema.json",
3
+ "version": 1,
4
+ "project": {
5
+ "key": "go-api",
6
+ "name": "go-api"
7
+ },
8
+ "environments": [
9
+ "development",
10
+ "test",
11
+ "uat",
12
+ "nightly",
13
+ "staging",
14
+ "preview",
15
+ "production"
16
+ ],
17
+ "providers": {
18
+ "digitalocean": {
19
+ "region": "nyc3",
20
+ "resources": [
21
+ {
22
+ "type": "digitalocean_project",
23
+ "name": "main",
24
+ "values": {
25
+ "name": "go-api"
26
+ }
27
+ }
28
+ ]
29
+ }
30
+ },
31
+ "apps": [
32
+ {
33
+ "key": "api",
34
+ "name": "go-api",
35
+ "framework": "go",
36
+ "rootDirectory": "."
37
+ }
38
+ ],
39
+ "queues": [
40
+ {
41
+ "key": "jobs"
42
+ }
43
+ ],
44
+ "clusters": [
45
+ {
46
+ "key": "workers",
47
+ "size": 2,
48
+ "providers": {
49
+ "digitalocean": {
50
+ "nodes": 2,
51
+ "sizeSlug": "s-1vcpu-1gb"
52
+ }
53
+ }
54
+ }
55
+ ],
56
+ "env": {
57
+ "environments": {
58
+ "development": {
59
+ "files": [
60
+ ".env.development"
61
+ ]
62
+ },
63
+ "test": {
64
+ "files": [
65
+ ".env.test"
66
+ ]
67
+ },
68
+ "uat": {
69
+ "files": [
70
+ ".env.uat"
71
+ ]
72
+ },
73
+ "nightly": {
74
+ "files": [
75
+ ".env.nightly"
76
+ ]
77
+ },
78
+ "staging": {
79
+ "files": [
80
+ ".env.staging"
81
+ ]
82
+ },
83
+ "production": {
84
+ "files": [
85
+ ".env.production"
86
+ ]
87
+ }
88
+ }
89
+ }
90
+ }