Try Live
Add Docs
Rankings
Pricing
Docs
Install
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
Terraform
https://github.com/hashicorp/terraform
Admin
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently
...
Tokens:
42,587
Snippets:
92
Trust Score:
9.8
Update:
1 week ago
Context
Skills
Chat
Benchmark
67.5
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Terraform Terraform is an infrastructure as code tool that enables you to safely and predictably create, change, and improve infrastructure. It codifies cloud APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned. Terraform can manage existing and popular service providers (AWS, Azure, GCP, Kubernetes, etc.) as well as custom in-house solutions through its extensible provider plugin architecture. The core features of Terraform include Infrastructure as Code for describing infrastructure using a high-level configuration syntax, Execution Plans that show what Terraform will do before making changes, a Resource Graph that parallelizes resource creation based on dependencies, and Change Automation that applies complex changesets with minimal human interaction. Terraform uses a state file to map real-world resources to your configuration, track metadata, and improve performance for large infrastructures. ## terraform init - Initialize Working Directory The `terraform init` command initializes a working directory containing Terraform configuration files. This is the first command that should be run after writing a new Terraform configuration or cloning an existing one. It downloads provider plugins, initializes the backend for state storage, and downloads any modules referenced in the configuration. ```bash # Initialize a new Terraform working directory terraform init # Initialize with backend configuration terraform init -backend-config="bucket=my-terraform-state" \ -backend-config="key=prod/terraform.tfstate" \ -backend-config="region=us-west-2" # Upgrade providers to latest versions within constraints terraform init -upgrade # Initialize without downloading providers (useful for CI/CD with cached providers) terraform init -plugin-dir=/path/to/plugins # Example output: # Initializing the backend... # Initializing provider plugins... # - Finding hashicorp/aws versions matching "~> 5.0"... # - Installing hashicorp/aws v5.31.0... # - Installed hashicorp/aws v5.31.0 (signed by HashiCorp) # Terraform has been successfully initialized! ``` ## terraform plan - Create Execution Plan The `terraform plan` command creates an execution plan showing what actions Terraform will take to change infrastructure to match the configuration. It reads the current state of any existing remote objects, compares the current configuration to the prior state, and proposes a set of change actions that should make remote objects match the configuration. ```bash # Generate and show an execution plan terraform plan # Save the plan to a file for later execution terraform plan -out=tfplan # Plan with variable values terraform plan -var="instance_type=t3.large" -var="environment=staging" # Plan with variables file terraform plan -var-file="production.tfvars" # Plan to destroy infrastructure terraform plan -destroy # Plan with specific targets terraform plan -target=aws_instance.web -target=aws_security_group.allow_http # Generate plan in JSON format for programmatic consumption terraform plan -json -out=tfplan # Example output: # Terraform will perform the following actions: # # # aws_instance.web will be created # + resource "aws_instance" "web" { # + ami = "ami-0c55b159cbfafe1f0" # + instance_type = "t3.micro" # + tags = { # + "Name" = "WebServer" # } # } # # Plan: 1 to add, 0 to change, 0 to destroy. ``` ## terraform apply - Apply Changes The `terraform apply` command executes the actions proposed in a Terraform plan to create, update, or destroy infrastructure. When run without a saved plan file, it creates a new plan and prompts for approval before applying. With a saved plan file, it applies exactly those changes without prompting. ```bash # Apply changes with interactive approval terraform apply # Apply a saved plan file (no prompt) terraform apply tfplan # Auto-approve without interactive prompt (use carefully) terraform apply -auto-approve # Apply with variables terraform apply -var="instance_count=3" -var="region=us-east-1" # Apply with parallelism control (default: 10) terraform apply -parallelism=5 # Apply targeting specific resources terraform apply -target=module.networking -target=aws_instance.bastion # Apply with compact warnings terraform apply -compact-warnings # Example output: # aws_instance.web: Creating... # aws_instance.web: Still creating... [10s elapsed] # aws_instance.web: Creation complete after 35s [id=i-0abc123def456789] # # Apply complete! Resources: 1 added, 0 changed, 0 destroyed. # # Outputs: # instance_ip = "54.123.45.67" ``` ## terraform destroy - Destroy Infrastructure The `terraform destroy` command destroys all remote objects managed by a particular Terraform configuration. This is the inverse of `terraform apply` and is useful for cleaning up temporary environments or decommissioning infrastructure. ```bash # Destroy all managed infrastructure terraform destroy # Auto-approve destruction (use with caution) terraform destroy -auto-approve # Destroy specific resources terraform destroy -target=aws_instance.temporary # Destroy with variables (for configurations that require them) terraform destroy -var-file="production.tfvars" # Preview destruction plan before executing terraform plan -destroy # Example output: # aws_instance.web: Destroying... [id=i-0abc123def456789] # aws_instance.web: Still destroying... [10s elapsed] # aws_instance.web: Destruction complete after 30s # # Destroy complete! Resources: 1 destroyed. ``` ## terraform validate - Validate Configuration The `terraform validate` command validates the configuration files in a directory. It checks that a configuration is syntactically valid and internally consistent, regardless of any provided variables or existing state. Validation requires an initialized working directory with provider plugins. ```bash # Validate the configuration in the current directory terraform validate # Validate and output in JSON format terraform validate -json # Example successful output: # Success! The configuration is valid. # Example JSON output: # { # "valid": true, # "error_count": 0, # "warning_count": 0, # "diagnostics": [] # } # Example error output: # Error: Missing required argument # # on main.tf line 5, in resource "aws_instance" "web": # 5: resource "aws_instance" "web" { # # The argument "ami" is required, but no definition was found. ``` ## terraform fmt - Format Configuration The `terraform fmt` command rewrites Terraform configuration files to a canonical format and style. It applies a subset of the Terraform language style conventions, including proper indentation and alignment. This command is useful for ensuring consistent formatting across a team. ```bash # Format files in the current directory terraform fmt # Format and list files that were modified terraform fmt -list=true # Check if files are formatted (useful in CI/CD) terraform fmt -check # Show diff of formatting changes terraform fmt -diff # Recursively format files in subdirectories terraform fmt -recursive # Format a specific file terraform fmt main.tf # Format from stdin echo 'resource"aws_instance""example"{ami="ami-12345"}' | terraform fmt - # Example output with -list: # main.tf # variables.tf ``` ## terraform output - Read Outputs The `terraform output` command reads an output variable from a Terraform state file and prints the value. Output values are defined in configuration and computed after apply, making them available for other configurations or external systems. ```bash # Show all outputs terraform output # Show a specific output value terraform output instance_ip # Show output in JSON format terraform output -json # Show raw output value (without quotes for strings) terraform output -raw instance_ip # Read from a specific state file terraform output -state=path/to/terraform.tfstate # Example configuration: # output "instance_ip" { # value = aws_instance.web.public_ip # description = "Public IP of the web server" # } # # output "database_endpoint" { # value = aws_db_instance.main.endpoint # sensitive = true # } # Example output: # database_endpoint = <sensitive> # instance_ip = "54.123.45.67" ``` ## terraform state - State Management The `terraform state` command provides subcommands for advanced state management operations. These commands can modify the state file and should be used with caution. Common operations include listing resources, showing resource details, moving resources, and removing resources from state. ```bash # List all resources in the state terraform state list # List resources matching a pattern terraform state list 'module.vpc.*' # Show details of a specific resource terraform state show aws_instance.web # Move a resource to a different address (rename) terraform state mv aws_instance.web aws_instance.web_server # Move a resource into a module terraform state mv aws_instance.web module.compute.aws_instance.web # Remove a resource from state (without destroying) terraform state rm aws_instance.legacy # Pull the current state and output to stdout terraform state pull # Push a local state file to remote backend terraform state push terraform.tfstate # Replace provider for all resources terraform state replace-provider hashicorp/aws registry.example.com/aws # Example state show output: # resource "aws_instance" "web" { # ami = "ami-0c55b159cbfafe1f0" # arn = "arn:aws:ec2:us-west-2:123456789:instance/i-0abc123" # instance_type = "t3.micro" # private_ip = "10.0.1.50" # public_ip = "54.123.45.67" # tags = { # "Name" = "WebServer" # } # } ``` ## terraform import - Import Existing Resources The `terraform import` command imports existing infrastructure into your Terraform state. This allows you to bring resources created outside of Terraform under Terraform management. You must write a resource configuration block that corresponds to the imported resource. ```bash # Import an AWS EC2 instance terraform import aws_instance.web i-0abc123def456789 # Import with variables terraform import -var="region=us-west-2" aws_instance.web i-0abc123def456789 # Import a resource into a module terraform import module.vpc.aws_vpc.main vpc-12345678 # Import with specific state file terraform import -state=terraform.tfstate aws_s3_bucket.data my-bucket-name # Example: Import workflow # 1. Write the resource configuration: # resource "aws_instance" "web" { # # Configuration will be filled after import # } # # 2. Run import command: # terraform import aws_instance.web i-0abc123def456789 # # 3. Run plan to see current vs desired state: # terraform plan # # 4. Update configuration to match imported state # Import block (Terraform 1.5+) - declarative import: # import { # to = aws_instance.web # id = "i-0abc123def456789" # } ``` ## terraform workspace - Manage Workspaces The `terraform workspace` command manages named workspaces, allowing you to have multiple distinct state files for the same configuration. Workspaces are useful for managing multiple environments (dev, staging, prod) with the same Terraform code. ```bash # List all workspaces terraform workspace list # Show current workspace terraform workspace show # Create a new workspace terraform workspace new staging # Switch to an existing workspace terraform workspace select production # Delete a workspace (must switch away first) terraform workspace delete staging # Create workspace with existing state terraform workspace new -state=existing.tfstate production # Example usage with workspace-aware configuration: # locals { # environment = terraform.workspace # instance_count = { # default = 1 # development = 1 # staging = 2 # production = 5 # } # } # # resource "aws_instance" "web" { # count = local.instance_count[local.environment] # instance_type = local.environment == "production" ? "t3.large" : "t3.micro" # tags = { # Environment = local.environment # } # } # Example output: # default # * development # production # staging ``` ## terraform test - Run Integration Tests The `terraform test` command executes automated integration tests against your Terraform configuration. Tests are written in `.tftest.hcl` files and create real infrastructure to verify that your modules work correctly. Terraform automatically cleans up test infrastructure after execution. ```bash # Run all tests terraform test # Run specific test files terraform test -filter=tests/validation.tftest.hcl # Run tests with verbose output terraform test -verbose # Run tests with variables terraform test -var="region=us-west-2" # Output test results in JSON format terraform test -json # Save JUnit XML report terraform test -junit-xml=test-results.xml # Example test file (tests/basic.tftest.hcl): # run "create_instance" { # command = apply # # assert { # condition = aws_instance.web.instance_state == "running" # error_message = "Instance should be running" # } # # assert { # condition = length(aws_instance.web.public_ip) > 0 # error_message = "Instance should have a public IP" # } # } # # run "verify_tags" { # command = plan # # assert { # condition = aws_instance.web.tags["Environment"] == "test" # error_message = "Instance should be tagged with test environment" # } # } # Example output: # tests/basic.tftest.hcl... in progress # run "create_instance"... pass # run "verify_tags"... pass # tests/basic.tftest.hcl... tearing down # tests/basic.tftest.hcl... pass # # Success! 2 passed, 0 failed. ``` ## terraform console - Interactive Console The `terraform console` command provides an interactive console for evaluating Terraform expressions. It loads the current state and configuration, allowing you to test expressions and explore data before using them in your configuration. ```bash # Start the interactive console terraform console # Use with a specific state file terraform console -state=path/to/terraform.tfstate # Example console session: # > 1 + 2 # 3 # # > "hello, ${"world"}" # "hello, world" # # > length(["a", "b", "c"]) # 3 # # > aws_instance.web.public_ip # "54.123.45.67" # # > [for s in ["a", "b", "c"] : upper(s)] # ["A", "B", "C"] # # > { for k, v in var.tags : k => lower(v) } # { "Environment" = "production", "Team" = "platform" } # # > cidrsubnet("10.0.0.0/16", 8, 1) # "10.0.1.0/24" # # > formatdate("YYYY-MM-DD", timestamp()) # "2024-01-15" # # > jsondecode(file("config.json")) # { "setting1" = "value1", "setting2" = "value2" } ``` ## terraform graph - Generate Dependency Graph The `terraform graph` command generates a visual representation of the configuration or execution plan as a graph in DOT format. This is useful for understanding dependencies between resources and debugging complex configurations. ```bash # Generate a graph of the configuration terraform graph # Generate a graph from a plan file terraform graph tfplan # Generate and render as PNG using Graphviz terraform graph | dot -Tpng > graph.png # Generate and render as SVG terraform graph | dot -Tsvg > graph.svg # Generate a plan graph (includes planned changes) terraform graph -type=plan # Generate an apply graph terraform graph -type=apply # Generate a destroy graph terraform graph -type=plan-destroy # Example DOT output: # digraph { # compound = "true" # newrank = "true" # subgraph "root" { # "[root] aws_instance.web" [label = "aws_instance.web", shape = "box"] # "[root] aws_security_group.allow_http" [label = "aws_security_group.allow_http", shape = "box"] # "[root] aws_instance.web" -> "[root] aws_security_group.allow_http" # } # } ``` ## terraform providers - Provider Information The `terraform providers` command shows information about the providers required by the current configuration. Subcommands allow locking provider versions, mirroring providers for air-gapped environments, and viewing provider schemas. ```bash # Show providers required by configuration terraform providers # Lock provider versions to dependency lock file terraform providers lock # Lock for specific platforms terraform providers lock -platform=linux_amd64 -platform=darwin_arm64 # Mirror providers to a local directory terraform providers mirror /path/to/mirror # Show provider schema in JSON format terraform providers schema -json # Example output: # Providers required by configuration: # . # ├── provider[registry.terraform.io/hashicorp/aws] ~> 5.0 # ├── provider[registry.terraform.io/hashicorp/random] >= 3.0 # └── module.vpc # └── provider[registry.terraform.io/hashicorp/aws] >= 4.0 # Example schema output (partial): # terraform providers schema -json | jq '.provider_schemas["registry.terraform.io/hashicorp/aws"].resource_schemas["aws_instance"]' ``` ## terraform show - Inspect State or Plan The `terraform show` command reads and outputs a Terraform state or plan file in a human-readable form. When given a plan file, it shows the planned changes. When given no arguments, it shows the current state. ```bash # Show the current state terraform show # Show a saved plan file terraform show tfplan # Show state in JSON format terraform show -json # Show plan in JSON format terraform show -json tfplan # Show without color (useful for logging) terraform show -no-color # Example output: # # aws_instance.web: # resource "aws_instance" "web" { # ami = "ami-0c55b159cbfafe1f0" # arn = "arn:aws:ec2:us-west-2:123456789:instance/i-0abc123" # availability_zone = "us-west-2a" # instance_state = "running" # instance_type = "t3.micro" # private_ip = "10.0.1.50" # public_ip = "54.123.45.67" # tags = { # "Name" = "WebServer" # } # } ``` ## Configuration Language - Resource Blocks Terraform configurations use HCL (HashiCorp Configuration Language) to define infrastructure resources. Resource blocks describe one or more infrastructure objects, such as virtual networks, compute instances, or DNS records. ```hcl # Basic resource definition resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro" tags = { Name = "WebServer" Environment = "production" } } # Resource with count for multiple instances resource "aws_instance" "cluster" { count = 3 ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro" tags = { Name = "cluster-${count.index}" } } # Resource with for_each for named instances resource "aws_instance" "servers" { for_each = toset(["web", "api", "db"]) ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro" tags = { Name = each.key Role = each.value } } # Resource with dependencies resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro" subnet_id = aws_subnet.main.id vpc_security_group_ids = [aws_security_group.allow_http.id] depends_on = [aws_internet_gateway.main] } # Resource with lifecycle rules resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro" lifecycle { create_before_destroy = true prevent_destroy = true ignore_changes = [tags] } } # Resource with provisioner (use sparingly) resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro" provisioner "remote-exec" { inline = [ "sudo apt-get update", "sudo apt-get install -y nginx" ] connection { type = "ssh" user = "ubuntu" private_key = file("~/.ssh/id_rsa") host = self.public_ip } } } ``` ## Configuration Language - Variables and Outputs Variables allow parameterizing Terraform configurations, making them reusable across different environments. Outputs expose values from your configuration for use by other configurations or external systems. ```hcl # Variable definitions (variables.tf) variable "region" { description = "AWS region for resources" type = string default = "us-west-2" } variable "instance_count" { description = "Number of instances to create" type = number default = 1 validation { condition = var.instance_count > 0 && var.instance_count <= 10 error_message = "Instance count must be between 1 and 10." } } variable "environment" { description = "Environment name" type = string validation { condition = contains(["dev", "staging", "prod"], var.environment) error_message = "Environment must be dev, staging, or prod." } } variable "tags" { description = "Tags to apply to resources" type = map(string) default = {} } variable "availability_zones" { description = "List of availability zones" type = list(string) default = ["us-west-2a", "us-west-2b"] } variable "database_config" { description = "Database configuration" type = object({ engine = string instance_class = string storage = number }) default = { engine = "postgres" instance_class = "db.t3.micro" storage = 20 } } variable "db_password" { description = "Database password" type = string sensitive = true } # Output definitions (outputs.tf) output "instance_ids" { description = "IDs of created instances" value = aws_instance.web[*].id } output "load_balancer_dns" { description = "DNS name of the load balancer" value = aws_lb.main.dns_name } output "database_endpoint" { description = "Database connection endpoint" value = aws_db_instance.main.endpoint sensitive = true } output "instance_map" { description = "Map of instance names to IPs" value = { for k, v in aws_instance.servers : k => v.public_ip } } # Variable file (terraform.tfvars) region = "us-east-1" instance_count = 3 environment = "prod" tags = { Project = "MyApp" Owner = "platform-team" } # Using variables in resources resource "aws_instance" "web" { count = var.instance_count ami = data.aws_ami.ubuntu.id instance_type = var.environment == "prod" ? "t3.large" : "t3.micro" tags = merge(var.tags, { Name = "web-${count.index}" Environment = var.environment }) } ``` ## Configuration Language - Modules Modules are containers for multiple resources that are used together. They allow you to organize configuration, encapsulate complexity, and reuse infrastructure patterns across projects. ```hcl # Calling a module from the Terraform Registry module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "5.0.0" name = "my-vpc" cidr = "10.0.0.0/16" azs = ["us-west-2a", "us-west-2b", "us-west-2c"] private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] enable_nat_gateway = true single_nat_gateway = true tags = { Environment = "production" } } # Calling a local module module "web_server" { source = "./modules/web-server" instance_count = 3 instance_type = "t3.micro" subnet_ids = module.vpc.private_subnets vpc_id = module.vpc.vpc_id } # Calling a module from GitHub module "security" { source = "github.com/myorg/terraform-modules//security?ref=v1.2.0" vpc_id = module.vpc.vpc_id } # Module with for_each module "environments" { source = "./modules/environment" for_each = toset(["dev", "staging", "prod"]) environment_name = each.key instance_count = each.key == "prod" ? 5 : 1 } # Local module definition (modules/web-server/main.tf) variable "instance_count" { type = number } variable "instance_type" { type = string } variable "subnet_ids" { type = list(string) } variable "vpc_id" { type = string } resource "aws_instance" "web" { count = var.instance_count ami = data.aws_ami.ubuntu.id instance_type = var.instance_type subnet_id = element(var.subnet_ids, count.index) tags = { Name = "web-${count.index}" } } resource "aws_security_group" "web" { vpc_id = var.vpc_id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } output "instance_ids" { value = aws_instance.web[*].id } output "security_group_id" { value = aws_security_group.web.id } ``` ## Configuration Language - Data Sources Data sources allow Terraform to use information defined outside of Terraform, defined by another separate Terraform configuration, or modified by functions. They enable querying and referencing external data in your configurations. ```hcl # Query the latest Ubuntu AMI data "aws_ami" "ubuntu" { most_recent = true owners = ["099720109477"] # Canonical filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"] } filter { name = "virtualization-type" values = ["hvm"] } } # Use the AMI in a resource resource "aws_instance" "web" { ami = data.aws_ami.ubuntu.id instance_type = "t3.micro" } # Query current AWS account info data "aws_caller_identity" "current" {} data "aws_region" "current" {} # Use account info resource "aws_s3_bucket" "logs" { bucket = "logs-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}" } # Query existing VPC data "aws_vpc" "existing" { filter { name = "tag:Name" values = ["production-vpc"] } } # Query availability zones data "aws_availability_zones" "available" { state = "available" } resource "aws_subnet" "private" { count = length(data.aws_availability_zones.available.names) vpc_id = data.aws_vpc.existing.id availability_zone = data.aws_availability_zones.available.names[count.index] cidr_block = cidrsubnet(data.aws_vpc.existing.cidr_block, 8, count.index) } # Read a file data "local_file" "config" { filename = "${path.module}/config.json" } # Query remote state from another Terraform configuration data "terraform_remote_state" "network" { backend = "s3" config = { bucket = "terraform-state" key = "network/terraform.tfstate" region = "us-west-2" } } resource "aws_instance" "web" { ami = data.aws_ami.ubuntu.id instance_type = "t3.micro" subnet_id = data.terraform_remote_state.network.outputs.private_subnet_ids[0] } ``` ## Backend Configuration - State Storage Backends define where Terraform stores its state file. Remote backends enable team collaboration, state locking, and secure storage. The backend configuration block specifies how state operations are performed. ```hcl # S3 backend with DynamoDB locking terraform { backend "s3" { bucket = "my-terraform-state" key = "prod/terraform.tfstate" region = "us-west-2" encrypt = true dynamodb_table = "terraform-locks" } } # Azure Storage backend terraform { backend "azurerm" { resource_group_name = "tfstate-rg" storage_account_name = "tfstate12345" container_name = "tfstate" key = "prod.terraform.tfstate" } } # Google Cloud Storage backend terraform { backend "gcs" { bucket = "my-terraform-state" prefix = "terraform/state" } } # HCP Terraform (Terraform Cloud) backend terraform { cloud { organization = "my-org" workspaces { name = "my-workspace" } } } # Multiple workspaces with HCP Terraform terraform { cloud { organization = "my-org" workspaces { tags = ["app:myapp"] } } } # Local backend (default) terraform { backend "local" { path = "terraform.tfstate" } } # Consul backend terraform { backend "consul" { address = "consul.example.com:8500" scheme = "https" path = "terraform/state" lock = true } } # Partial backend configuration (set remaining values via CLI or file) terraform { backend "s3" { key = "prod/terraform.tfstate" # bucket and region provided via: # terraform init -backend-config="bucket=my-bucket" -backend-config="region=us-west-2" } } ``` Terraform is primarily used to provision and manage cloud infrastructure resources across multiple providers including AWS, Azure, Google Cloud, Kubernetes, and many others. Common use cases include deploying multi-tier applications, managing networking infrastructure (VPCs, subnets, security groups), provisioning databases and storage, setting up CI/CD infrastructure, and managing container orchestration platforms. The declarative approach allows teams to version control their infrastructure alongside application code, enabling Infrastructure as Code (IaC) practices. Integration patterns with Terraform typically involve using remote backends for team collaboration and state management, implementing CI/CD pipelines that run `terraform plan` on pull requests and `terraform apply` on merge, structuring configurations into reusable modules for common patterns, using workspaces or directory structures to manage multiple environments, and integrating with secret management tools like HashiCorp Vault for sensitive data. Terraform can also be embedded into larger automation workflows using its JSON output format for machine-readable results, the `terraform-exec` Go library for programmatic control, or the RPC API for advanced integrations requiring direct access to Terraform Core functionality.