Automate Terraform Enterprise with APIs (Part 1 — State Download)

Terraform Enterprise is a powerful tool for infrastructure as code (IaC), enabling organizations to provision, manage, and version their infrastructure in a consistent and automated way. One of the most exciting aspects of Terraform Enterprise is its robust API support, allowing you to automate various tasks that would otherwise require manual intervention. In this blog post, we’ll explore how to harness the power of Terraform Enterprise APIs for automation.

Getting Started with the Terraform Enterprise API

Authentication

To interact with the Terraform Enterprise API, you’ll need an API token. This token grants access to the resources and actions available within your Terraform Enterprise organization. You can create an API token in your user settings:

  1. Log in to Terraform Enterprise.
  2. Go to User Settings > Tokens.
  3. Create a new API token and store it securely.

With the token in hand, you can authenticate API requests by including it in the Authorization header like so:

Authorization: Bearer <your-api-token>

Start Simple

How to Download the State File Using curl

To download the state file, you’ll need to:

Obtain the workspace ID: Every workspace in Terraform Enterprise has a unique ID. You can retrieve this by querying the list of workspaces for your organization or copy from the workspace console UI

Get the current state version: The state file is associated with a specific version, and you need to know the latest state version to download it.

curl --request GET \
--header "Authorization: Bearer <your-api-token>" \
--header "Content-Type: application/vnd.api+json" \
https://<HOST_NAME>/api/v2/workspaces/<workspace-id>/current-state-version

Download the state file: Once you have the state version, you can download the state file.

#!/bin/bash
# Set variables
HOST_NAME="<terraform-enterprise-hostname>" # Example: app.terraform.io
ORG_NAME="<organization-name>"
WORKSPACE_ID="<workspace-id>"
API_TOKEN="<your-api-token>"
# Get the current state version download URL
DOWNLOAD_URL=$(curl --silent \
--header "Authorization: Bearer $API_TOKEN" \
--header "Content-Type: application/vnd.api+json" \
"https://$HOST_NAME/api/v2/workspaces/$WORKSPACE_ID/current-state-version" | \
jq -r '.data.attributes."download-url"')
# Download the state file
curl --request GET \
--header "Authorization: Bearer $API_TOKEN" \
"$DOWNLOAD_URL" --output terraform.tfstate
echo "State file downloaded successfully as terraform.tfstate"
  • Replace <terraform-enterprise-hostname>, <organization-name>, <workspace-id>, and <your-api-token> with actual values.

For a single workspace this should help. What if I have a list of workspaces. How do I download state for all those workspaces

  • Option 1: Create a list of workspaces inside the script at loop over it
#!/bin/bash
# Set variables
HOST_NAME="<terraform-enterprise-hostname>" # Example: app.terraform.io
API_TOKEN="<your-api-token>"
# List of workspace IDs (space-separated)
WORKSPACE_IDS=("workspace-id-1" "workspace-id-2" "workspace-id-3")
# Loop through each workspace ID and download the state file
for WORKSPACE_ID in "${WORKSPACE_IDS[@]}"; do
echo "Downloading state file for workspace ID: $WORKSPACE_ID"
# Get the current state version download URL
DOWNLOAD_URL=$(curl --silent \
--header "Authorization: Bearer $API_TOKEN" \
--header "Content-Type: application/vnd.api+json" \
"https://$HOST_NAME/api/v2/workspaces/$WORKSPACE_ID/current-state-version" | \
jq -r '.data.attributes."download-url"')
# Check if the download URL was retrieved successfully
if [[ -z "$DOWNLOAD_URL" || "$DOWNLOAD_URL" == "null" ]]; then
echo "Failed to retrieve the state file for workspace ID: $WORKSPACE_ID"
continue
fi
# Download the state file
OUTPUT_FILE="terraform_$WORKSPACE_ID.tfstate"
curl --request GET \
--header "Authorization: Bearer $API_TOKEN" \
"$DOWNLOAD_URL" --output "$OUTPUT_FILE"
echo "State file downloaded successfully for workspace ID: $WORKSPACE_ID as $OUTPUT_FILE"
done
echo "All specified workspaces have been processed."
  • Option 2: Make the script to accept the workspace id as a command line argument. we’ll modify the script to accept a WORKSPACE_ID as a command-line argument and use a list.txt file containing the list of workspace IDs. This allows you to run the script for each workspace ID provided by xargs.

Steps

  • Create list.txt: This file should contain a list of workspace IDs, one per line.
workspace-id-1
workspace-id-2
workspace-id-3
  • Modify the script: Update the script to accept the WORKSPACE_ID as a command-line argument.
#!/bin/bash
# Check if the workspace ID is provided
if [ -z "$1" ]; then
echo "Usage: $0 <workspace-id>"
exit 1
fi
# Set variables
HOST_NAME="<terraform-enterprise-hostname>" # Example: app.terraform.io
API_TOKEN="<your-api-token>"
WORKSPACE_ID="$1"
# Get the current state version download URL
DOWNLOAD_URL=$(curl --silent \
--header "Authorization: Bearer $API_TOKEN" \
--header "Content-Type: application/vnd.api+json" \
"https://$HOST_NAME/api/v2/workspaces/$WORKSPACE_ID/current-state-version" | \
jq -r '.data.attributes."download-url"')
# Check if the download URL was retrieved successfully
if [[ -z "$DOWNLOAD_URL" || "$DOWNLOAD_URL" == "null" ]]; then
echo "Failed to retrieve the state file for workspace ID: $WORKSPACE_ID"
exit 1
fi
# Download the state file
OUTPUT_FILE="terraform_$WORKSPACE_ID.tfstate"
curl --request GET \
--header "Authorization: Bearer $API_TOKEN" \
"$DOWNLOAD_URL" --output "$OUTPUT_FILE"
echo "State file downloaded successfully for workspace ID: $WORKSPACE_ID as $OUTPUT_FILE"

Use xargs to run the script for each workspace ID:

xargs -a list.txt -I {} ./download_state.sh {}

Wrapping Up

This post introduced basic automation with the Terraform Enterprise API, showing how to download state files for one or more workspaces. These techniques lay the groundwork for more advanced automation tasks.

Stay tuned for more in this Terraform Enterprise API series, where we’ll cover topics like workspace management, run automation, and system integration.

Feel free to share your thoughts or request specific topics for future posts in the comments!

Learn more Automate Terraform Enterprise with APIs (Part 1 — State Download)

Leave a Reply