Skip to content

Repository files navigation

TFC to Scalr Migration Overview

This script will migrate the following objects from TFC to Scalr in bulk:

  • Workspaces with all attributes
    • VCS settings and trigger patterns
    • Terraform version
    • Execution mode (remote/local)
    • Working directory
    • Auto-apply settings
    • Remote state sharing
    • Variable values (including sensitive variables when available)
    • Workspace dependencies
  • State file migration
    • Preserves state history
  • Variable migration (including sensitive variables from plan files)
  • Variable set migration
    • Variable set variables (including sensitive values recovery)
    • Non-global variable set workspace links and environment access updates
    • Only TFC variable sets in scope for this run are migrated: global sets, sets linked to --tfc-project (when set), and sets linked to workspaces in scope for this run (workspace name patterns). TFC-global sets become Scalr shared (is-shared) variable sets with no explicit environment relationships; non-global sets get environment access merged by name across reruns.
  • VCS provider configuration
  • Provider configuration linking
  • Remote state consumers
  • Trigger patterns handling
  • Workspace locking in TFC/E after migration to avoid conflicting runs

At the end of the migration, the Scalr Terraform provider code will be generated, allowing you to continue managing Scalr objects with code. A Scalr management environment and workspace will be created for managing Scalr environments and workspaces.

Usage

Prerequisites

Cross-Platform Compatibility

This migration tool is designed to work seamlessly across different operating systems and environments:

Supported Platforms

  • Linux/macOS: Native bash environments
  • Windows: Git Bash, WSL (Windows Subsystem for Linux), Cygwin, MSYS2

Automatic Detection

  • Python: Automatically detects and uses the best available Python 3.x installation
  • Operating System: Automatically adapts paths and commands based on the detected platform
  • Virtual Environment: Handles activation scripts for both Windows and Unix-like systems
  • Home Directory: Cross-platform detection for credential file locations

Dependencies

  • jq: Optional for reading Terraform credentials file (graceful fallback if not available)
  • bash: Required shell environment (available on all supported platforms)

Installation

  1. Clone this repository:
git clone https://github.com/your-org/terraform-scalr-migrate-tfc.git
cd terraform-scalr-migrate-tfc
  1. Make the scripts executable:
chmod +x migrate.sh

Authentication

Authentication can be provided in three ways. When the same value is set in more than one place, this order applies:

  1. Command-line arguments (highest priority)
  2. Environment variables
  3. ~/.terraform.d/credentials.tfrc.json (fallback when tokens are not set elsewhere)

Both --flag value and --flag=value formats are supported for all options (for example, --tfc-token "your-token" or --tfc-token=your-token).

Command line arguments:

./migrate.sh \
  --tfc-token "your-token" \
  --tfc-organization="my-org" \
  --scalr-hostname "account.scalr.io" \
  --scalr-token "your-token"

Inline values passed this way are always used, even if tokens for the same hostnames exist in the credentials file.

Environment variables:

export SCALR_HOSTNAME="account.scalr.io" # Replace `account` with the actual account name
export SCALR_TOKEN="your-token"
export TFC_TOKEN="your-token"

Environment variables are used when a value is not passed on the command line. They take precedence over the credentials file.

Terraform credentials file (~/.terraform.d/credentials.tfrc.json):

When tokens are not provided via the command line or environment variables, the migrator reads them from the locally cached credentials file (usually written by the terraform login command). The Scalr hostname must be known (via --scalr-hostname or SCALR_HOSTNAME) to look up the Scalr token.

{
  "credentials": {
    "account.scalr.io": {
      "token": "your-scalr-token"
    },
    "app.terraform.io": {
      "token": "your-tfc-token"
    }
  }
}

To use this auth method, run two commands first:

Cache TFC token:

terraform login

Cache Scalr token (replace account with the actual account name):

terraform login account.scalr.io

Execution

./migrate.sh --tfc-token "your-token" --tfc-organization="my-org" --scalr-hostname "your-account.scalr.io" --scalr-token "your-token"

Required Arguments

  • --scalr-hostname: Scalr hostname (e.g., myorg.scalr.io)
  • --scalr-token: Scalr API token
  • --tfc-hostname: TFC/E hostname (e.g., app.terraform.io)
  • --tfc-token: TFC/E API token
  • --tfc-organization: TFC/E organization name

