Introduction
This article describes a process for replacing the VCS OAuth token for multiple workspaces in HCP Terraform or Terraform Enterprise using a provided shell script.
Use Case
This procedure is useful when you need to update the OAuth token for many workspaces at once. Common scenarios include:
- The current OAuth token was compromised or is no longer valid.
- The current OAuth token was revoked by the VCS provider.
- The OAuth token expired unexpectedly.
Prerequisites
Before you begin, ensure you have the following:
- An API token from a user account with permissions to update workspace VCS settings.
- The
curlandjqcommand-line utilities installed on your local machine. - The following script saved locally as
vcs-update-script.sh.
#!/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 $TFE_HOSTNAME ] || [ -z $ORG ] || [ -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" \
"TFE_HOSTNAME" "The hostname of your Terraform Enterprise instance or app.terraform.io" \
"ORG" "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
## 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 "{\"data\":{\"attributes\":{\"vcs-repo\":{\"identifier\":\"$REPO\",\"oauth-token-id\":\"$OAUTH_TOKEN\"}},\"type\":\"workspaces\"}}" \
"https://$TFE_HOSTNAME/api/v2/organizations/$ORG/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
doneProcedure
Follow these steps to update the VCS tokens for your workspaces.
Step 1: Set Initial Environment Variables
In your shell, export the following environment variables. Replace the placeholder values with your information.
$ export TOKEN="<YOUR_API_TOKEN>" $ export ORG="<YOUR_ORGANIZATION_NAME>" $ export TFE_HOSTNAME="<YOUR_TFE_HOSTNAME>"
Note: For HCP Terraform, set the TFE_HOSTNAME variable to app.terraform.io.
Step 2: Identify the New OAuth Token ID
Run the following command to retrieve the OAuth clients for your organization.
$ curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request GET \
https://$TFE_HOSTNAME/api/v2/organizations/$ORG/oauth-clientsFrom the JSON output, locate the new VCS connection you want to use. Find its id within the relationships.oauth-tokens.data array. The ID is prefixed with ot-. The example below is trimmed for clarity.
{
"data": [
{
"id": "oc-zpYpgyFj9FWe4Vih",
"type": "oauth-clients",
"attributes": {
"name": "Test ADO",
"service-provider": "ado_services"
},
"relationships": {
"organization": {
"data": {
"id": "orgnamehere",
"type": "organizations"
}
},
"oauth-tokens": {
"data": [
{
"id": "ot-R9dcvasfasnny5pRFH",
"type": "oauth-tokens"
}
]
}
}
}
]
}In this example, the target OAuth token ID is ot-R9dcvasfasnny5pRFH.
Step 3: Set the OAuth Token Environment Variable
Export the OAuth token ID you identified in the previous step.
$ export OAUTH_TOKEN="<OAUTH_TOKEN_ID>"
Step 4: Generate a Workspace List
Run the following command to generate a JSON file named output.json containing a list of workspaces in your organization.
$ curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
"https://$TFE_HOSTNAME/api/v2/organizations/$ORG/workspaces?page%5Bnumber%5D=1&page%5Bsize%5D=100" | \
jq -r '[.data[].attributes | {workspace: .name, repo: ."vcs-repo"."display-identifier"}]' > output.jsonReview output.json and remove any workspaces that use a different VCS provider or that you do not want to update.
Step 5: Run the Update Script
Execute the script, passing the output.json file as an argument.
$ chmod +x vcs-update-script.sh $ ./vcs-update-script.sh output.json
Outcome
The script will print the status of each workspace update. A successful update will look like this:
Setting VCS connection for workspace1 to VCSOrg/workspace1 Success! Setting VCS connection for workspace2 to VCSOrg/workspace2 Success!
If an error occurs, the script will log the API response.
Setting VCS connection for test-vcs-tfc to testorg/test-vcs-tfc/test-vcs-tfc
Something went wrong: {"errors":[{"status":"422","title":"invalid attribute","detail":"Repository doesn't exist or isn't accessible","source":{"pointer":"/data/attributes/repository"}}]}CLI-driven workspaces will process without error, as the script effectively sets their already null VCS token to null.
Additional Information
The vcs-update-script.sh script uses the HCP Terraform and Terraform Enterprise API to update the VCS repository settings for each workspace specified in the input file. For more details on the API endpoints used, refer to the official documentation: