Migrating Terraform state from one backend to another
Terraform state management accept an easy migration from one backend to another,
either this backend is remote or local. It detects the actual change on the
object backend
within the context terraform
and apply the proper changes to
execute the migration.
Within a repository with an already initialized state, run the following:
terraform init -migrate-state
Example migration to Gitlab
When not defining a backend, Terraform use a local backend by default, to
migrate to Gitlab just create a backend.tf
file with the following:
terraform {
backend "http" {
}
}
Below a more complex example migrating a state file from a local machine to
Gitlab using glab
. Before running it configure glab
to properly point to your
Gitlab instance, it assumes that the username of the user in the current machine
is the same on the Gitlab (result of whoami
), and that the variable
GITLAB_ACCESS_TOKEN
has a valid token.
export TF_STATE_NAME=default
export GITLAB_HOST="$(glab config get host)"
export PROJECT_ID="$(glab api projects/:fullpath/ | jq '.id')"
export PROJECT_URL="https://${GITLAB_HOST}/api/v4/projects/${PROJECT_ID}"
export BASE_URL="${PROJECT_URL}/terraform/state/${TF_STATE_NAME}"
terraform init -migrate-state\
-backend-config="address=${BASE_URL}" \
-backend-config="lock_address=${BASE_URL}/lock" \
-backend-config="unlock_address=${BASE_URL}/lock" \
-backend-config="username=$(whoami)" \
-backend-config="password=$GITLAB_ACCESS_TOKEN" \
-backend-config="lock_method=POST" \
-backend-config="unlock_method=DELETE" \
-backend-config="retry_wait_min=5"
The following is the output of the command above if is successful:
Initializing the backend... Do you want to copy existing state to the new backend? Pre-existing state was found while migrating the previous "local" backend to the newly configured "http" backend. No existing state was found in the newly configured "http" backend. Do you want to copy this state to the new "http" backend? Enter "yes" to copy and "no" to start with an empty state. Enter a value: yes Successfully configured the backend "http"! Terraform will automatically use this backend unless the backend configuration changes. Initializing provider plugins... - Reusing previous version of telmate/proxmox from the dependency lock file - Using previously-installed telmate/proxmox v3.0.1-rc4 Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.
Appendix
The script for migrating to Gitlab above wrapped in a nice function:
function terraform-state-migrate-to-gitlab() {
local TF_STATE_NAME=default
local GITLAB_HOST="$(glab config get host)"
local PROJECT_ID="$(glab api projects/:fullpath/ | jq '.id')"
local PROJECT_URL="https://${GITLAB_HOST}/api/v4/projects/${PROJECT_ID}"
local BASE_URL="${PROJECT_URL}/terraform/state/${TF_STATE_NAME}"
terraform init -migrate-state\
-backend-config="address=${BASE_URL}" \
-backend-config="lock_address=${BASE_URL}/lock" \
-backend-config="unlock_address=${BASE_URL}/lock" \
-backend-config="username=$(whoami)" \
-backend-config="password=$GITLAB_ACCESS_TOKEN" \
-backend-config="lock_method=POST" \
-backend-config="unlock_method=DELETE" \
-backend-config="retry_wait_min=5"
}