Introduction
When you revoke the connection of your Version Control System (VCS) provider in Terraform Enterprise (TFE) or HCP Terraform, all workspaces using that provider lose their VCS configuration. You must then manually re-connect the VCS provider on each affected workspace.
This article provides a script to automate the process of updating workspaces with a new VCS provider connection.
Prerequisites
- The third-party command-line JSON processor
jqmust be installed on your system. You can download it from the official jq download page. - A Terraform API token with admin permissions for your TFE or HCP Terraform organization.
Procedure
Follow these steps to gather a list of workspaces, prepare a target list, and run the script to update their VCS connections.
1. Set Environment Variables
Before running the script, export the following environment variables. These are required by the script to authenticate and target the correct resources.
$ export TOKEN="<ORGANIZATION_TOKEN_OR_ADMIN_TOKEN>" $ export ORG_NAME="<YOUR_ORGANIZATION_NAME>" $ export HOSTNAME="<YOUR_TFE_HOSTNAME_OR_app.terraform.io>" $ export OAUTH_TOKEN="<VCS_PROVIDER_OAUTH_TOKEN_ID>"
-
TOKEN: An organization-level or admin user API token. -
ORG_NAME: The name of your organization in TFE or HCP Terraform. -
HOSTNAME: Your TFE instance hostname (e.g.,tfe.example.com) orapp.terraform.iofor HCP Terraform. -
OAUTH_TOKEN: The OAuth Token ID for the new VCS connection you want to use. You can find this in your organization's VCS provider settings.
2. Generate a List of Workspaces
Run the following curl command to retrieve all workspaces in your organization and save their name and repository identifier to a file named output.json.
$ curl --header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
"https://$HOSTNAME/api/v2/organizations/$ORG_NAME/workspaces?page%5Bnumber%5D=1&page%5Bsize%5D=100" | \
jq -r '[.data[].attributes | {workspace: .name, repo: ."vcs-repo"."display-identifier"}]' > output.jsonNote: The API returns a maximum of 100 workspaces per page. If you have more than 100 workspaces, you must run this command multiple times, incrementing the page[number] parameter each time and appending the results.
3. Edit the Workspace JSON File
Open the output.json file and edit it to contain only the workspaces you want to update. Ensure the repo value for each workspace matches the repository identifier required by the new VCS provider.
Here is an example of a formatted output.json file targeting two workspaces.
[
{
"workspace": "random_pet_example2",
"repo": "munnep/random_pet"
},
{
"workspace": "random_pet_example1",
"repo": "munnep/random_pet"
}
]Below is an image of a workspace's settings before the update, showing the original VCS provider.
4. Create the Update Script
Save the following shell script as vcs-update-script.sh on your machine.
#!/bin/bash
## Pass the input file to the script or exit
INPUT_FILE=$1
if [[ -z $INPUT_FILE ]]; then
echo "Usage: $0 file-to-read"
exit 1
fi
## Make sure all of the required variables are set.
if [ -z $TOKEN ] || [ -z $HOSTNAME ] || [ -z $ORG_NAME ] || [ -z $OAUTH_TOKEN ]; then
printf "Please make sure the following environment variables are set:\n\n"
printf "%-13s %s\n" \
"TOKEN" "A user token with the appropriate permissions to alter a workspace's VCS settings" \
"HOSTNAME" "The hostname of your Terraform Enterprise instance" \
"ORG_NAME" "The organization that the workspaces exists in" \
"OAUTH_TOKEN" "The OAuth token of the VCS connection. Can be found in the organization's VCS settings"
exit 1
fi
## Break the input file into individual flat objects
WORKSPACES=$(jq -c '.[]' $INPUT_FILE)
## Iterate over the lines, making the appropriate API call
for x in $WORKSPACES; do
NAME=$(echo $x | jq -r '.workspace')
REPO=$(echo $x | jq -r '.repo')
printf "Setting VCS connection for %s to %s \n" $NAME $REPO
PAYLOAD='{"data":{"attributes":{"vcs-repo":{"identifier":"'$REPO'","oauth-token-id":"'$OAUTH_TOKEN'"}},"type":"workspaces"}}'
## Capture and parse the response, looking for the VCS repo identifier.
## This allows us to compare the expected result to the *actual* result.
RESPONSE=$(curl -s \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request PATCH \
--data "$PAYLOAD" \
"https://$HOSTNAME/api/v2/organizations/$ORG_NAME/workspaces/$NAME")
PARSED_RESPONSE=$(echo $RESPONSE | jq -r '.data.attributes."vcs-repo".identifier')
## Report back whether expectation == reality
if [[ $PARSED_RESPONSE == $REPO ]]; then
printf "Success! \n \n"
else
printf "Something went wrong: $RESPONSE \n \n"
fi
done5. Execute the Script to Update Workspaces
Run the script, passing the output.json file as an argument.
$ ./vcs-update-script.sh output.json
The script iterates through the workspaces defined in output.json and updates the VCS repository using a PATCH request to the Workspaces API.
Outcome
The script will print the status of the update for each workspace. A successful run will produce output similar to this.
Setting VCS connection for random_pet_example2 to munnep/random_pet Success! Setting VCS connection for random_pet_example1 to munnep/random_pet Success!
After the script completes, the workspace settings will show the new VCS provider.
Note: We recommend testing this script in a non-production environment to familiarize yourself with its operation before using it in production.
Additional Information
- For more details on managing workspaces via the API, refer to the Workspaces API documentation.