@vertile-ai/iac
v0.1.0
Published
App-first portable infrastructure intent for Vercel, AWS, and DigitalOcean.
Downloads
282
Readme
@vertile-ai/iac
Opinionated infrastructure-as-code tooling.
Install once, define infrastructure once, then run vertile-iac plan or
guarded vertile-iac apply to manage Vercel, AWS, and DigitalOcean changes
from the same IaC source of truth.
Product repos keep their own manifests and env source files, while this package renders provider-specific Terraform workspaces and keeps the existing Vercel reconciliation flow available as compatibility commands.
Install
pnpm add -D @vertile-ai/iacTerraform is required for vertile-iac plan. The render command does not call
Terraform and can be used offline.
Commands
vertile-iac render --target=all --env=production
vertile-iac plan --target=vercel --env=preview
vertile-iac apply --target=aws --deployment=prod --yes
vertile-iac sync-env --repo-root ../noop --variants=local,staging,test
vertile-iac env --repo-root ../noop --scope=all --targets=preview,production
vertile-iac projects --repo-root ../noop
vertile-iac domains --repo-root ../noopThe render, plan, and apply commands read infrastructure/iac/iac.json
and write generated Terraform workspaces to .vertile/terraform/<target>/.
When --deployment=<name> maps to a provider deployment, the workspace is
.vertile/terraform/<target>/<deployment>/.
Apply is guarded. Non-interactive apply requires --yes, which passes
Terraform -auto-approve.
The env, projects, and domains commands reconcile Vercel through the
Vercel API. They still read the older compatibility manifest files when those
files exist, and otherwise derive the same desired state from
infrastructure/iac/iac.json.
Apply mode requires VERCEL_TOKEN, VERCEL_API_KEY, or a token file:
VERCEL_TOKEN=... vertile-iac env --repo-root ../noop --applyManifest Layout
The new Terraform flow expects the target project to have:
infrastructure/iac/iac.json
.vertile-iac/env/shared/.env.development
.vertile-iac/env/shared/.env.staging
.vertile-iac/env/shared/.env.production
.vertile-iac/env/<app-key>/.env.development
.vertile-iac/env/<app-key>/.env.staging
.vertile-iac/env/<app-key>/.env.productionMinimal iac.json example:
{
"$schema": "./node_modules/@vertile-ai/iac/schema/iac.schema.json",
"version": 1,
"project": { "name": "example" },
"environments": ["development", "uat", "production"],
"providers": {
"vercel": { "team": "example-team" },
"aws": {
"region": "us-east-1",
"deployments": {
"uat": {
"environment": "uat",
"region": "us-east-1",
"profile": "example-uat",
"tags": { "Stage": "uat" }
},
"prod": {
"environment": "production",
"region": "us-east-1",
"profile": "example-prod",
"tags": { "Stage": "prod" }
}
}
},
"digitalocean": {}
},
"apps": [
{
"key": "web",
"name": "example-web",
"framework": "nextjs",
"rootDirectory": "apps/web",
"domains": ["web.example.com"]
}
],
"env": {
"environments": {
"development": { "files": [".env.development"] },
"uat": { "files": [".env.uat"] },
"production": { "files": [".env.production"] }
},
"sync": {
"apps": ["web"]
}
},
"domains": []
}Portable concepts currently include:
appsdomainsobjectStoragedatabasesqueuessandboxesclusters
Provider-specific Terraform resources can be added under
providers.<target>.resources as { "type", "name", "values" } objects while
the manifest schema stays narrow.
Provider deployments map user-defined stage names such as uat, nightly, or
prod to logical environments and provider-specific inputs. AWS uses deployment
values for provider region/profile, generated workspace path, resource names,
and default tags. The logical environment still controls env file selection.
By default, Vercel env reconciliation reads .env.* files from
.vertile-iac/env/shared and .vertile-iac/env/<project-key>.
When the old compatibility files exist, they are used directly:
infrastructure/iac/env-manifest.json
infrastructure/iac/project-settings.json
infrastructure/iac/project-domains.jsonWhen they do not exist, the Vercel commands derive equivalent manifests from
iac.json:
providers.vercel.teamSlugorproviders.vercel.teambecomes the Vercel team.env.sourceDirselects the env source folder and defaults to.vertile-iac/env.env.environments.<name>.filesmaps logical environments to ordered env files.apps[].key,apps[].idorapps[].projectId, andapps[].namebecome managed Vercel projects.apps[].rootDirectory,apps[].nodeVersion, andapps[].enableAffectedProjectsDeploymentsbecome project settings.apps[].domainsand top-leveldomains[]become project domains.
Vercel targets map to logical environments as follows by default:
development->developmentpreview->stagingproduction->production
Those logical environments then resolve through env.environments. For example,
staging defaults to .env.staging, but can be configured as
"staging": { "files": [".env.preview", ".env.staging"] }.
The default manifest location can be overridden:
vertile-iac env \
--repo-root ../some-project \
--manifest ./deploy/env-manifest.jsonEnv File Sync
vertile-iac sync-env generates package-local .env.* files from the env
source tree declared by iac.json. This is separate from vertile-iac env,
which reconciles Vercel remote environment variables.
The boundary is:
env.sourceDiris the source tree, defaulting to.vertile-iac/env.env.environments.<name>.filesdeclares ordered source files for any logical environment, including custom names such asuat,nightly, orqa.env.sync.sharedKeyis the shared source folder, defaulting toshared.env.sync.appslimits whichapps[]are materialized locally. Without it, all apps are synced.- Each app reads from
<env.sourceDir>/<app.key>by default. - Each app writes into
apps[].rootDirectoryby default. apps[].env.sourceKeyandapps[].env.outputDiroverride those defaults.- When the same key exists in shared and app-specific files, the app-specific
value wins in generated package
.env.*files. apps[].env.sharedPrefixprojects prefixed shared keys into one app, strips the prefix in that app's generated file, and keeps those prefixed keys out of other generated app env files.
Examples:
{
"env": {
"sync": {
"apps": ["landing", "web-client", "web-server"],
"sharedKey": "shared"
}
},
"apps": [
{
"key": "web-client",
"rootDirectory": "packages/web-client",
"env": { "sharedPrefix": "WEB_CLIENT_" }
}
]
}Built-in local sync variants are local, staging, preview, production,
and test. Custom variants declared in env.environments can also be selected
with --variants, such as --variants=uat,nightly.
Shared Options
--repo-root <path>: product repo root containinginfrastructure/.--iac-dir <path>: manifest directory, defaultinfrastructure/iac.--manifest <path>: env manifest path.--project-settings <path>: project settings manifest path.--project-domains <path>: project domains manifest path.--token-file <path>: token file, default<repo-root>/.vercel.token.--auto-create-keys <a,b>: project keys allowed for Vercel auto-create.--auto-create-prefixes <a,b>: project key prefixes allowed for Vercel auto-create.--iac-manifest <path>: source-of-truth IaC manifest, default<iac-dir>/iac.json.--out <path>: generated Terraform root, default.vertile/terraform.--target <name|all>:vercel,aws,digitalocean, orall.--env <name>: environment to render, plan, or apply, defaultproduction.--deployment <name>: provider deployment/stage name, such asuatorprod.--terraform-bin <path>: Terraform executable forplan, defaultterraform.--yes: allow non-interactiveapplywith Terraform auto-approve.
Docs
Public-facing docs live in docs/. The static docs website entrypoint is:
docs/index.htmlExamples
The examples/ directory uses runtime-oriented fixture names so each project
shape is clear at a glance:
examples/node-apiexamples/bun-hono-apiexamples/react-spaexamples/next-monorepoexamples/sveltekit-webexamples/python-fastapi-apiexamples/go-api
Every example keeps a portable infrastructure/iac/iac.json. Examples with
provider-specific fields also include standalone provider variants such as
iac.aws.json, iac.vercel.json, or iac.do.json that can be passed with
--iac-manifest.
Schema
The manifest schema is published as JSON Schema Draft 2020-12:
schema/iac.schema.jsonProduct manifests can reference the package copy:
{
"$schema": "./node_modules/@vertile-ai/iac/schema/iac.schema.json"
}Publishing
Publish with public access:
pnpm publish --access public