@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
@@ -0,0 +1,106 @@
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
+ "aws": {
19
+ "region": "us-east-1",
20
+ "deployments": {
21
+ "dev": {
22
+ "environment": "development",
23
+ "region": "us-east-1",
24
+ "profile": "go-api-dev",
25
+ "tags": {
26
+ "Stage": "dev"
27
+ }
28
+ },
29
+ "uat": {
30
+ "environment": "uat",
31
+ "region": "us-east-1",
32
+ "profile": "go-api-uat",
33
+ "tags": {
34
+ "Stage": "uat"
35
+ }
36
+ },
37
+ "nightly": {
38
+ "environment": "nightly",
39
+ "region": "us-east-1",
40
+ "profile": "go-api-nightly",
41
+ "tags": {
42
+ "Stage": "nightly"
43
+ }
44
+ },
45
+ "prod": {
46
+ "environment": "production",
47
+ "region": "us-east-1",
48
+ "profile": "go-api-prod",
49
+ "tags": {
50
+ "Stage": "prod"
51
+ }
52
+ }
53
+ }
54
+ },
55
+ "digitalocean": {
56
+ "region": "nyc3"
57
+ }
58
+ },
59
+ "apps": [
60
+ {
61
+ "key": "api",
62
+ "name": "go-api",
63
+ "framework": "go",
64
+ "rootDirectory": "."
65
+ }
66
+ ],
67
+ "queues": [
68
+ {
69
+ "key": "jobs"
70
+ }
71
+ ],
72
+ "env": {
73
+ "environments": {
74
+ "development": {
75
+ "files": [
76
+ ".env.development"
77
+ ]
78
+ },
79
+ "test": {
80
+ "files": [
81
+ ".env.test"
82
+ ]
83
+ },
84
+ "uat": {
85
+ "files": [
86
+ ".env.uat"
87
+ ]
88
+ },
89
+ "nightly": {
90
+ "files": [
91
+ ".env.nightly"
92
+ ]
93
+ },
94
+ "staging": {
95
+ "files": [
96
+ ".env.staging"
97
+ ]
98
+ },
99
+ "production": {
100
+ "files": [
101
+ ".env.production"
102
+ ]
103
+ }
104
+ }
105
+ }
106
+ }
@@ -0,0 +1,22 @@
1
+ # Next.js Monorepo
2
+
3
+ This fixture shows a two-app Next.js monorepo from the shape a product repo
4
+ would keep. It intentionally uses the full current manifest surface: multiple
5
+ Vercel apps, domains, preview/production env provisioning, local env sync,
6
+ portable storage/database/queue/compute concepts, provider overrides, and
7
+ provider-specific escape hatch resources.
8
+
9
+ It intentionally contains no real secrets. The env files use placeholder values
10
+ so package consumers can inspect and run dry-runs without extra setup.
11
+
12
+ ## Commands
13
+
14
+ ```bash
15
+ vertile-iac sync-env --repo-root examples/next-monorepo --variants=staging,production
16
+ vertile-iac env --repo-root examples/next-monorepo --targets=preview,production
17
+ vertile-iac projects --repo-root examples/next-monorepo --projects=web
18
+ vertile-iac domains --repo-root examples/next-monorepo --projects=web
19
+ vertile-iac render --repo-root examples/next-monorepo --target=all --deployment=prod
20
+ ```
21
+
22
+ Apply commands require `VERCEL_TOKEN` and a real Vercel team/project.
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "next-monorepo-admin",
3
+ "private": true,
4
+ "scripts": {
5
+ "build": "echo \"next-monorepo admin fixture build\""
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "next-monorepo-web",
3
+ "private": true,
4
+ "scripts": {
5
+ "build": "echo \"next-monorepo web fixture build\""
6
+ }
7
+ }
@@ -0,0 +1,172 @@
1
+ {
2
+ "$schema": "../../../../schema/iac.schema.json",
3
+ "version": 1,
4
+ "project": {
5
+ "key": "next-monorepo",
6
+ "name": "next-monorepo"
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-east-1",
20
+ "defaultTags": {
21
+ "Example": "next-monorepo",
22
+ "Runtime": "nextjs"
23
+ },
24
+ "resources": [
25
+ {
26
+ "type": "aws_sns_topic",
27
+ "name": "events",
28
+ "values": {
29
+ "name": "next-monorepo-events"
30
+ }
31
+ }
32
+ ],
33
+ "deployments": {
34
+ "dev": {
35
+ "environment": "development",
36
+ "region": "us-east-1",
37
+ "profile": "next-monorepo-dev",
38
+ "tags": {
39
+ "Stage": "dev"
40
+ }
41
+ },
42
+ "uat": {
43
+ "environment": "uat",
44
+ "region": "us-east-1",
45
+ "profile": "next-monorepo-uat",
46
+ "tags": {
47
+ "Stage": "uat"
48
+ }
49
+ },
50
+ "nightly": {
51
+ "environment": "nightly",
52
+ "region": "us-east-1",
53
+ "profile": "next-monorepo-nightly",
54
+ "tags": {
55
+ "Stage": "nightly"
56
+ }
57
+ },
58
+ "prod": {
59
+ "environment": "production",
60
+ "region": "us-east-1",
61
+ "profile": "next-monorepo-prod",
62
+ "tags": {
63
+ "Stage": "prod"
64
+ }
65
+ }
66
+ }
67
+ }
68
+ },
69
+ "apps": [
70
+ {
71
+ "key": "web",
72
+ "name": "next-monorepo-web",
73
+ "framework": "nextjs",
74
+ "rootDirectory": "apps/web"
75
+ },
76
+ {
77
+ "key": "admin",
78
+ "name": "next-monorepo-admin",
79
+ "framework": "nextjs",
80
+ "rootDirectory": "apps/admin"
81
+ }
82
+ ],
83
+ "objectStorage": [
84
+ {
85
+ "key": "uploads",
86
+ "visibility": "private",
87
+ "providers": {
88
+ "aws": {
89
+ "bucket": "next-monorepo-production-uploads",
90
+ "forceDestroy": true
91
+ }
92
+ }
93
+ }
94
+ ],
95
+ "databases": [
96
+ {
97
+ "key": "appdb",
98
+ "engine": "postgres",
99
+ "providers": {
100
+ "aws": {
101
+ "engineVersion": "16",
102
+ "instanceClass": "db.t4g.micro",
103
+ "allocatedStorage": 20,
104
+ "databaseName": "next_monorepo",
105
+ "username": "next_monorepo",
106
+ "skipFinalSnapshot": true
107
+ }
108
+ }
109
+ }
110
+ ],
111
+ "queues": [
112
+ {
113
+ "key": "jobs",
114
+ "kind": "fifo"
115
+ }
116
+ ],
117
+ "sandboxes": [
118
+ {
119
+ "key": "runner",
120
+ "providers": {
121
+ "aws": {
122
+ "instanceType": "t3.micro"
123
+ }
124
+ }
125
+ }
126
+ ],
127
+ "clusters": [
128
+ {
129
+ "key": "workers",
130
+ "size": 2,
131
+ "providers": {
132
+ "aws": {
133
+ "instanceType": "t3.small"
134
+ }
135
+ }
136
+ }
137
+ ],
138
+ "env": {
139
+ "environments": {
140
+ "development": {
141
+ "files": [
142
+ ".env.development"
143
+ ]
144
+ },
145
+ "test": {
146
+ "files": [
147
+ ".env.test"
148
+ ]
149
+ },
150
+ "uat": {
151
+ "files": [
152
+ ".env.uat"
153
+ ]
154
+ },
155
+ "nightly": {
156
+ "files": [
157
+ ".env.nightly"
158
+ ]
159
+ },
160
+ "staging": {
161
+ "files": [
162
+ ".env.staging"
163
+ ]
164
+ },
165
+ "production": {
166
+ "files": [
167
+ ".env.production"
168
+ ]
169
+ }
170
+ }
171
+ }
172
+ }
@@ -0,0 +1,129 @@
1
+ {
2
+ "$schema": "../../../../schema/iac.schema.json",
3
+ "version": 1,
4
+ "project": {
5
+ "key": "next-monorepo",
6
+ "name": "next-monorepo"
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
+ "version": ">= 2.0.0",
21
+ "resources": [
22
+ {
23
+ "type": "digitalocean_project",
24
+ "name": "main",
25
+ "values": {
26
+ "name": "next-monorepo"
27
+ }
28
+ }
29
+ ]
30
+ }
31
+ },
32
+ "apps": [
33
+ {
34
+ "key": "web",
35
+ "name": "next-monorepo-web",
36
+ "framework": "nextjs",
37
+ "rootDirectory": "apps/web"
38
+ },
39
+ {
40
+ "key": "admin",
41
+ "name": "next-monorepo-admin",
42
+ "framework": "nextjs",
43
+ "rootDirectory": "apps/admin"
44
+ }
45
+ ],
46
+ "objectStorage": [
47
+ {
48
+ "key": "uploads",
49
+ "visibility": "private",
50
+ "providers": {
51
+ "digitalocean": {
52
+ "name": "next-monorepo-uploads",
53
+ "acl": "private",
54
+ "region": "nyc3"
55
+ }
56
+ }
57
+ }
58
+ ],
59
+ "databases": [
60
+ {
61
+ "key": "appdb",
62
+ "engine": "postgres",
63
+ "providers": {
64
+ "digitalocean": {
65
+ "engine": "pg",
66
+ "version": "16",
67
+ "size": "db-s-1vcpu-1gb",
68
+ "nodeCount": 1
69
+ }
70
+ }
71
+ }
72
+ ],
73
+ "sandboxes": [
74
+ {
75
+ "key": "runner",
76
+ "providers": {
77
+ "digitalocean": {
78
+ "sizeSlug": "s-1vcpu-1gb"
79
+ }
80
+ }
81
+ }
82
+ ],
83
+ "clusters": [
84
+ {
85
+ "key": "workers",
86
+ "size": 2,
87
+ "providers": {
88
+ "digitalocean": {
89
+ "nodes": 2,
90
+ "sizeSlug": "s-1vcpu-2gb"
91
+ }
92
+ }
93
+ }
94
+ ],
95
+ "env": {
96
+ "environments": {
97
+ "development": {
98
+ "files": [
99
+ ".env.development"
100
+ ]
101
+ },
102
+ "test": {
103
+ "files": [
104
+ ".env.test"
105
+ ]
106
+ },
107
+ "uat": {
108
+ "files": [
109
+ ".env.uat"
110
+ ]
111
+ },
112
+ "nightly": {
113
+ "files": [
114
+ ".env.nightly"
115
+ ]
116
+ },
117
+ "staging": {
118
+ "files": [
119
+ ".env.staging"
120
+ ]
121
+ },
122
+ "production": {
123
+ "files": [
124
+ ".env.production"
125
+ ]
126
+ }
127
+ }
128
+ }
129
+ }
@@ -2,10 +2,18 @@
2
2
  "$schema": "../../../../schema/iac.schema.json",
