Quick Start¶
Prepare a module¶
The examples on this page run against a real Terraform module directory. If you
already have one, point at it directly. Otherwise, this snippet creates a minimal
module that runs anywhere — it uses Terraform's built-in terraform_data
resource, so it needs no cloud credentials and downloads no providers:
import os
import tempfile
module_dir = tempfile.mkdtemp()
with open(os.path.join(module_dir, "main.tf"), "w") as f:
f.write(
'''
variable "environment" {
type = string
default = "dev"
}
resource "terraform_data" "example" {
input = var.environment
}
output "environment" {
value = terraform_data.example.output
}
'''
)
Every example below uses module_dir as the working directory.
Run Terraform commands¶
Create a TerraformCommand for the module directory, then initialize and
validate it:
from libterraform import TerraformCommand
cli = TerraformCommand(module_dir)
cli.init(check=True)
validation = cli.validate(check=True)
print(validation.value["valid"]) # True
check=True raises TerraformCommandError when Terraform reports failure, so
errors surface immediately instead of hiding in a return code.
Generate a plan. Methods that support JSON output return parsed Python values, so
plan.value is a list of Terraform's log events:
plan = cli.plan(check=True)
for event in plan.value:
print(event.get("@level"), event.get("@message"))
Apply the plan. auto_approve skips the interactive prompt and input=False
disables interactive input, which is what most automation wants:
Pass json=False to keep Terraform's plain text output instead of parsed JSON:
Pass Terraform options¶
Python keyword arguments become Terraform CLI flags. Underscores become hyphens,
so detailed_exitcode maps to -detailed-exitcode:
The conversion rules cover the common flag shapes:
True/Falsebecome Terraform's lowercase booleans, e.g.lock=Falseis-lock=false.- A dict expands to repeated
key=valueflags, e.g.vars={"a": "1", "b": "2"}is-var=a=1 -var=b=2. - A list expands to a repeated flag, e.g.
var_files=["a.tfvars", "b.tfvars"].
Parse Terraform configuration¶
TerraformConfig returns Terraform's own parsed view of a configuration
directory, without running a command:
from libterraform import TerraformConfig
module, diagnostics = TerraformConfig.load_config_dir(module_dir)
print(list(module["ManagedResources"])) # ['terraform_data.example']
print(diagnostics)
Use asyncio¶
AsyncTerraformCommand lets an asyncio application await Terraform operations
without blocking the event loop:
from libterraform import AsyncTerraformCommand
cli = AsyncTerraformCommand(module_dir)
validation = await cli.validate(check=True)
By default the Terraform call runs in a worker process, so Terraform's
process-wide state does not leak into the event-loop process. Use
backend="thread" only when you explicitly want the current-process backend.
Cancelling the coroutine interrupts the worker process for the default backend.
To reuse worker processes or run Terraform commands at the same time — across
modules, with sync or async APIs — see Parallel Execution,
which covers TerraformPool.
See the API Reference for the generated interface documentation.