State Migration

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

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

Rollback

If you need to revert to the old backend:

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

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

Troubleshooting

"Backend configuration changed"

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

"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