WASM Build Target
Terraform Version
latest
Use Cases
Run terraform in browser using WebAssembly
Attempted Solutions
Compiling Terraform from source to a WASM target produces several errors due to incompatible calls and libraries. The solution will need to include excluding these calls for the WASM build target.
Proposal
No response
References
No response
Hi @badarsebard! Thanks for this feature request.
Terraform performs many actions that are likely to require different strategies in a WebAssembly context:
- Accessing files on local disk.
- Making outgoing network requests to various remote hosts.
- Downloading provider packages which contain further executables that need to be run somehow (so these would at least need to be compiled for WebAssembly too, and probably also be run in a different way)
- Executing other commands on the local system, such as Git and anything run from a local-exec provisioner.
My sense is that the exact details of this will need to vary based on the intended execution context. For example, compiling for a WASI target will require different techniques than interacting through a web browser JavaScript API.
To proceed here then we'd need to know a bit more about what the goal is, because the decisions about how to handle problems like the above are likely to constrain how a WASI port of Terraform could be used.
Can you say some more about what you intend to do with a WASM build of Terraform? Thanks!
My particular use case is executing Terraform from within a browser/js context. I have written a tool called Terraforge that allows a user to visually build and edit Terraform configurations. The application runs entirely within the user's browser and not on a backend server, so I'm unable to actually use the Terraform binary. Some notable uses for executing the binary within the app:
- execute a fmt on code the app is outputting
- utilize the
terraform providers schemacommand to read the schema of various providers - running core commands like validate and plan
- apply as an advanced use case
Thanks for that extra context, @badarsebard.
That does seem like we would need to find answers to most of the problems I posed in my previous comment, then.
Running Terraform in a web browser is not a priority for us right now and so I don't expect we'll be able to spend any time designing for this in the short term, but it does seem like an interesting idea.
My bet is that to make it work will require adding another package main somewhere in the Terraform repository that would be used instead of the root package main when building for WebAssembly, and would probably skip over all of the usual Terraform CLI machinery and instead just call directly into Terraform Core somehow.
I did try something similar at one point with GopherJS, but my goals then were much more modest: I was investigating whether it would be possible to build a client-side "playground"-like experience which manages only mock infrastructure in memory, represented as graphics onscreen. That allowed me to avoid dealing with any real providers or with real network requests and focus only on a single special fake provider that was implemented in JavaScript. However, even that didn't really work out well because Terraform has not been designed to run in a web browser context; I expect WebAssembly will present similar challenges.
At this time I don't have any ideas at all for how to support interacting with real providers and real remote state backends from a WebAssembly context, and my focus is elsewhere so I won't be able to spend any time thinking about it right now. If you have any concrete ideas I'd be interested to hear them, but I can't promise we'll be able to act on this in the foreseeable future.
Thanks!
I've just submit a PR towards go-plugin to add supports for WASM: https://github.com/hashicorp/go-plugin/pull/280.
I've also privately tried to play with it by using a lightweighted tf client, to import and read a resource from a provider, which works well. All this happens in the browser, and the change to the client and provider is just one line code change thi their go.mod to direct to using my branch of go-plugin.