Version remote state with the HCP Terraform API
The Terraform state file is the source of truth for your infrastructure. Protecting and backing up this file is critical for practitioners who use Terraform in production. Remote state storage with HCP Terraform offers fail-safes for your infrastructure in the event of disaster-recovery situations and local file corruption. Although Terraform takes steps to prevent state errors, your state file can get corrupted due to partial apply operations or incorrectly running terraform import
or terraform taint
. Using the HCP Terraform API, you can safely download, modify, and upload your state file to an HCP Terraform workspace.
In this tutorial, you will generate a state file by deploying an AWS instance with web access using the Terraform CLI. Then, you will download your remote state file and use the Terraform API to create a new state version.
Prerequisites
For this tutorial you will need:
- The Terraform CLI 0.15.0+ installed locally.
- Access to HCP Terraform or Enterprise.
- An AWS account with credentials configured for Terraform.
- The
awscli
configured. jq
installed.
Note
Windows users must install Windows Subsystem for Linux and start this tutorial in the Linux terminal.
Clone the example configuration
Clone the example GitHub repository.
Change into the repository directory.
Open the main.tf
file to review the configuration. The main resources in this configuration are an AWS EC2 instance and a security group with port 8080 access.
First, update your configuration with your HCP Terraform information. Update <YOUR-ORGANIZATION-NAME>
with your HCP Terraform organization name.
Note
Because the cloud
block is not supported by older versions of Terraform, you must use 1.1.0 or higher in order to follow this tutorial. Previous versions can use the remote
backend block to configure the CLI workflow and migrate state.
Save your changes.
Run the terraform login
subcommand, and follow the prompts to authenticate to HCP Terraform.
For more detailed instructions on logging in, reference the Authenticate the CLI with HCP Terraform tutorial.
After authenticating, initialize your Terraform configuration.
Add AWS credentials to workspace variables
Navigate to your HCP Terraform state-versioning
workspace. Click on "Variables" and add your region
variable as a Terraform variable. Add your AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
variables as environment variables. Be sure to mark the AWS credentials environment variables as sensitive
Note
The AWS_SESSION_TOKEN
is optional unless your organization requires it.
Apply your configuration
In your terminal, apply your configuration. Enter yes
when prompted to confirm your changes.
Verify that your state file contains your resources using terraform state list
command.
In the next section, you will configure your HCP Terraform workspace.
Configure the HCP Terraform workspace
You will need your workspace ID and a new HCP Terraform API token to access your workspace's state file.
Retrieve workspace ID
In HCP Terraform, navigate to your new workspace.
In your state-versioning
workspace, navigate to "Settings" then "General" and copy your workspace ID.
Create a workspace ID environment variable in your terminal, replacing <YOUR-WORKSPACE-ID>
with the workspace ID you just copied.
Retrieve HCP Terraform API token
Create a new user token by clicking the icon for your user in the top right corner, then "User settings", then "Tokens". Select "Create an API token".
Name your token "state-versioning" then select "Create API token".
Copy the API token.
Create an environment variable with your token, replacing <YOUR-TFC-TOKEN>
with the token you just copied.
Lock your workspace
Click on the lock icon to lock your workspace. Locking your workspace prevents other operations from running and potentially corrupting the state file you are going to download. Your workspace needs to be locked before you can push a new state file via API. You must lock the workspace as the same user you generated the HCP Terraform token for in the previous step.
Edit configuration tags
Run the AWS CLI to add the Org
tag to your EC2 resource. Your state file does not have a record of this value.
It may take a few minutes to update your instance.
Your new Org
tag is HashiCorp
in AWS while your Terraform state file is not aware of this change.
Later in this tutorial, you will reconcile this difference with the Terraform state.
Download the state file
In your terminal, navigate to the helper_scripts
folder.
The shell scripts in this directory construct your API queries, download your remote state file for editing, and create a payload for uploading your changes.
Open the getstate.sh
file to review the API query.
If you are using Terraform Enterprise, change the URL from app.terraform.io
to your personalized Terraform Enterprise domain.
This snippet uses your environment variables and authenticates to your HCP Terraform workspace to download the current remote state file. The hosted-state-download-url
contains the URL that hosts your remote state file.
In your terminal, run the getstate.sh
script.
Verify your query downloaded the state file and open state.tfstate
.
Modify and create the state payload
Warning
We discourage directly editing state files. In production environments, you should only use this method as a last resort.
Now that you have the remote state downloaded, open the state.tfstate
file in your file editor. Increment your serial
number by one then save the file.
This is your new state version number. Terraform uses the serial
to keep track of the changes made in each new state file and uses it to make sure your operations run against the correct known state file in the HCP Terraform workspace. In standard operations, Terraform updates the serial
for you automatically. However, since you're pushing a new state version, you need to manually increment this value.
Edit your instance tags to include the new Org
tag. Search for terraform-learn-state-versioning
in the state.tfstate
file. Add a comma at the end of the Name
tag. Terraform parses the JSON-formatting state file and adds elements to your resource records.
Save your file.
Now, you will construct your current state payload. Select the tab for your operating system for specific instructions.
In your helper_scripts
folder, open the createpayload.sh
file.
This snippet finds the serial
and lineage
values in your state.tfstate
file and creates an MD5 signature for your state file with a base64 encoded version of your state. Then, this script passes those values to a new file named payload.json
. You will upload this file to your HCP Terraform workspace with the TFC API in the next step.
Run the createpayload.sh
script.
Open payload.json
to verify the script successfully created your payload.
Upload the new state file to HCP Terraform
Now that you have a JSON payload with your encrypted state file, upload the new state file to HCP Terraform.
In your helper_scripts
directory, open the uploadstate.sh
file.
Tip
If you are using Terraform Enterprise, change the URL from app.terraform.io
to your personalized Terraform Enterprise domain.
This API query uses the --data
flag to upload the payload.json
file to your workspace.
Run the uploadstate.sh
script.
In your HCP Terraform workspace, navigate to your "States" tab and select the most recent state.
In the "Changes in this version" section, confirm your new state file contains a new serial number and tag reference.
Unlock your workspace by clicking on the lock icon and confirming the unlock.
Update your configuration
Because you updated your resource outside of the Terraform workflow with an additional tag, you must update the configuration with the updated resource and run a terraform apply
to maintain parity with your state file. Terraform will perform the apply, but will not make any resource changes. This is a "no-operation" or "no-op" apply.
Change into the root directory.
Open the main.tf
file and update your instance tag.
Run terraform apply
to consolidate your configuration with your remote state. This is a "no-op" apply.
Now that your modified state file matches your infrastructure and configuration, delete the local version of your state file.
Your payload.json
file also contains an encrypted version of your state. Delete your payload.json
file.
Destroy your infrastructure
In HCP Terraform, destroy your remote workspace.
Navigate to "Settings" > "Destruction and Deletion".
At the bottom of the page, select "Queue Destroy Plan" and confirm.
Next, delete your workspace from HCP Terraform. At the bottom of the page, select "Delete workspace" and confirm.
Next steps
In this tutorial, you learned how to use the HCP Terraform API to interact with and update your HCP Terraform workspace's state. First, you created infrastructure in HCP Terraform. Then, you downloaded your current HCP Terraform state file and safely modified and versioned your state file. Finally, you uploaded your versioned and updated state file to HCP Terraform.
For more information about the HCP Terraform API or Terraform state, review the following resources:
- HCP Terraform API documentation.
- HCP Terraform Fundamentals tutorials.
- Terraform State tutorials.