{"id":29829739,"url":"https://github.com/hashicorp/terraform-migrate-utility","last_synced_at":"2025-10-10T21:14:56.332Z","repository":{"id":306262359,"uuid":"1025093669","full_name":"hashicorp/terraform-migrate-utility","owner":"hashicorp","description":"A helper library for terraform migrate CLI and provider","archived":false,"fork":false,"pushed_at":"2025-07-24T13:44:43.000Z","size":108,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-24T17:56:41.202Z","etag":null,"topics":["doormat-managed"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hashicorp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-23T17:57:48.000Z","updated_at":"2025-07-24T13:59:53.000Z","dependencies_parsed_at":"2025-07-24T17:56:48.628Z","dependency_job_id":null,"html_url":"https://github.com/hashicorp/terraform-migrate-utility","commit_stats":null,"previous_names":["hashicorp/terraform-migrate-utility"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/hashicorp/terraform-migrate-utility","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashicorp%2Fterraform-migrate-utility","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashicorp%2Fterraform-migrate-utility/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashicorp%2Fterraform-migrate-utility/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashicorp%2Fterraform-migrate-utility/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hashicorp","download_url":"https://codeload.github.com/hashicorp/terraform-migrate-utility/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashicorp%2Fterraform-migrate-utility/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267660013,"owners_count":24123657,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["doormat-managed"],"created_at":"2025-07-29T09:04:58.759Z","updated_at":"2025-10-10T21:14:56.280Z","avatar_url":"https://github.com/hashicorp.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Terraform Migrate Utility\n\nA Go library and utility for migrating Terraform state files to Terraform Stacks using HashiCorp's Terraform RPC API.\n\n## Overview\n\nThis utility provides a Go-based interface to migrate traditional Terraform configurations and state files to the new Terraform Stacks format. It leverages Terraform's gRPC-based RPC API to perform the migration operations safely and efficiently.\n\n## Features\n\n- **State Migration**: Migrate existing Terraform state files to Terraform Stacks format\n- **Configuration Handling**: Process Terraform modules, dependencies, and provider configurations\n- **gRPC Integration**: Uses Terraform's official RPC API for reliable operations\n- **Resource Mapping**: Supports custom resource and module address mapping during migration\n- **Provider Cache Management**: Handles provider plugin caches and dependency locks\n\n## Requirements\n\n- Go 1.24.5 or later\n- Terraform CLI with RPC API support\n- Compatible Terraform version (refer to [Terraform Stacks requirements](https://hashi.co/tfstacks-requirements))\n\n## Installation\n\n```bash\ngo get github.com/hashicorp/terraform-migrate-utility\n```\n\n## Usage\n\n### Example of migrating a Terraform state file to Stacks format:\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"io\"\n    \"os\"\n    \"path/filepath\"\n    \"github.com/hashicorp/terraform-migrate-utility/rpcapi\"\n    \"github.com/hashicorp/terraform-migrate-utility/rpcapi/terraform1/stacks\"\n    \"github.com/hashicorp/terraform-migrate-utility/rpcapi/tfstacksagent1\"\n    stateOps \"github.com/hashicorp/terraform-migrate-utility/stateops\"\n\n    _ \"github.com/hashicorp/terraform-migrate-utility/rpcapi/tfstackdata1\"\n\n    \"google.golang.org/protobuf/encoding/protojson\"\n)\n\nvar (\n    jsonOpts = protojson.MarshalOptions{\n        Multiline: true,\n    }\n)\n\nfunc main() {\n    ctx := context.Background()\n\n    // Connect to Terraform RPC API\n    client, err := rpcapi.Connect(ctx)\n    if err != nil {\n        fmt.Println(\"Error connecting to RPC API:\", err)\n        return\n    }\n    defer client.Stop()\n\n    // Create state operations handler\n    r := stateOps.NewTFStateOperations(ctx, client)\n\n    // Define paths (adjust these to your project structure)\n    workspaceDir := \"/path/to/your/terraform/workspace\"\n    stackConfigDir := \"/path/to/your/stack/config\"\n\n    // Open Terraform state from workspace directory\n    tfStateHandle, closeTFState, err := r.OpenTerraformState(workspaceDir)\n    if err != nil {\n        fmt.Println(\"Error opening Terraform state:\", err)\n        return\n    }\n    defer closeTFState()\n\n    // Open source bundle (modules directory)\n    sourceBundleHandle, closeSourceBundle, err := r.OpenSourceBundle(filepath.Join(workspaceDir, \".terraform/modules/\"))\n    if err != nil {\n        fmt.Println(\"Error opening source bundle:\", err)\n        return\n    }\n    defer closeSourceBundle()\n\n    // Open stack configuration (relative path from current working directory)\n    cwd, _ := os.Getwd()\n    relStackPath, _ := filepath.Rel(cwd, stackConfigDir)\n    stackConfigHandle, closeConfig, err := r.OpenStacksConfiguration(sourceBundleHandle, relStackPath)\n    if err != nil {\n        fmt.Println(\"Error opening stacks configuration:\", err)\n        return\n    }\n    defer closeConfig()\n\n    // Open dependency lock file (relative path from current working directory)\n    lockFilePath := filepath.Join(workspaceDir, \".terraform.lock.hcl\")\n    relLockPath, _ := filepath.Rel(cwd, lockFilePath)\n    dependencyLocksHandle, closeLock, err := r.OpenDependencyLockFile(sourceBundleHandle, relLockPath)\n    if err != nil {\n        fmt.Println(\"Error opening dependency lock file:\", err)\n        return\n    }\n    defer closeLock()\n\n    // Open provider cache\n    providerCacheHandle, closeProviderCache, err := r.OpenProviderCache(filepath.Join(workspaceDir, \".terraform/providers\"))\n    if err != nil {\n        fmt.Println(\"Error opening provider cache:\", err)\n        return\n    }\n    defer closeProviderCache()\n\n    // Perform migration with custom mappings\n    events, err := r.MigrateTFState(\n        tfStateHandle,\n        stackConfigHandle,\n        dependencyLocksHandle,\n        providerCacheHandle,\n        map[string]string{}, // Resource mappings (empty in this example)\n        map[string]string{   // Module mappings\n            \"random_number\":   \"triage-min\",\n            \"random_number_2\": \"triage-max\",\n        },\n    )\n    if err != nil {\n        fmt.Println(\"Error migrating Terraform state:\", err)\n        return\n    }\n\n    stackState := \u0026tfstacksagent1.StackState{\n\t\tFormatVersion: 1,\n\t\tRaw:           make(map[string]*anypb.Any),\n\t\tDescriptions:  make(map[string]*stacks.AppliedChange_ChangeDescription),\n\t}\n\n    // Process migration events\n    for {\n        item, err := events.Recv()\n        if err == io.EOF {\n            break \n        } else if err != nil {\n            fmt.Println(\"Error receiving migration events:\", err)\n            return\n        }\n\n        // Handle different event types\n        switch result := item.Result.(type) {\n        case *stacks.MigrateTerraformState_Event_AppliedChange:\n            for _, raw := range result.AppliedChange.Raw {\n\t\t\t\tstackState.Raw[raw.Key] = raw.Value\n\t\t\t}\n\n\t\t\tfor _, change := range result.AppliedChange.Descriptions {\n\t\t\t\tstackState.Descriptions[change.Key] = change\n\t\t\t}\n        case *stacks.MigrateTerraformState_Event_Diagnostic:\n            fmt.Println(\"Diagnostic:\", result.Diagnostic.Detail)\n        default:\n            fmt.Printf(\"Received event: %T\\n\", result)\n        }\n    }\n\n    fmt.Println(jsonOpts.Format(stackState))\n    fmt.Println(\"Migration completed successfully!\")\n}\n```\n\n### Example use of `TfWorkspaceStateUtility` Interface:\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"terraform-migrate-utility/tfstateutil\"\n)\n\nconst (\n\tstackSourceBundleAbsPath  = \"/Users/sujaysamanta/Workspace/Codebase/terraform-migrate-utility/terraform-no-mod-v1/modularized_config/_stacks_generated\"\n\tterraformConfigDirAbsPath = \"/Users/sujaysamanta/Workspace/Codebase/terraform-migrate-utility/terraform-no-mod-v1/modularized_config\"\n)\n\nfunc main() {\n\tvar err error\n\tctx := context.Background()\n\ttfStateUtil := stateUtil.NewTfWorkspaceStateUtility(ctx)\n\n\t// Read all resources from the Terraform state file\n\tresources, err := listAllResourcesFromWorkspaceStateExample(tfStateUtil, terraformConfigDirAbsPath)\n\tif err != nil {\n\t\tpanic(\"Failed to list all resources from workspace state: \" + err.Error())\n\t} else {\n\t\tfmt.Println(\"Resources in the Terraform state:\")\n\t\tfor _, resource := range resources {\n\t\t\tfmt.Println(resource)\n\t\t}\n\t\tfmt.Println()\n\t}\n\n\t// Check if the resources are fully modular\n\tstateFullyModular := isFullyModularExample(tfStateUtil, resources)\n\tif stateFullyModular {\n\t\tfmt.Println(\"The Terraform state is fully modular.\")\n\t\tfmt.Println()\n\t} else {\n\t\tfmt.Println(\"The Terraform state is not fully modular.\")\n\t\tfmt.Println()\n\t}\n\n\t// Create a map of workspace to stack address\n\tworkspaceToStackMap, err := workspaceToStackAddressMapExample(tfStateUtil, terraformConfigDirAbsPath, stackSourceBundleAbsPath)\n\tif err != nil {\n\t\tpanic(\"Failed to create workspace to stack address map: \" + err.Error())\n\t} else {\n\t\tfmt.Println(\"Workspace to Stack Address Map:\")\n\t\tindent, _ := json.MarshalIndent(workspaceToStackMap, \"\", \"  \")\n\t\tfmt.Println(string(indent))\n\t\tfmt.Println()\n\t}\n}\n\n\nfunc listAllResourcesFromWorkspaceStateExample(tfStateUtil stateUtil.TfWorkspaceStateUtility, workingDir string) ([]string, error) {\n\treturn tfStateUtil.ListAllResourcesFromWorkspaceState(workingDir)\n}\n\nfunc isFullyModularExample(tfStateUtil stateUtil.TfWorkspaceStateUtility, resources []string) bool {\n\treturn tfStateUtil.IsFullyModular(resources)\n}\n\nfunc workspaceToStackAddressMapExample(tfStateUtil stateUtil.TfWorkspaceStateUtility, terraformConfigFilesAbsPath string, stackSourceBundleAbsPath string) (map[string]string, error) {\n\treturn tfStateUtil.WorkspaceToStackAddressMap(terraformConfigFilesAbsPath, stackSourceBundleAbsPath)\n}\n```\n\n\n## Contributing\n\nThis project follows HashiCorp's contribution guidelines. Please ensure:\n\n1. Code follows Go best practices\n2. All changes include appropriate tests\n3. Documentation is updated for API changes\n4. Protobuf changes are properly generated\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashicorp%2Fterraform-migrate-utility","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhashicorp%2Fterraform-migrate-utility","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashicorp%2Fterraform-migrate-utility/lists"}