Terraform Core Wiki
Relevant source files
The following files were used as context for generating this wiki page:
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. This repository, terraform, contains the core of the Terraform project, which includes the command-line interface (CLI) and the main graph engine. It does not contain the code for providers, which are implemented as separate plugins that Terraform Core can automatically download from registries.
The core is responsible for parsing configuration files, building a dependency graph of resources, creating execution plans, and applying those plans to create and manage infrastructure. It interacts with providers to manage the lifecycle of specific resources and can be integrated with HCP Terraform (or Terraform Enterprise) for advanced state management, collaboration, and governance.
Sources: README.md
Core Concepts
Terraform's core functionality is built on a few key concepts that enable its declarative and automated approach to infrastructure management.
- Infrastructure as Code: Infrastructure is described using a high-level configuration syntax. This allows a blueprint of your datacenter to be versioned, shared, and reused like any other code.
- Execution Plans: Terraform has a "planning" step where it generates an execution plan. This plan shows what Terraform will do when
applyis called, such as creating, updating, or deleting resources. This provides predictability and prevents surprises. - Resource Graph: Terraform builds a graph of all resources defined in the configuration to understand their dependencies. It uses this graph to parallelize the creation and modification of any non-dependent resources, making infrastructure provisioning as efficient as possible.
- Change Automation: Complex changesets can be applied to infrastructure with minimal human interaction. The execution plan and resource graph ensure that changes are applied in the correct order, avoiding many potential human errors.
Sources: README.md:10-27
Architecture
Terraform Core acts as an orchestrator, connecting user configuration with the plugins that manage the actual infrastructure resources.
This diagram shows the high-level architecture of Terraform. The user provides configuration files, which the Terraform Core CLI and Graph Engine process. The Core interacts with Provider Plugins to manage infrastructure, and with either a local state file or a remote backend like HCP Terraform for state management.
Sources: README.md:32-35
HCP Terraform and Cloud Backend
Terraform Core can integrate with HCP Terraform or Terraform Enterprise using the cloud block, which replaces the legacy remote backend. This integration enables features like remote state storage, remote operations, and governance.
Sources: internal/cloud/backend.go:132-135
Configuration
The cloud integration is configured via a cloud block within a terraform block in the configuration files.
| Attribute | Type | Description |
|---|---|---|
hostname | string | The hostname of the Terraform Enterprise instance. Defaults to app.terraform.io for HCP Terraform. |
organization | string | The name of the organization containing the target workspaces. |
token | string | The API token for authentication. It's recommended to use terraform login instead of setting this directly. |
workspaces | block (single) | A block to configure how CLI workspaces map to remote workspaces. Contains either a name or tags attribute. |
workspaces.name | string | The name of a single remote workspace to use. Conflicts with tags. |
workspaces.project | string | The name of an HCP Terraform or Terraform Enterprise project. Workspaces that need creating will be created within this project. |
workspaces.tags | set or map | A set of tags (or key/value map of tags) used to select a group of remote workspaces. Conflicts with name. When using a map, the backend must support key-value tags. |
Sources: internal/cloud/backend.go:138-171, internal/cloud/backend.go:1360-1388
Configuration Resolution
The final cloud configuration is resolved from the HCL configuration, environment variables, and default values.
This diagram illustrates the logic of the resolveCloudConfig function.
Sources: internal/cloud/backend.go:490-589
Workspace Mapping Strategies
The workspaces block determines how local workspaces map to remote ones in HCP Terraform.
| Strategy | workspaces Configuration | TF_WORKSPACE Env Var | Behavior |
|---|---|---|---|
WorkspaceNameStrategy | name = "my-workspace" | Not allowed (unless it matches name) | Binds the configuration to a single remote workspace. |
WorkspaceTagsStrategy | tags = ["app", "prod"] | Optional; selects the current workspace from the set. | Maps to a set of remote workspaces matching the given tags. New workspaces are created with these tags. |
WorkspaceKVTagsStrategy | tags = { team = "devops", env = "prod" } | Optional; selects the current workspace from the set. | Maps to a set of remote workspaces matching the given key-value tags. |
WorkspaceNoneStrategy | Not set | my-workspace | Falls back to using TF_WORKSPACE as the workspace name. If not set, it's an error. |
Sources: internal/cloud/backend.go:1174-1196
Command Lifecycle: init
The terraform init command is the first step in any workflow. It prepares the working directory by downloading modules, initializing the backend, and downloading required provider plugins.
init Process Flow
The run method in internal/command/init.go orchestrates the initialization steps.
This flowchart shows the main steps of the init command, including optional steps like copying a module and the core tasks of installing modules, initializing the backend, and installing providers.
Sources: internal/command/init.go
UI Messages
The init command provides feedback to the user in either human-readable text or a machine-readable JSON format. The internal/command/views/init.go file defines the messages for this output.
| Message Code | Human-Readable Example | JSON Example |
|---|---|---|
initializing_backend_message | Initializing the backend... | Initializing the backend... |
initializing_provider_plugin_message | Initializing provider plugins... | Initializing provider plugins... |
finding_matching_version_message | - Finding hashicorp/null versions matching ">= 1.0"... | Finding matching versions for provider: hashicorp/null, version_constraint: ">= 1.0" |
installing_provider_message | - Installing hashicorp/null v3.2.1... | Installing provider version: hashicorp/null v3.2.1... |
output_init_success_message | Terraform has been successfully initialized! | Terraform has been successfully initialized! |
Sources: internal/command/views/init.go:101-213
Data Structures
Terraform Core relies on several key data structures, defined as Protocol Buffers, for its internal operations, particularly for plans and provider schemas.
Plan File Structure
The structure of a Terraform plan file (tfplan) is defined in internal/plans/planproto/planfile.proto. It's a binary format that captures the intended changes to the infrastructure.
The diagram below shows the main entities within a Plan message.
Provider Schema
The schema for providers, their resources, and their attributes is defined in internal/rpcapi/terraform1/dependencies/dependencies.pb.go. This structure allows Terraform Core to understand the configuration options available for any given provider.
A ProviderSchema contains:
ProviderConfig: ASchemafor the provider's own configuration block.ManagedResourceTypes: A map of resource type names to theirSchema.DataResourceTypes: A map of data source type names to theirSchema.
A Schema is composed of a Block, which contains Attributes and nested BlockTypes.
This class diagram illustrates how a ProviderSchema is composed of Schema objects, which in turn are defined by Blocks containing attributes and other nested blocks.
Sources: internal/rpcapi/terraform1/dependencies/dependencies.pb.go:1745-1815, internal/rpcapi/terraform1/dependencies/dependencies.pb.go:1817-2717
Development and Contribution
The project has well-defined processes for building from source, handling bugs, and testing.
Building from Source
Terraform can be built from source using the Go toolchain. The build can be customized with ldflags.
version.dev=no: Removes the-devsuffix from the version string.main.experimentsAllowed=yes: Enables experimental features, which are typically only active in alpha builds.
For most platforms, CGO_ENABLED is set to 0 to produce a statically linked binary. For macOS, it is set to 1 to handle a platform-specific DNS resolution issue.
Sources: BUILDING.md
Bug Triage Process
The bug triage process is structured to ensure that issues are handled efficiently.
This flowchart visualizes the lifecycle of a bug report, from initial creation and filtering to confirmation, explanation, and finally resolution.
Sources: BUGPROCESS.md:4-40
Testing
Equivalence testing is a key part of the CI/CD pipeline. These are end-to-end tests that verify that the output of Terraform commands does not change unexpectedly between code changes.
- The tests are run automatically on every pull request.
- The
diffcommand is used to show differences between the current and previous run's output. - The
updatecommand is used to update the reference output files after a PR is merged. - This process is designed to be invisible to the PR author if no changes are detected.
Sources: testing/equivalence-tests/README.md
Additionally, the TF_IN_AUTOMATION environment variable can be set to any non-empty value to signal that Terraform is running in an automation pipeline. This adjusts the CLI output to be more suitable for non-interactive environments, for example by suppressing prompts and interactive advice.
Sources: internal/command/e2etest/automation_test.go:27-29, internal/command/e2etest/automation_test.go:61-64