3
3
  "version": 1,
4
4
  "project": {
5
- "key": "dynomic",
6
- "name": "dynomic"
5
+ "key": "next-monorepo",
6
+ "name": "next-monorepo"
7
7
  },
8
- "environments": ["development", "preview", "production"],
8
+ "environments": [
9
+ "development",
10
+ "test",
11
+ "uat",
12
+ "nightly",
13
+ "staging",
14
+ "preview",
15
+ "production"
16
+ ],
9
17
  "providers": {
10
18
  "vercel": {
11
19
  "teamSlug": "vertile-ai",
@@ -18,10 +26,12 @@
18
26
  "type": "vercel_project_environment_variable",
19
27
  "name": "example_escape_hatch",
20
28
  "values": {
21
- "project_id": "prj_dynomic_placeholder",
29
+ "project_id": "prj_next_monorepo_placeholder",
22
30
  "key": "ESCAPE_HATCH_EXAMPLE",
23
31
  "value": "configured-through-provider-resource",
24
- "target": ["preview"]
32
+ "target": [
33
+ "preview"
34
+ ]
25
35
  }
26
36
  }
27
37
  ]
@@ -30,17 +40,51 @@
30
40
  "region": "us-east-1",
31
41
  "defaultTags": {
32
42
  "Owner": "vertile-ai",
33
- "Fixture": "dynomic"
43
+ "Fixture": "next-monorepo"
34
44
  },
