← Back to hashicorp/terraform

How to Deploy & Use hashicorp/terraform

# Terraform Core Deployment & Usage Guide

Comprehensive guide for building, deploying, and using Terraform Core from source.

## Prerequisites

- **Go**: Version 1.22 or later (required for building from source)
- **Git**: For cloning the repository
- **Protocol Buffers Compiler** (`protoc`): Required only if regenerating protobuf/gRPC code (development/contributing)
- **Make**: Optional but recommended for using build shortcuts
- **Operating System**: Linux, macOS, or Windows

## Installation

### 1. Clone the Repository

```bash
git clone https://github.com/hashicorp/terraform.git
cd terraform

2. Build from Source

Development Build:

go build -o terraform .

Install to $GOPATH/bin:

go install .

Verify Installation:

./terraform version
# or if installed to PATH:
terraform version

3. Download Pre-built Binaries (Alternative)

If not building from source, download official releases from: https://developer.hashicorp.com/terraform/downloads

Configuration

Environment Variables

VariableDescriptionExample
TF_LOGEnable logging (TRACE, DEBUG, INFO, WARN, ERROR)TF_LOG=DEBUG
TF_LOG_PATHPath to write log outputTF_LOG_PATH=/tmp/terraform.log
TF_DATA_DIRChange location of .terraform directoryTF_DATA_DIR=/opt/terraform/data
TF_PLUGIN_CACHE_DIRDirectory to cache provider pluginsTF_PLUGIN_CACHE_DIR=$HOME/.terraform.d/plugin-cache
TF_CLI_CONFIG_FILEPath to CLI configuration fileTF_CLI_CONFIG_FILE=~/.terraformrc
TF_IN_AUTOMATIONAdjust output for CI/CD environmentsTF_IN_AUTOMATION=true

CLI Configuration File

Create ~/.terraformrc (Unix) or %APPDATA%\terraform.rc (Windows):

plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"

provider_installation {
  filesystem_mirror {
    path    = "/opt/terraform/providers"
    include = ["registry.terraform.io/*/*"]
  }
  direct {
    exclude = ["registry.terraform.io/hashicorp/*"]
  }
}

Provider Configuration

Provider configuration is project-specific. Example main.tf:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "us-west-2"
}

Build & Run

Development Workflow

Run Tests:

# All tests
go test ./...

# Specific package (e.g., plan file handling)
go test ./internal/plans/planfile/...

# With verbose output
go test -v ./internal/terraform/...

# Race condition detection
go test -race ./...

Generate Protobuf Code (if modifying .proto files):

# Requires protoc and protoc-gen-go
go generate ./...

Build for Multiple Platforms:

# Linux
GOOS=linux GOARCH=amd64 go build -o terraform-linux-amd64 .

# macOS
GOOS=darwin GOARCH=amd64 go build -o terraform-darwin-amd64 .
GOOS=darwin GOARCH=arm64 go build -o terraform-darwin-arm64 .

# Windows
GOOS=windows GOARCH=amd64 go build -o terraform-windows-amd64.exe .

Local Execution

Initialize a Project:

mkdir ~/terraform-test && cd ~/terraform-test
cat > main.tf << 'EOF'
resource "null_resource" "test" {
  triggers = {
    always_run = timestamp()
  }
}
EOF

/path/to/terraform init

Plan and Apply:

/path/to/terraform plan
/path/to/terraform apply -auto-approve

Deployment

CI/CD Integration

GitHub Actions:

name: Terraform
on: [push]
jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: "1.9.0"
      - run: terraform init
      - run: terraform plan

GitLab CI:

stages:
  - deploy

terraform:
  stage: deploy
  image: hashicorp/terraform:1.9
  script:
    - terraform init
    - terraform apply -auto-approve
  only:
    - main

Container Deployment

Dockerfile for Custom Build:

FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o terraform .

FROM alpine:latest
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/terraform /usr/local/bin/terraform
ENTRYPOINT ["terraform"]

Build and Run:

docker build -t terraform-local .
docker run --rm -v $(pwd):/workspace -w /workspace terraform-local plan

Package Managers

Homebrew (macOS/Linux):

brew tap hashicorp/tap
brew install hashicorp/tap/terraform

Chocolatey (Windows):

choco install terraform

APT (Debian/Ubuntu):

wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform

Troubleshooting

Build Issues

Error: go: module requires Go 1.22

  • Solution: Upgrade Go to version 1.22 or later:
    # macOS
    brew install go@1.22
    
    # Linux
    wget https://go.dev/dl/go1.22.0.linux-amd64.tar.gz
    sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz
    export PATH=$PATH:/usr/local/go/bin
    

Error: protoc: command not found (when running go generate)

  • Solution: Install Protocol Buffers compiler:
    # macOS
    brew install protobuf
    
    # Ubuntu/Debian
    apt install -y protobuf-compiler
    
    # Then install Go protoc plugins
    go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
    

Error: undefined: tfplugin5 or undefined: tfplugin6

  • Solution: Regenerate protobuf code:
    go generate ./internal/plugin/...
    go generate ./internal/plugin6/...
    

Runtime Issues

Error: Failed to load plugin: incompatible API version

  • Cause: Provider plugin protocol mismatch between Terraform core and provider
  • Solution:
    • Update provider to version supporting protocol v6 (for Terraform 1.0+)
    • Or set TF_PLUGIN_PROTOCOL_VERSIONS=5 to force legacy protocol

Error: Error acquiring the state lock

  • Cause: Previous Terraform process crashed or state is locked by another process
  • Solution:
    # Identify lock holder
    terraform force-unlock <LOCK_ID>
    
    # Or if using local state and sure no other process is running:
    rm .terraform.tfstate.lock.info
    

High Memory Usage During Plan

  • Cause: Large state files or complex resource graphs
  • Solution:
    • Set TF_PLUGIN_CACHE_DIR to avoid re-downloading providers
    • Use -target to limit scope: terraform plan -target=aws_instance.example
    • Enable parallel resource reduction: TF_PLUGIN_PROCESSES=2 (limits concurrent provider processes)

Debug and Logging

Enable Debug Logging:

export TF_LOG=TRACE
export TF_LOG_PATH=/tmp/terraform-debug.log
terraform apply

GRPC Debugging (Provider Communication):

export TF_GRPC_DEBUG=1
export TF_LOG=DEBUG

Check Provider Plugin Versions:

terraform version
terraform providers

Common Exit Codes

CodeMeaningResolution
0Success-
1ErrorCheck logs with TF_LOG=DEBUG
2Plan changes presentNormal for plan in CI/CD