Building & publishing
Build a self-contained binary, package release assets, and publish to the Terraform Registry.
Why distribute as a binary?
Operators who use your provider should not need Node.js or Bun installed. A single-file executable application bundles the JS runtime into a single native binary — exactly like a Go provider — so Terraform can launch it with a normal required_providers block.
Build a binary
terrably build
# → bin/terraform-provider-mycloud (JS runtime embedded)terrably build runs these steps automatically –
Compile TypeScript
Runs tsc using your project's tsconfig.json.
Bundle with esbuild
Produces a single CJS file with all dependencies inlined.
Generate a SEA entry-point
Writes a preamble that extracts embedded .proto assets to a temp directory at startup and sets TF_PROTO_DIR, then appends the esbuild bundle.
Produce the binary
Runs node --build-sea (added in Node.js 25.5.0) to inject the entry-point into a copy of the node binary. If run with Bun, runs bun --compile (added in Bun 0.6.0) to build a single executable binary.
Sign (macOS only)
Runs codesign --sign - (ad-hoc signature required for execution on macOS).
Produce the binary
Runs bun --compile (added in Bun 0.6.0) to build a single executable binary.
Sign (macOS only)
Runs codesign --sign - (ad-hoc signature required for execution on macOS).
Options
terrably build [options]
--name <n> Provider short name (default: inferred from package.json "name")
--out <dir> Output directory (default: bin/)
--target <target> Bun only – cross-compilation target (e.g. bun-linux-x64, bun-darwin-arm64). See https://bun.sh/docs/bundler/executables#supported-targets for the full list.Smoke-test the binary
TF_PLUGIN_MAGIC_COOKIE=d602bf8f470bc67ca7faa0386276bbdd4330efaf76d1a219cb4d6991ca9872b2 \
./bin/terraform-provider-mycloud
# → prints the go-plugin handshake line and blocksOr run the full schema validation –
terrably checkPackage a release with terrably publish
terrably publish assembles all the release assets the Terraform Registry requires – zips, manifest, SHA256SUMS, and GPG signature.
terrably publish [options]
--release-version <v> Version (e.g. 1.2.3 or v1.2.3); default: package.json version
--name <n> Provider short name; default: package.json name
--binaries-dir <dir> Directory with per-platform binaries (default: bin/)
--out <dir> Output directory for release assets (default: release/)
--protocol-version <v> 5.0 or 6.0 (default: 6.0)
--gpg-key <fp> GPG key fingerprint/email (default: $GPG_FINGERPRINT)
--github-release Create GitHub Release and upload all assets (requires $GITHUB_TOKEN)
--draft Create the release as a draft
--tag <tag> Git tag name (default: v{version})
--include Additional files to be included in the release assetRequired release asset layout
Prop
Type
The binary inside each zip must be named terraform-provider-{name}_v{ver} (no OS/arch suffix).
Binary naming convention
Files in --binaries-dir must be named terraform-provider-{name}_{os}_{arch}[.exe] –
If only one binary is present with no platform suffix (the plain output of terrably build), it is treated as the current platform — useful for local smoke tests.
Local packaging example
# 1. Build the binary for the current platform
terrably build
# 2. Rename it with a platform suffix for publish
mv bin/terraform-provider-mycloud \
bin/terraform-provider-mycloud_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/')
# 3. Package, sign, and preview (no GitHub Release)
GPG_FINGERPRINT=your@email.com terrably publish --release-version 1.0.0See CI workflow for the full multi-platform automation.
Last updated on