35
45
  "resources": [
36
46
  {
37
47
  "type": "aws_sns_topic",
38
48
  "name": "events",
39
49
  "values": {
40
- "name": "dynomic-events"
50
+ "name": "next-monorepo-events"
41
51
  }
42
52
  }
43
- ]
53
+ ],
54
+ "deployments": {
55
+ "dev": {
56
+ "environment": "development",
57
+ "region": "us-east-1",
58
+ "profile": "next-monorepo-dev",
59
+ "tags": {
60
+ "Stage": "dev"
61
+ }
62
+ },
63
+ "uat": {
64
+ "environment": "uat",
65
+ "region": "us-east-1",
66
+ "profile": "next-monorepo-uat",
67
+ "tags": {
68
+ "Stage": "uat"
69
+ }
70
+ },
71
+ "nightly": {
72
+ "environment": "nightly",
73
+ "region": "us-east-1",
74
+ "profile": "next-monorepo-nightly",
75
+ "tags": {
76
+ "Stage": "nightly"
77
+ }
78
+ },
79
+ "prod": {
80
+ "environment": "production",
81
+ "region": "us-east-1",
82
+ "profile": "next-monorepo-prod",
83
+ "tags": {
84
+ "Stage": "prod"
85
+ }
86
+ }
87
+ }
44
88
  },
