Install
dotnet add package TerraformDotnet --version 1.1.1
| Product | Versions |
|---|---|
| .NET |
README
TerraformDotnet
A .NET toolkit for working with Terraform — parse HCL, load modules, inspect variables, and generate Terraform code.
Packages
| Package | Description |
|---|---|
| TerraformDotnet.Hcl | High-performance HCLv2 parser and writer, AOT-compatible |
| TerraformDotnet | Terraform module loader and code generator built on top of TerraformDotnet.Hcl |
Quick Start — TerraformDotnet
Load a Terraform module, inspect its variables, and generate the calling code.
Install
dotnet add package TerraformDotnet
Load and inspect a module
using TerraformDotnet.Module;
var module = TerraformModule.LoadFromDirectory("/path/to/module");
Console.WriteLine($"Required variables: {module.RequiredVariables.Count}");
foreach (var v in module.RequiredVariables)
{
Console.WriteLine($" {v.Name}: {v.Type?.ToHcl() ?? "any"} — {v.Description}");
}
Console.WriteLine($"Optional variables: {module.OptionalVariables.Count}");
Console.WriteLine($"Outputs: {module.Outputs.Count}");
Console.WriteLine($"Resources: {module.Resources.Count}");
Generate a module call
using TerraformDotnet.Emit;
var call = new ModuleCallBuilder("my-app", module)
.Source("git::https://example.com/modules/app?ref=v1.0")
.FillRequired(name => $"var.{name}")
.SetLiteral("tier", "premium")
.IncludeOptionalComments(true)
.Build();
var emitter = new ModuleCallEmitter(call);
string hcl = emitter.EmitModuleBlock();
// module "my-app" {
// source = "git::https://example.com/modules/app?ref=v1.0"
//
// project = var.project
// region = var.region
// labels = var.labels
// tier = "premium"
//
// # (Optional) Maximum instance count.
// # max_count = var.max_count
// }
Generate multiple files at once
emitter.WriteTo("output/", new FileEmitterOptions
{
ModuleFileName = "resources-app.tf",
VariablesFileName = "variables-app.tf",
InputFiles = new Dictionary<string, IDictionary<string, InputValue>>
{
["input-dev.tfvars"] = new Dictionary<string, InputValue>
{
["project"] = new InputValue("\"dev-app\"", "Development"),
["region"] = "\"eu-west-1\"",
},
["input-prod.tfvars"] = new Dictionary<string, InputValue>
{
["project"] = new InputValue("\"prod-app\"", "Production"),
["region"] = "\"eu-west-1\"",
},
},
});
Quick Start — TerraformDotnet.Hcl
Parse and write HCL at any level of abstraction.
Install
dotnet add package TerraformDotnet.Hcl
Parse HCL into an AST
using TerraformDotnet.Hcl.Nodes;
var hcl = """
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "HelloWorld"
}
}
"""u8;
HclFile file = HclFile.Load(hcl);
HclBlock block = file.Body.Blocks[0];
Console.WriteLine(block.Type); // "resource"
Console.WriteLine(block.Labels[0]); // "aws_instance"
Console.WriteLine(block.Labels[1]); // "web"
Write HCL
using TerraformDotnet.Hcl.Writer;
var buffer = new ArrayBufferWriter<byte>();
using var writer = new Utf8HclWriter(buffer);
writer.WriteBlockStart("resource", "aws_s3_bucket", "data");
writer.WriteAttribute("bucket", "my-bucket");
writer.WriteBooleanAttribute("force_destroy", true);
writer.WriteBlockEnd();
writer.Flush();
string output = Encoding.UTF8.GetString(buffer.WrittenSpan);
// resource "aws_s3_bucket" "data" {
// bucket = "my-bucket"
// force_destroy = true
// }
Round-trip (parse → modify → emit)
var hcl = "name = \"old\""u8;
HclFile file = HclFile.Load(hcl);
file.Body.Attributes[0].Value = new HclLiteralExpression("new");
var buffer = new ArrayBufferWriter<byte>();
using var writer = new Utf8HclWriter(buffer);
new HclFileEmitter(writer).Emit(file);
writer.Flush();
// Output: name = "new"
Architecture
| Layer | Namespace | Description |
|---|---|---|
| Reader | TerraformDotnet.Hcl.Reader |
ref struct tokenizer — zero-copy, pull-based |
| Nodes | TerraformDotnet.Hcl.Nodes |
AST model with visitor pattern and DeepClone() |
| Writer | TerraformDotnet.Hcl.Writer |
Forward-only writer producing terraform fmt output |
| Evaluation | TerraformDotnet.Hcl.Evaluation |
Variable resolution engine |
| Module | TerraformDotnet.Module |
Terraform module loader and model |
| Emit | TerraformDotnet.Emit |
Module call builder and code emitter |
See docs/hcl.md and docs/terraformdotnet.md for detailed documentation.
See docs/architecture.md for internal design and architecture.
Building
dotnet build all.csproj
Testing
dotnet test all.csproj
Performance
TerraformDotnet.Hcl uses stack-first, zero-copy design:
Utf8HclReaderis aref structoperating onReadOnlySpan<byte>- Token values reference slices of the original input — no allocations for most tokens
- No LINQ, no reflection in any hot path
- AOT-compatible (
IsAotCompatible = true)
License
Changes from Previous Version
No structural changes between v1.1.0 and v1.1.1.
Adoption Assessment
Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.
Compatibility metadata lists 1 target framework; confirm the exact target used by your application.
Related Guides & Workflows
Learn how to evaluate, integrate, or audit this package in your .NET project.