Developer Guide
Relevant source files
The following files were used as context for generating this wiki page:
This guide provides essential information for developers contributing to Terraform Core. It covers the project's structure, development workflows, bug triage process, release procedures, and testing framework. This repository contains only Terraform core, which includes the command-line interface (CLI) and the main graph engine. Providers are implemented as plugins and are developed in separate repositories.
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Its key features include Infrastructure as Code, Execution Plans, a Resource Graph for parallel execution, and Change Automation. For more details on contributing, refer to the contributing guide. For documentation contributions, see the Web Unified Docs repository.
Sources: README.md, website/README.md
Bug Triage Process
The Terraform Core team follows a structured bug triage process to respond to reported issues quickly. The goal is to either prepare a bug report for engineering to fix or to close it with an explanation.
Sources: BUGPROCESS.md
Triage Workflow
The process involves several stages, managed through GitHub labels.
The following diagram illustrates the bug triage workflow from initial report to resolution.
Sources: BUGPROCESS.md:10-53
GitHub Issue Labels
The following labels are used to track the state of bug reports in the triage process.
| Label | Description |
|---|---|
new | A new issue that has not yet been triaged. |
waiting for reproduction | The issue cannot be reproduced without more information from the reporter. |
confirmed | A Terraform Core team member has successfully reproduced the issue. |
explained | A team member has described the root cause of the issue in the code. |
working as designed | The reported behavior is intended, and the issue is closed. |
duplicate | The issue is a duplicate of another existing issue. |
not reproducible | The issue was closed because a reproduction case could not be generated. |
pending project | The issue is confirmed but requires a significant project to fix. |
Sources: BUGPROCESS.md:55-64
Issue Lifecycle
- Initial Filtering: New issues are filtered to categorize them, route them to appropriate teams (backends, providers), or close them if they are support requests or for unsupported versions.
- Reproduction: A core team member attempts to reproduce the issue. If successful, it's marked as
confirmed. If not, it's labeledwaiting for reproduction. - Explanation/Fix: For
confirmedissues, the team either explains why the behavior is expected (working as designed) or locates the defect in the code, marking it asexplained. - Resolution:
explainedissues are assigned to a milestone and a pull request is created to fix them.
Issues waiting for reproduction or waiting-response for more than 30 days may be closed to keep the bug backlog actionable.
Sources: BUGPROCESS.md:10-53, BUGPROCESS.md:66-75
Release and Changelog Management
Release and changelog tasks are managed by the scripts/changelog.sh script. This script uses changie to update CHANGELOG.md and sets the version in the version/VERSION file.
Sources: scripts/changelog.sh
Commands
The script supports several commands for managing different phases of a release.
| Command | Description |
|---|---|
generate <release-type> | Creates a new section in CHANGELOG.md for the given release type. |
nextminor | Updates the minor version on the main branch. |
listIssuesInRelease | Lists all issues associated with a specific release version. |
Sources: scripts/changelog.sh:13-26, scripts/changelog.sh:160-178
Release Generation Flow
The generate command handles different types of releases, each updating the changelog and version file accordingly.
The diagram below shows the workflow for the generate command based on the release type.
Sources: scripts/changelog.sh:28-121
Testing
Terraform Core has a robust testing framework, including the terraform test command for running module tests and a suite of equivalence tests to ensure command output consistency.
Module Testing (terraform test)
The terraform test command executes test files, typically with a .tftest.hcl extension, to validate module behavior. Tests are organized into run blocks, which execute plan or apply commands and make assertions on the results.
Sources: internal/command/test_test.go
Test File Structure
testblock: Defines file-level settings, such asparallel = true.providerblock: Defines providers used within the test file.variablesblock: Defines input variables for the test runs.runblock: Defines a single test case. It can specify acommand(planorapply), inputvariables, andassertblocks to validate conditions.assertblock: Contains aconditionexpression that must evaluate totruefor the test to pass and anerror_message.
Sources: internal/command/test_test.go
Test Execution Lifecycle
A typical test run involves planning, applying, and asserting conditions on the resulting state and outputs. The framework also handles teardown to clean up created resources.
This sequence diagram illustrates the lifecycle of a single run block within terraform test.
Sources: internal/command/test_test.go
Key Features
- State Management: Tests can share state using the
state_keyattribute inrunblocks. This allows for creating dependent infrastructure across multiple test runs. - Mocking: The framework supports mocking providers and overriding resource behavior during
planorapplystages usingoverride_blocks. - Assertions: Custom conditions can be asserted on input variables, resource attributes, and output values. The framework provides detailed diffs on failure.
- Parallelism: Tests can be run in parallel to speed up execution, both at the file level (
test { parallel = true }) and via the-parallelismcommand-line flag. - Cleanup: The testing framework automatically destroys resources created during a test run. The
skip_cleanupattribute can be used to persist state for debugging or for subsequent test runs. Theterraform test -cleanupcommand can be used to clean up any leftover state.
Sources: internal/command/test_test.go:183-187, internal/command/test_test.go:240-243, internal/command/test_test.go:1300-1304, internal/command/test_test.go:2073-2077
Equivalence Testing
Equivalence tests are end-to-end tests that verify the output of Terraform commands does not change unexpectedly between code changes. These tests are located in the testing/equivalence-tests directory and are executed automatically by the CI system on every pull request.
- When a PR is opened, the tests run a
diffand comment on the PR with the results. - When a PR is closed, the tests run an
updateand open a new PR with the updated reference output files if changes are detected.
Sources: testing/equivalence-tests/README.md
Development for Automation
Terraform is designed to be run in automated CI/CD pipelines. The TF_IN_AUTOMATION environment variable can be set to any non-empty value to optimize the CLI output for non-interactive environments.
Sources: internal/command/e2etest/automation_test.go:28-32
Recommended Automation Workflow
The recommended workflow for automation is to separate planning and applying into distinct steps to allow for manual review and approval.
This diagram shows a typical CI/CD pipeline for Terraform.
terraform init -input=false: Initializes the working directory non-interactively.terraform plan -out=tfplan -input=false: Creates an execution plan and saves it to a file.terraform apply -input=false tfplan: Applies the changes defined in the saved plan file, also non-interactively.
For workflows that do not require a manual approval step, terraform apply -auto-approve can be used.
Sources: internal/command/e2etest/automation_test.go:81-137
Cloud Backend Integration
Terraform can use HCP Terraform or Terraform Enterprise as a remote backend for state storage and operations. This is configured via the cloud block in a Terraform configuration file.
Sources: internal/cloud/backend.go
Configuration
The cloud backend is configured with the following attributes:
| Attribute | Description | Environment Variable |
|---|---|---|
hostname | The Terraform Enterprise hostname. Defaults to app.terraform.io. | TF_CLOUD_HOSTNAME |
organization | The name of the organization containing the workspaces. | TF_CLOUD_ORGANIZATION |
token | The API token for authentication. It's recommended to use terraform login instead. | (Varies by hostname) |
workspaces | A block to configure workspace mapping using either name or tags. | TF_WORKSPACE |
Sources: internal/cloud/backend.go:104-135, internal/cloud/backend.go:394-490
Workspace Mapping Strategies
There are two primary strategies for mapping a local configuration to remote workspaces:
- Name Strategy: A single remote workspace is specified by
workspaces.name. This conflicts with thetagsattribute and theTF_WORKSPACEenvironment variable. - Tags Strategy: A set of
workspaces.tagsis used to select a group of remote workspaces. This is the recommended approach for managing multiple environments (e.g., dev, staging, prod) from a single configuration. Tags can be a set of strings or a map of key-value pairs.
If neither name nor tags are specified, Terraform falls back to using the TF_WORKSPACE environment variable to determine the workspace name.
Sources: internal/cloud/backend.go:463-488, internal/cloud/backend.go:1072-1090