Skip to content

Instantly share code, notes, and snippets.

@tomcant
Created August 26, 2020 16:05
Show Gist options
  • Save tomcant/b900c1d920018c85b81636c5863ed487 to your computer and use it in GitHub Desktop.
Save tomcant/b900c1d920018c85b81636c5863ed487 to your computer and use it in GitHub Desktop.
Update the version of Terraform used by a Terraform Cloud/Enterprise workspace (also queues a plan)
#!/usr/bin/env bash
readonly DEFAULT_VERSION='0.13.0'
readonly DEFAULT_API_HOST='app.terraform.io'
highlight() { echo -e "\033[36m$*\033[0m"; }
info() { echo -e "\033[36mINFO: $*\033[0m"; }
success() { echo -e "\033[32m$*\033[0m"; }
fail() { echo -e "\033[31mERROR: $*\033[0m" >&2; exit 1; }
##
# Usage information.
##
usage() {
cat <<-EOM
Update the version of Terraform used by the given workspace.
Usage: $(highlight "./$(basename "${BASH_SOURCE[0]}") ORGANISATION WORKSPACE [VERSION=${DEFAULT_VERSION}] [API_HOST=${DEFAULT_API_HOST}]")
Arguments:
$(highlight ORGANISATION) the name of the organisation the workspace belongs to
$(highlight WORKSPACE) the name of the workspace to update
$(highlight VERSION) the version of Terraform to update the workspace to (defaults to ${DEFAULT_VERSION})
$(highlight API_HOST) the hostname of the Terraform Cloud/Enterprise API server (defaults to ${DEFAULT_API_HOST})
EOM
}
##
# Verify requirements.
##
command -v jq >/dev/null || fail 'jq is missing.'
readonly ORGANISATION=$1
[[ -z "${ORGANISATION}" ]] && usage && fail 'Required argument ORGANISATION is missing.'
readonly WORKSPACE=$2
[[ -z "${WORKSPACE}" ]] && usage && fail 'Required argument WORKSPACE is missing.'
readonly VERSION=${3:-${DEFAULT_VERSION}}
[[ ! "${VERSION}" =~ ^([0-9]+\.){2}[0-9]+$ ]] && usage && fail 'Version must conform to semver.'
readonly API_HOST=${4:-${DEFAULT_API_HOST}}
[[ -z "${API_HOST}" ]] && usage && fail 'API host cannot be empty.'
readonly TOKEN=$(jq -r '.credentials["'"${API_HOST}"'"].token' < ~/.terraform.d/credentials.tfrc.json)
[[ -z "${TOKEN}" ]] && fail "Could not find authentication token. Run 'terraform login' to generate one."
##
# Update the workspace.
##
readonly API_BASE_URL="https://${API_HOST}/api/v2"
info "Updating workspace '${WORKSPACE}' to Terraform version ${VERSION}"
curl -s -X PATCH \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/vnd.api+json" \
"${API_BASE_URL}/organizations/${ORGANISATION}/workspaces/${WORKSPACE}" -d \
'
{
"data": {
"attributes": {
"terraform_version": "'"${VERSION}"'"
},
"type": "workspaces"
}
}
' >/dev/null
success 'Workspace updated.'
##
# Run a plan in the workspace.
##
info 'Determining workspace ID'
workspace_id=$(
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/vnd.api+json" \
"${API_BASE_URL}/organizations/${ORGANISATION}/workspaces/${WORKSPACE}" | jq -r '.data.id'
)
info "Queueing a plan for workspace ID '${workspace_id}'"
curl -s -X POST \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/vnd.api+json" \
"${API_BASE_URL}/runs" -d \
'
{
"data": {
"type":"runs",
"relationships": {
"workspace": {
"data": {
"type": "workspaces",
"id": "'"${workspace_id}"'"
}
}
}
}
}
' >/dev/null
success 'Plan queued.'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment