Terraform Backend Configuration

Complete guide to configuring Terraform to use FreeState as your backend. Includes copy-paste examples for all common scenarios.

Basic Configuration

The simplest way to configure FreeState as your Terraform backend is to add the following configuration to your main.tf file:

terraform {
  backend "http" {
    address        = "https://api.freestate.cloud/v1/state/my-workspace"
    lock_address   = "https://api.freestate.cloud/v1/state/my-workspace/lock"
    unlock_address = "https://api.freestate.cloud/v1/state/my-workspace/lock"
    username       = "your-email@example.com"
    password       = "fs_api_your_api_key_here"
  }
}

Environment-Specific Configuration

For production use, it's recommended to use different workspaces for different environments. Here are examples for common environment setups:

Development Environment

# backend-dev.tf
terraform {
  backend "http" {
    address        = "https://api.freestate.cloud/v1/state/myapp-dev"
    lock_address   = "https://api.freestate.cloud/v1/state/myapp-dev/lock"
    unlock_address = "https://api.freestate.cloud/v1/state/myapp-dev/lock"
    username       = "dev-user@example.com"
    password       = "fs_api_dev_key_here"
  }
}

Staging Environment

# backend-staging.tf
terraform {
  backend "http" {
    address        = "https://api.freestate.cloud/v1/state/myapp-staging"
    lock_address   = "https://api.freestate.cloud/v1/state/myapp-staging/lock"
    unlock_address = "https://api.freestate.cloud/v1/state/myapp-staging/lock"
    username       = "staging-user@example.com"
    password       = "fs_api_staging_key_here"
  }
}

Production Environment

# backend-prod.tf
terraform {
  backend "http" {
    address        = "https://api.freestate.cloud/v1/state/myapp-prod"
    lock_address   = "https://api.freestate.cloud/v1/state/myapp-prod/lock"
    unlock_address = "https://api.freestate.cloud/v1/state/myapp-prod/lock"
    username       = "prod-user@example.com"
    password       = "fs_api_prod_key_here"
  }
}

Using Environment Variables

For better security, avoid hardcoding credentials in your Terraform files. Instead, use environment variables:

# backend.tf - Using environment variables
terraform {
  backend "http" {
    address        = "https://api.freestate.cloud/v1/state/myapp-prod"
    lock_address   = "https://api.freestate.cloud/v1/state/myapp-prod/lock"
    unlock_address = "https://api.freestate.cloud/v1/state/myapp-prod/lock"
    # username and password will be read from environment variables:
    # TF_HTTP_USERNAME and TF_HTTP_PASSWORD
  }
}

Set the environment variables before running Terraform:

# Linux/macOS
export TF_HTTP_USERNAME="your-email@example.com"
export TF_HTTP_PASSWORD="fs_api_your_key_here"

# Windows (PowerShell)
$env:TF_HTTP_USERNAME="your-email@example.com"
$env:TF_HTTP_PASSWORD="fs_api_your_key_here"

# Windows (Command Prompt)
set TF_HTTP_USERNAME=your-email@example.com
set TF_HTTP_PASSWORD=fs_api_your_key_here

CI/CD Configuration

When using FreeState in CI/CD pipelines, environment variables are the preferred method. Here are examples for popular CI/CD platforms:

GitHub Actions

# .github/workflows/terraform.yml
name: Terraform

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  terraform:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Terraform
      uses: hashicorp/setup-terraform@v2
      with:
        terraform_version: 1.0.0
    
    - name: Terraform Init
      run: terraform init
      env:
        TF_HTTP_USERNAME: \${{ secrets.FREESTATE_USERNAME}}
        TF_HTTP_PASSWORD: \${{ secrets.FREESTATE_API_KEY}}
    
    - name: Terraform Plan
      run: terraform plan
      env:
        TF_HTTP_USERNAME: \${{ secrets.FREESTATE_USERNAME}}
        TF_HTTP_PASSWORD: \${{ secrets.FREESTATE_API_KEY}}

GitLab CI

# .gitlab-ci.yml
stages:
  - plan
  - apply

variables:
  TF_ROOT: ${CI_PROJECT_DIR}
  TF_HTTP_USERNAME: ${FREESTATE_USERNAME}
  TF_HTTP_PASSWORD: ${FREESTATE_API_KEY}

before_script:
  - cd ${TF_ROOT}
  - terraform --version
  - terraform init

plan:
  stage: plan
  script:
    - terraform plan -out=plan.out
  artifacts:
    paths:
      - ${TF_ROOT}/plan.out

apply:
  stage: apply
  script:
    - terraform apply -auto-approve plan.out
  dependencies:
    - plan
  only:
    - main

Multi-Region Setup

For multi-region deployments, use separate workspaces for each region:

# us-east-1/backend.tf
terraform {
  backend "http" {
    address        = "https://api.freestate.cloud/v1/state/myapp-us-east-1"
    lock_address   = "https://api.freestate.cloud/v1/state/myapp-us-east-1/lock"
    unlock_address = "https://api.freestate.cloud/v1/state/myapp-us-east-1/lock"
  }
}

# us-west-2/backend.tf
terraform {
  backend "http" {
    address        = "https://api.freestate.cloud/v1/state/myapp-us-west-2"
    lock_address   = "https://api.freestate.cloud/v1/state/myapp-us-west-2/lock"
    unlock_address = "https://api.freestate.cloud/v1/state/myapp-us-west-2/lock"
  }
}

# eu-west-1/backend.tf
terraform {
  backend "http" {
    address        = "https://api.freestate.cloud/v1/state/myapp-eu-west-1"
    lock_address   = "https://api.freestate.cloud/v1/state/myapp-eu-west-1/lock"
    unlock_address = "https://api.freestate.cloud/v1/state/myapp-eu-west-1/lock"
  }
}

Backend Configuration with Terraform Cloud

If you're migrating from Terraform Cloud, you can easily switch to FreeState while keeping your existing workflow:

# Replace this Terraform Cloud backend:
terraform {
  cloud {
    organization = "my-org"
    workspaces {
      name = "my-workspace"
    }
  }
}

# With this FreeState backend:
terraform {
  backend "http" {
    address        = "https://api.freestate.cloud/v1/state/my-org-my-workspace"
    lock_address   = "https://api.freestate.cloud/v1/state/my-org-my-workspace/lock"
    unlock_address = "https://api.freestate.cloud/v1/state/my-org-my-workspace/lock"
  }
}

Initialization Commands

Common commands for initializing and migrating your Terraform backend:

# Initialize a new backend
terraform init

# Migrate from existing backend (interactive)
terraform init -migrate-state

# Migrate from existing backend (automatic)
terraform init -migrate-state -force-copy

# Reconfigure backend without migration
terraform init -reconfigure

# Upgrade backend configuration
terraform init -upgrade

Pro Tip

Use descriptive workspace names that include your environment and application name. This makes it easier to manage multiple projects and environments in your FreeState dashboard.

Troubleshooting

Common issues and solutions:

Authentication Errors

Error: "401 Unauthorized"
Solution: Check your username and API key. Ensure your API key is active and has the correct permissions.

Workspace Not Found

Error: "404 Not Found"
Solution: The workspace will be created automatically on first use. If you're still getting this error, check the workspace name in your configuration.

State Lock Issues

Error: "State is locked"
Solution: Use terraform force-unlock LOCK_ID with the lock ID from the error message.

Next Steps