State Migration

This guide covers migrating existing Terraform state to Stategraph from other backends.

Before you begin: You need an API key to authenticate with Stategraph. In the Stategraph UI, go to Settings > API Keys and click Create API Key. You'll use this key in the steps below.

Overview

Terraform's built-in state migration handles the transfer. The process:

  1. Create a state in Stategraph (via API)
  2. Configure Stategraph as the new backend using the group_id
  3. Run terraform init
  4. Terraform detects the backend change and offers to migrate
  5. State is copied to Stategraph

Prerequisites

  • Stategraph CLI installed and configured
  • Terraform installed
  • Access to your existing state backend

Before migrating, create a state in Stategraph to get the group_id:

# Configure CLI and Terraform credentials
export TF_HTTP_USERNAME="session"
export TF_HTTP_PASSWORD="<your-api-key>"
export STATEGRAPH_API_BASE="http://stategraph:8080"
export STATEGRAPH_API_KEY="$TF_HTTP_PASSWORD"

# List your tenants to get your tenant ID
stategraph user tenants list

Output:

550e8400-e29b-41d4-a716-446655440000    my-org

Then create the state:

stategraph states create --tenant 550e8400-e29b-41d4-a716-446655440000 --name "my-project"

Copy the group_id from the response for the next steps.

From S3

Current Configuration

terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "prod/terraform.tfstate"
    region = "us-west-2"
  }
}

New Configuration

Replace the backend block with the group_id from the prerequisites:

terraform {
  backend "http" {
    address = "http://stategraph:8080/api/v1/states/backend/550e8400-e29b-41d4-a716-446655440000"
    # username and password from TF_HTTP_USERNAME and TF_HTTP_PASSWORD
  }
}

Migration Steps

terraform init -migrate-state

# Terraform will prompt:
# Do you want to copy existing state to the new backend?
# Enter "yes"

Verify Migration

# Verify state is accessible
terraform state list

# Run a plan to confirm no changes
terraform plan

From GCS

Current Configuration

terraform {
  backend "gcs" {
    bucket = "my-terraform-state"
    prefix = "prod"
  }
}

Migration

Follow the same process as S3:

terraform {
  backend "http" {
    address = "http://stategraph:8080/api/v1/states/backend/550e8400-e29b-41d4-a716-446655440000"
    # username and password from TF_HTTP_USERNAME and TF_HTTP_PASSWORD
  }
}
terraform init -migrate-state
# Answer "yes" to migrate

From Azure Blob Storage

Current Configuration

terraform {
  backend "azurerm" {
    storage_account_name = "mystorageaccount"
    container_name       = "terraform"
    key                  = "prod.tfstate"
  }
}

Migration

terraform {
  backend "http" {
    address = "http://stategraph:8080/api/v1/states/backend/550e8400-e29b-41d4-a716-446655440000"
    # username and password from TF_HTTP_USERNAME and TF_HTTP_PASSWORD
  }
}
terraform init -migrate-state
# Answer "yes" to migrate

From Terraform Cloud

Current Configuration

terraform {
  cloud {
    organization = "my-org"
    workspaces {
      name = "my-workspace"
    }
  }
}

Migration

Replace the cloud block with HTTP backend:

terraform {
  backend "http" {
    address = "http://stategraph:8080/api/v1/states/backend/550e8400-e29b-41d4-a716-446655440000"
    # username and password from TF_HTTP_USERNAME and TF_HTTP_PASSWORD
  }
}
terraform init -migrate-state
# Answer "yes" to migrate

From Local State

Current Configuration (implicit)

No backend block means local state in terraform.tfstate.

Migration

Add the HTTP backend:

terraform {
  backend "http" {
    address = "http://stategraph:8080/api/v1/states/backend/550e8400-e29b-41d4-a716-446655440000"
    # username and password from TF_HTTP_USERNAME and TF_HTTP_PASSWORD
  }
}
terraform init -migrate-state
# Answer "yes" to migrate

Verification Checklist

After migration, verify:

  • terraform state list shows all resources
  • terraform plan shows no changes
  • State appears in Stategraph UI
  • Resource count matches expectations
  • Dependencies are visible in graph view

Migrating Away from Stategraph

Stategraph is designed with zero vendor lock-in. You can export your state and migrate to any standard Terraform backend at any time.

Export Options

Option 1: Standard Backend Migration

The same process that migrated TO Stategraph works in reverse:

# Update your Terraform configuration to point to your target backend
terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "prod/terraform.tfstate"
    region = "us-west-2"
  }
}

# Migrate state back
terraform init -migrate-state
# Answer "yes" to migrate

Option 2: Export to Local File

You can export state to a standard .tfstate file:

# Pull current state
terraform state pull > terraform.tfstate

# Remove Stategraph backend from configuration
# Then run init with local backend
terraform init -reconfigure

# Verify the local state
terraform state list
terraform plan

Option 3: Direct PostgreSQL Export

Since Stategraph stores state in a documented PostgreSQL schema (not a proprietary format), you can also export directly from the database if needed. Contact support for schema documentation.

Migration Destinations

Stategraph state can be migrated to any standard Terraform backend:

  • Cloud Storage: S3, GCS, Azure Blob Storage
  • Terraform Cloud/Enterprise
  • Other HTTP Backends: Terraform's pg backend, Consul, etc.
  • Local Files: For development or archival

Verification After Export

After migrating away from Stategraph:

  • terraform state list shows all resources
  • terraform plan shows no changes
  • All resource attributes are intact
  • Dependencies are preserved
  • Test a small terraform apply to confirm functionality

Data Preservation Guarantee

When you migrate away from Stategraph:

  • All resource data is preserved (IDs, attributes, metadata)
  • Dependencies are maintained in standard Terraform format
  • Provider information is intact
  • Output values are preserved
  • Workspace data is fully exportable

Your infrastructure state belongs to you. We believe you should have complete freedom to move it wherever you want, whenever you want.

Rollback to Previous Backend

If you recently migrated TO Stategraph and want to revert:

  1. Change the backend configuration back to your previous backend
  2. Run terraform init -migrate-state
  3. Answer "yes" to migrate back

The state in Stategraph is preserved and can be re-migrated later if needed.

Troubleshooting

"Backend configuration changed"

This is expected - confirm the change by entering "yes".

401 Unauthorized

Your API key is missing or invalid. Make sure the environment variables are set before running terraform init:

export TF_HTTP_USERNAME="session"
export TF_HTTP_PASSWORD="<your-api-key>"

If you haven't created an API key yet, open Stategraph, go to Settings > API Keys, and click Create API Key.

"HTTP remote state endpoint requires auth"

This error occurs when migrating between two HTTP backends. Use -reconfigure to skip migration and start fresh with the new backend:

terraform init -reconfigure

Note: This does not migrate existing state. If you need to preserve state, first pull it locally with terraform state pull > backup.tfstate, then push after reconfiguring with terraform state push backup.tfstate.

"Error copying state"

Check:
- Network connectivity to Stategraph
- Valid API key
- Stategraph server is running

Large state files

For very large states (>100MB):
- Ensure STATEGRAPH_CLIENT_MAX_BODY_SIZE is set appropriately
- Check proxy/load balancer timeouts

Next Steps