Public Wiki47,621View on GitHub
Want hashicorp/terraform knowledge in your AI?

main.go

This is the Terraform CLI — HashiCorp's infrastructure-as-code tool that lets users declaratively define cloud and on-premises infrastructure in HCL configuration files, then plan and apply changes to provision and manage that infrastructure. It includes a core engine for dependency graph construction, diff planning, and state management, plus a gRPC-based plugin system for communicating with providers (AWS, GCP, Azure, etc.) and provisioners.

Key Features

  • Plan & Apply Engine
  • HCL Configuration Parsing
  • State Management
  • Provider Plugin System (gRPC v5/v6)
  • HCP Terraform / Terraform Enterprise Backend
  • CLI Command Framework
  • Address System
  • JSON Plan/State Rendering
  • Configuration Checks
  • Provider Source & Installation

Entry Points

Start here when working with this codebase

main.go
main.go

Application entry point

Start here to understand how the application initializes

Coding Conventions

Standards and patterns used in this codebase

Architecture

Use a factory pattern for CLI command registration, where each command is registered via a closure that returns a new command instance with injected dependencies (Meta struct, views, etc.)

"apply": func() (cli.Command, error) { return &command.ApplyCommand{Meta: meta}, nil }
commands.go
Architecture

Separate interface definitions from implementations using dedicated interface files, with provider/provisioner interfaces defined in their own packages and gRPC implementations wrapped separately

The providers.Interface is defined in internal/providers/, gRPC client in internal/plugin/, and gRPC server wrapper in internal/grpcwrap/
internal/providers/internal/plugin/internal/grpcwrap/
Package Design

Use dedicated address types (in internal/addrs) to represent all referenceable Terraform objects, providing type safety and consistent string representation across the codebase

addrs.Resource, addrs.Module, addrs.Provider types used throughout core, configs, states, and plans packages
internal/addrs/
Output/Views

Separate command logic from output rendering using a Views pattern, with distinct human-readable and JSON output implementations behind a common interface

internal/command/views/ contains separate human and JSON view implementations for each command (e.g., ApplyHuman, ApplyJSON)
internal/command/views/
Testing

Provide dedicated testing utility files (testing.go) within packages that define interfaces or complex types, offering helper functions for backend validation, state management testing, etc.

internal/backend/testing.go provides TestBackendConfig, TestBackendStates helper functions for validating backend implementations
internal/backend/testing.go
Version Management

Centralize version information in a dedicated version package to avoid import cycles, with SemVer string and prerelease metadata managed separately

version/version.go provides Version, Prerelease, and SemVer variables used throughout the codebase
version/version.go
Package Design

Separate representation from serialization: core domain types (states, plans, configs) live in their own packages, with JSON serialization handled in dedicated sibling packages (command/json*)

internal/states/ defines state types, internal/command/jsonstate/ handles JSON serialization of state
internal/states/internal/command/
Architecture

Use a layered plugin protocol with protobuf definitions (tfplugin5, tfplugin6) separate from Go interface wrappers, supporting multiple protocol versions simultaneously

internal/tfplugin5/ and internal/tfplugin6/ contain proto definitions; internal/plugin/ contains GRPCProvider for v5 and internal/plugin6/ for v6
internal/tfplugin5/internal/tfplugin6/internal/plugin/
State Management

Track check/validation states using a centralized state object with explicit status enums (Unknown, Pass, Fail, Error) initialized from configuration and updated during execution

checks.State manages statuses with StatusUnknown, StatusPass, StatusFail, StatusError and separates init (state_init.go) from reporting (state_report.go)
internal/checks/state.gointernal/checks/state_init.gointernal/checks/state_report.go
CLI Design

Separate argument/flag parsing into dedicated packages (internal/command/arguments) distinct from command execution logic, with validation handled at parse time

internal/command/arguments/ contains flag definitions and validation separate from command implementations in internal/command/
internal/command/arguments/
Initialization

Use signal handling and deferred cleanup in the main entry point, with graceful shutdown support via context cancellation and OS signal interception

main.go sets up signal handlers for SIGINT/SIGTERM and propagates cancellation through context
main.go
Observability

Support optional OpenTelemetry tracing via environment-driven configuration, keeping telemetry initialization isolated in its own file

telemetry.go initializes OTLP exporter when environment variables are set, with no impact when disabled
telemetry.go