Skip to content

Instantly share code, notes, and snippets.

@abuxton
Last active February 9, 2022 16:14
Show Gist options
  • Save abuxton/ea5f37767af44a710020ee2fbe97a7f3 to your computer and use it in GitHub Desktop.
Save abuxton/ea5f37767af44a710020ee2fbe97a7f3 to your computer and use it in GitHub Desktop.
Publish pmr script

Publish PMR helper script

Script to publish modules utilizing the API https://www.terraform.io/docs/cloud/api/modules.html. Uses native OS python json library, but the alt. jq lines are included feel free to amend.

Usage

> git clone https://gist.github.com/abuxton/ea5f37767af44a710020ee2fbe97a7f3 publish-pmr-module && cd publish-pmr-module
export TFE_ORG=# your TFE/C organisation name
export TFE_ADDR=app.terraform.io #set your internal TFE DNS
export TFE_TOKEN=$TOKEN 
# your access token for tfe/c normally equates to `$(cat ~/.terraform.d/credentials.tfrc.json | jq '.credentials."${TF_ADDR}".token' | sed s/\"//g)` 
export SEMVER # i.e 0.1.0 (if you're using version control, `git describe --tags` will get that last tag)

bash ./publish_pmr_module.sh \ 
  TFE_TOKEN=$TOKEN \
  TFE_ORG=$TF_ORG \
  TFE_ORG=$TF_ADDR \
  PRIVATE_MODULE=true \
  TFE_MODULE_VERSION=$SEMVER