45
89
  "digitalocean": {
46
90
  "region": "nyc3",
@@ -50,7 +94,7 @@
50
94
  "type": "digitalocean_project",
51
95
  "name": "main",
52
96
  "values": {
53
- "name": "dynomic"
97
+ "name": "next-monorepo"
54
98
  }
55
99
  }
56
100
  ]
@@ -59,22 +103,57 @@
59
103
  "env": {
60
104
  "sourceDir": "infrastructure",
61
105
  "sync": {
62
- "apps": ["web", "admin"],
106
+ "apps": [
107
+ "web",
108
+ "admin"
109
+ ],
63
110
  "sharedKey": "shared"
111
+ },
112
+ "environments": {
113
+ "development": {
114
+ "files": [
115
+ ".env.development"
116
+ ]
117
+ },
118
+ "test": {
119
+ "files": [
120
+ ".env.test"
121
+ ]
122
+ },
123
+ "uat": {
124
+ "files": [
125
+ ".env.uat"
126
+ ]
127
+ },
128
+ "nightly": {
129
+ "files": [
130
+ ".env.nightly"
131
+ ]
132
+ },
133
+ "staging": {
134
+ "files": [
135
+ ".env.staging"
136
+ ]
137
+ },
138
+ "production": {
139
+ "files": [
140
+ ".env.production"
141
+ ]
142
+ }
64
143
  }
65
144
  },
66
145
  "apps": [
67
146
  {
68
147
  "key": "web",
69
- "id": "prj_dynomic_web_placeholder",
70
- "name": "dynomic-web",
148
+ "id": "prj_next_monorepo_web_placeholder",
149
+ "name": "next-monorepo-web",
71
150
  "framework": "nextjs",
72
151
  "rootDirectory": "apps/web",
73
152
  "nodeVersion": "20.x",
74
153
  "domains": [
75
- "dynomic.example.com",
154
+ "next-monorepo.example.com",
76
155
  {
77
- "name": "preview.dynomic.example.com",
156
+ "name": "preview.next-monorepo.example.com",
78
157
  "gitBranch": "preview"
79
158
  }
80
159
  ],
@@ -86,15 +165,15 @@
86
165
  },
87
166
  {
88
167
  "key": "admin",
89
- "id": "prj_dynomic_admin_placeholder",
90
- "name": "dynomic-admin",
168
+ "id": "prj_next_monorepo_admin_placeholder",
169
+ "name": "next-monorepo-admin",
91
170
  "framework": "nextjs",
92
171
  "rootDirectory": "apps/admin",
93
172
  "nodeVersion": "20.x",
94
173
  "domains": [
95
- "admin.dynomic.example.com",
174
+ "admin.next-monorepo.example.com",
96
175
  {
97
- "name": "admin-preview.dynomic.example.com",
176
+ "name": "admin-preview.next-monorepo.example.com",
98
177
  "gitBranch": "preview"
99
178
  }
100
179
  ],
@@ -105,7 +184,7 @@
105
184
  ],
106
185
  "domains": [
107
186
  {
108
- "name": "www.dynomic.example.com",
187
+ "name": "www.next-monorepo.example.com",
109
188
  "app": "web"
110
189
  }
111
190
  ],
@@ -115,11 +194,11 @@
115
194
  "visibility": "private",
116
195
  "providers": {
117
196
  "aws": {
118
- "bucket": "dynomic-production-uploads",
197
+ "bucket": "next-monorepo-production-uploads",
119
198
  "forceDestroy": true
120
199
  },
121
200
  "digitalocean": {
122
- "name": "dynomic-uploads",
201
+ "name": "next-monorepo-uploads",
123
202
  "acl": "private",
124
203
  "region": "nyc3"
125
204
  }
@@ -135,8 +214,8 @@
135
214
  "engineVersion": "16",
136
215
  "instanceClass": "db.t4g.micro",
137
216
  "allocatedStorage": 20,
138
- "databaseName": "dynomic",
139
- "username": "dynomic",
217
+ "databaseName": "next_monorepo",
218
+ "username": "next_monorepo",
140
219
  "skipFinalSnapshot": true
141
220
  },
142
221
  "digitalocean": {