Optional Arguments

  • -v|--vcs-name: VCS provider name in Scalr (required when any workspace in scope is VCS-driven; not checked at startup if omitted)
  • --scalr-environment: Scalr environment to create (default: --tfc-project if set, otherwise --tfc-organization)
  • --pc-name: Provider configuration name in Scalr to link to workspaces
  • --agent-pool-name: Agent pool name in Scalr to link to workspaces
  • -w|--workspaces: Workspace name pattern (supports shell-style wildcards, default: "*")
    • Examples: "prod-*" (starts with prod-), "*-staging" (ends with -staging), "test?" (test + any single char)
  • --skip-backend-secrets: Skip creation of shell variables for backend configuration
  • --skip-tfc-lock: Skip locking TFC/E workspaces after migration
  • --skip-post-migration: Skip post-migration Terraform/OpenTofu steps (fmt, init, apply)
  • --skip-variable-sets: Skip migration of TFC variable sets to Scalr (workspace-level variables are still migrated)
  • --migrate-variable-sets-only: Migrate only TFC variable sets. Workspaces, their state files and variables are not migrated; workspaces that already exist in the destination Scalr environment are reused to link non-global variable sets. Cannot be combined with --skip-variable-sets or --skip-variables="*". See Migrating variable sets separately.
  • --management-env-name: Name of the management environment (default: "scalr-admin")
  • --management-workspace-name: Name of the management workspace that holds the generated Terraform code (default: the --scalr-environment name; spaces are replaced with -)
  • --disable-deletion-protection: Disable deletion protection in workspace resources
  • --tfc-project: TFC project name to filter workspaces by
  • --skip-variables: Comma-separated list of variable key patterns to skip, or "*" to skip all variable migration (including variable sets)
  • --use-opentofu: Use OpenTofu for workspaces with Terraform version >= 1.6.0 instead of downgrading to 1.5.7
  • --opentofu-version: OpenTofu version to use when --use-opentofu is set (must be >= 1.6.0; default: latest active OpenTofu version in Scalr)
  • --credentials-set-name: Name of the TFC variable set the migrator creates for backend/credential secrets during sensitive environment variable migration (default: Scalr-Creds). This set is skipped when migrating variable sets to Scalr.

Migrating variable sets separately

The migration is idempotent, so variable sets and workspaces can be migrated in separate runs:

# 1st run: variable sets only
./migrate.sh --tfc-organization "my-org" --scalr-environment "my-env" --migrate-variable-sets-only

# 2nd run: workspaces (variable sets already exist and are updated in place and linked)
./migrate.sh --tfc-organization "my-org" --scalr-environment "my-env"

In --migrate-variable-sets-only mode:

  • TFC workspaces are still listed and filtered by --workspaces / --tfc-project to determine which variable sets are in scope, but no workspace, state file or workspace variable is migrated and no TFC workspace is locked.
  • Non-global variable sets are linked only to workspaces that already exist in the destination Scalr environment (from a previous run). Workspaces that do not exist yet are reported, and the links are created on the run that migrates them.
  • The management environment/workspace and the generated Terraform code are still created, unless --skip-post-migration is set.

Generated Files

The tool generates the following files in the generated-terraform/$SCALR_ENVIRONMENT directory so you can manage your workspaces with the Scalr Terraform provider:

  • main.tf: Contains all Terraform resources
  • backend.tf: Remote backend configuration
  • import_commands.sh: Script to import resources and push state

Post-Migration

After successful migration, the tool automatically runs the following steps (unless --skip-post-migration is specified):

  1. Navigate to the generated Terraform directory (generated-terraform/$SCALR_ENVIRONMENT)
  2. Run fmt to format the generated code
  3. Run init to initialize the workspace
  4. Run apply to import all previously created resources into the management workspace state file

By default these steps use the terraform CLI. When --use-opentofu is enabled, they use tofu instead (tofu fmt, tofu init, tofu apply).

To skip these automatic steps and run them manually, use the --skip-post-migration flag.

Limitations

  • By default, supports up to Terraform 1.5.7. If a higher version is used, the script will downgrade it to 1.5.7.
  • When --use-opentofu is enabled, workspaces with Terraform version >= 1.6.0 use OpenTofu (latest active version in Scalr, or the version from --opentofu-version) instead of downgrading. This requires Scalr to support OpenTofu.
  • State migration requires at least one state file in the source TFC/E workspace.
  • Sensitive terraform variables migration requires at least one plan file in the source TFC/E workspace.
  • Sensitive environment variables requires triggering of the remote run in a TFC/E workspace

Troubleshooting

  1. If you encounter authentication errors:

    • Verify your tokens are correct
    • Check that command-line tokens are not being overridden (CLI arguments take priority over the credentials file)
    • Check the credentials file format
    • Ensure you have the necessary permissions
  2. If state migration fails:

    • Check if the workspace has a valid state file
    • Ensure you have sufficient permissions in both platforms
  3. If workspace creation fails:

    • Verify the VCS provider is correctly configured
    • Check if the workspace name is available
    • Ensure you have sufficient permissions

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Commit your changes
  4. Push to the branch
  5. Create a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

5 stars

Watchers

15 watching

Forks

Releases

Packages

Used by

Contributors

Languages