#!/usr/bin/env sh -x
#!/bin/bash
# Script to publish modules utilizing the API https://www.terraform.io/docs/cloud/api/modules.html
# Uses native OS python json library, but the alt. jq lines are included feel free to amend.
# ❯ export TOKEN=`cat ~/.terraform.d/credentials.tfrc.json | jq '.credentials."app.terraform.io".token' | sed s/\"//g`
# ❯ cat ~/.terraform.d/credentials.tfrc.json | python -c "import sys, json; print(json.load(sys.stdin)['credentials']['app.terraform.io']['token'])"
# usage:
# ❯ bash ./publish_pmr_module.sh \
# TFE_TOKEN=$TOKEN \
# TFE_ORG=$TF_ORG \
# TFE_ORG=$TF_ADDR \
# PRIVATE_MODULE=true \
# TFE_MODULE_VERSION=$SEMVER
# Exit if any errors encountered
set -e
# uses, https://unix.stackexchange.com/questions/129391/passing-named-arguments-to-shell-scripts
# should use https://wiki.bash-hackers.org/howto/getopts_tutorial but -<singlechar> is too limited
for ARGUMENT in "$@"
do
KEY=$(echo $ARGUMENT | cut -f1 -d=)
VALUE=$(echo $ARGUMENT | cut -f2 -d=)
case "$KEY" in
TFE_TOKEN) TFE_TOKEN=${VALUE} ;;
TFE_ORG) TFE_ORG=${VALUE} ;;
TFE_ADDR) TFE_ADDR=${VALUE} ;;
PRIVATE_MODULE) PRIVATE=${VALUE} ;;
TFE_MODULE_VERSION) TFE_MODULE_VERSION=${VALUE} ;;
*)
esac
done
# Make sure TFE_TOKEN and TFE_ORG environment variables are set
# to owners team token and organization name for the respective
# TFE environment. TFE_TOKEN environment variable is set
# to a user or team token that has the write or admin permission
# for the workspace.
if [ ! -z "$TFE_TOKEN" ]; then
token=$TFE_TOKEN
echo "TFE_TOKEN environment variable was found."
else
echo "TFE_TOKEN environment variable was not set."
echo "You must export/set the TFE_TOKEN environment variable."
echo "It should be a user or team token that has write or admin"
echo "permission on the workspace."
echo "Exiting."
exit
fi
# Evaluate $TFE_ORG environment variable
# If not set, give error and exit
if [ ! -z "$TFE_ORG" ]; then
organization=$TFE_ORG
echo "TFE_ORG environment variable was set to ${TFE_ORG}."
echo "Using organization, ${organization}."
else
echo "You must export/set the TFE_ORG environment variable."
echo "Exiting."
exit
fi
# Evaluate $TFE_ADDR environment variable if it exists
# Otherwise, use "app.terraform.io"
# You should edit these before running the script.
if [ ! -z "$TFE_ADDR" ]; then
address=$TFE_ADDR
echo "TFE_ADDR environment variable was set to ${TFE_ADDR}."
echo "Using address, ${address}"
else
address="app.terraform.io"
echo "TFE_ADDR environment variable was not set."
echo "Using Terraform Cloud (TFE SaaS) address, app.terraform.io."
echo "If you want to use a private TFE server, export/set TFE_ADDR."
fi
if [ ! -z "$TFE_MODULE_VERSION" ]; then
version=$TFE_MODULE_VERSION
echo "TFE Module Version set to ${version}"
else
echo "VERSION not provided please export TFE_MODULE_VERSION or provide as flag"
echo "Exiting."
exit
fi
# Check to see if the workspace already exists and get workspace ID
echo "Checking to see if organisation exists and getting getting organisation ID"
check_organisation_result=$(curl -s --header "Authorization: Bearer $token" --header "Content-Type: application/vnd.api+json" "https://${address}/api/v2/organizations/${organization}")
# Parse workspace_id from check_workspace_result
# organisation_id=$(echo $check_organisation_result | jq '.data.id' )
organisation_id=$(echo $check_organisation_result | python -c "import sys, json; print(json.load(sys.stdin)['data']['id'])")
echo "Organisation ID: " $organisation_id
echo " "
module_name=$(basename $PWD)
# echo "module name = ${module_name}"
provider=$(echo $module_name | awk -F '[-]' '{print $2}')
echo "Module Provider = ${provider}"
name=$(echo $module_name | awk -F '[-]' '{print $3"-"$4}')
echo "Module Name = ${name}"
if [ $PRIVATE ]; then
# https://www.terraform.io/docs/cloud/api/modules.html#create-a-module-version
echo "Publishing private module"
echo "creating module"
cat > registry-module.json <<EOF
{
"data": {
"type": "registry-modules",
"attributes": {
"name": "${name}",
"provider": "${provider}",
"registry-name": "private"
}
}
}
EOF
create_private_module=$(curl -s --header "Authorization: Bearer $token" --header "Content-Type: application/vnd.api+json" --request POST --data @registry-module.json "https://${address}/api/v2/organizations/${organization}/registry-modules")
echo $create_private_module
echo "Retrieving module version"
cat > registry-module-version.json <<EOF
{
"data": {
"type": "registry-module-versions",
"attributes": {
"version": "${version}"
}
}
}
EOF
# sed -ie s/TFE_MODULE_VERSION/$version/g registry-module-version.json
retrieve_module_version=$(curl -s --header "Authorization: Bearer $token" --header "Content-Type: application/vnd.api+json" --request POST --data @registry-module-version.json "https://${address}/api/v2/organizations/${organization}/registry-modules/private/${organization}/${name}/${provider}/versions")
# echo $retrieve_module_version
# module_upload_url=$(echo $retrieve_module_version | jq '.data.links.upload')
module_upload_url=$(echo $retrieve_module_version | python -c "import sys, json; print(json.load(sys.stdin)['data']['links']['upload'])")
echo "Module being uploaded to ${module_upload_url}"
# https://www.terraform.io/docs/cloud/api/modules.html#upload-a-module-version-private-module-
echo "tarballing ./module.tar.gz"
tar zcf module.tar.gz *
upload_module=$(curl --header "Content-Type: application/octet-stream" --request PUT --data-binary @module.tar.gz "${module_upload_url}")
echo "Module uploaded"
echo "visit https://${address}/app/${organization}/registry/private/modules?q=${name}"
else
echo "Not able to publish public modules at this time"
exit
fi
@abuxton
Copy link
Author

abuxton commented Nov 12, 2021

usage
bash publish_pmr_module.sh TFE_TOKEN=$TOKEN TFE_ORG=abc-hashi-training PRIVATE_MODULE=true TFE_MODULE_VERSION=$SEMVER

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment