Skip to content

Commit ca3d986

Browse files
authored
Merge pull request hashicorp#73 from hashicorp/automation-script-mods
added handling of run_status planned
2 parents 5ba2af9 + 3a2d572 commit ca3d986

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

operations/automation-script/README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@ The script does the following steps:
88
1. Packages main.tf into the myconfig.tar.gz file.
99
1. Creates the workspace.
1010
1. Creates a new configuration version.
11-
1. Uploads the myconfig.tar.gz file as a new configuration. (This step used to trigger an initial run which caused an error because we had not yet set the name variable in the workspace. But we now have configversion.json configured to use auto-queue-runs set to false. So, this run is no longer triggered.)
11+
1. Uploads the myconfig.tar.gz file as a new configuration. (This step used to trigger an initial run which caused an error because we had not yet set the name variable in the workspace. But we now have configversion.json configured to use auto-queue-runs set to false. So, this run is no longer triggered.)
1212
1. Adds one Terraform variable called "name" and one Environment variable called "CONFIRM_DESTROY" to the workspace, getting their values from the variables.csv file. You can edit this file to add as many variables as you want.
13+
1. Determines the number of Sentinel policies.
1314
1. Starts a new run.
1415
1. Enters a loop to check the run results periodically.
16+
- If $run_status is "planned", $is_confirmable is "True", and $override is "no", the script stops. In this case, no Sentinel policies existed or none of them were applicable to this workspace. The script will stop. The user should can apply the run in the Terraform Enterprise UI.
17+
- If $run_status is "planned", $is_confirmable is "True", and $override is "yes", the script will do an apply. As in the previous case, no Sentinel policies existed or none of them were applicable to this workspace.
1518
- If $run_status is "policy_checked", it does an Apply. In this case, all Sentinel policies passed.
1619
- If $run_status is "policy_override" and $override is "yes", it overrides the failed policy checks and does an Apply. In this case, one or more Sentinel policies failed, but they were marked "advisory" or "soft-mandatory" and the script was configured to override the failure.
1720
- If $run_status is "policy_override" and $override is "no", it prints out a message indicating that some policies failed and are not being overridden.
1821
- If $run_status is "errored", either the plan failed or a Sentinel policy marked "hard-mandatory" failed. The script terminates.
22+
- Other values of $run_status cause the loop to repeat after a brief sleep.
1923

2024
Note that some json template files are included from which other json files are generated so that they can be passed to the curl commands.
2125

@@ -36,6 +40,12 @@ Do the following before using this script:
3640
1. `cd operations/automation-script`
3741
1. Make sure [python](https://www.python.org/downloads/) is installed on your machine and in your path since the script uses python to parse JSON documents returned by the Terraform Enterprise REST API.
3842

43+
## Using with Private Terraform Enteprise Server using private CA
44+
If you use this script with a Private Terraform Enterprise (PTFE) server that uses a private CA instead of a public CA, you will need to ensure that the curl commands run by the script will trust the private CA. There are several ways to do this. The first is easiest for enabling the automation script to run, but it only affects curl. The second and third are useful for using the Terraform and TFE CLIs against your PTFE server. The third is a permanent solution.
45+
1. `export CURL_CA_BUNDLE=<path_to_ca_bundle>`
46+
1. Export the Golang SSL_CERT_FILE and/or SSL_CERT_DIR environment variables. For instance, you could set the first of these to the same CA bundle used in option 1.
47+
1. Copy your certificate bundle to /etc/pki/ca-trust/source/anchors and then run `update-ca-trust extract`.
48+
3949
## Instructions
4050
Follow these instructions to run the script with the included main.tf and variables.csv files:
4151

@@ -45,7 +55,7 @@ Follow these instructions to run the script with the included main.tf and variab
4555
1. `export ATLAS_TOKEN=<owners_token>` where \<owners_token\> is the token generated in the previous step.
4656
1. If you want, you can also change the name of the workspace that will be created and the sleep_duration variable which controls how often the script checks the status of the triggered run (in seconds).
4757
1. Edit variables.csv to specify the name you would like to set the name variable to by replacing "Roger" with some other name.
48-
1. Run `./loadAndRunWorkspace.sh` or `./loadAndRunWorkspace.sh <override>` where \<override\> is "yes" or "no". If you do not specify a value for \<override\>, the script will set it to "no".
58+
1. Run `./loadAndRunWorkspace.sh` or `./loadAndRunWorkspace.sh <override>` where \<override\> is "yes" or "no". If you do not specify a value for \<override\>, the script will set it to "no". The override variable is used in two ways: a) to automatically do an apply when no Sentinel policies exist or none of them are applicable to the workspace, and b) to override any soft-mandatory Sentinel policies that failed.
4959

5060
### Examples
5161
`./loadAndRunWorkspace` (no override will be done)
@@ -55,7 +65,7 @@ Follow these instructions to run the script with the included main.tf and variab
5565
`./loadAndRunWorkspace no` (no override will be done)
5666

5767
### Running with other Terraform code
58-
If you would like to load other Terraform code into a workspace with the script, replace main.tf in the config directory with your own Terraform code. All files in the config directory will be uploaded to your TFE server. Also edit variables.csv to remove the first row with the name variable and add rows for any Terraform and Environment variables that are required by your Terraform code.
68+
If you would like to load other Terraform code into a workspace with the script, replace main.tf in the config directory with your own Terraform code. All files in the config directory will be uploaded to your TFE server. Also edit variables.csv to remove the first row with the name variable and add rows for any Terraform and Environment variables that are required by your Terraform code. If your code has a terraform.tfvars file, please rename it to terraform.auto.tfvars since TFE overwrites any instance of terraform.tfvars with the variables set in the workspace. Adding variables already in a `*.auto.tfvars` file is not strictly necessary, but is recommended so that users looking at the workspace can see the values set on the variables.
5969

6070
## Cleaning Up
6171
If you want to run the script again, delete the workspace from the Settings tab of the workspace in the TFE UI. You do not need to delete or touch any of the files in the directory containing the script and other files.

operations/automation-script/loadAndRunWorkspace.sh

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ organization="<your_organization>"
1111
workspace="workspace-from-api"
1212

1313
# You can change sleep duration if desired
14-
sleep_duration=15
14+
sleep_duration=5
1515

1616
# Override soft-mandatory policy checks that fail.
1717
# Set to "yes" or "no" in second argument passed to script.
@@ -59,6 +59,11 @@ do
5959
upload_variable_result=$(curl --header "Authorization: Bearer $ATLAS_TOKEN" --header "Content-Type: application/vnd.api+json" --data @variable.json "https://${address}/api/v2/vars?filter%5Borganization%5D%5Bname%5D=${organization}&filter%5Bworkspace%5D%5Bname%5D=${workspace}")
6060
done < variables.csv
6161

62+
# List Sentinel Policies
63+
sentinel_list_result=$(curl --header "Authorization: Bearer $ATLAS_TOKEN" --header "Content-Type: application/vnd.api+json" "https://${address}/api/v2/organizations/${organization}/policies")
64+
sentinel_policy_count=$(echo $sentinel_list_result | python -c "import sys, json; print(json.load(sys.stdin)['meta']['pagination']['total-count'])")
65+
echo "Number of Sentinel policies: " $sentinel_policy_count
66+
6267
# Do a run
6368
sed "s/workspace_id/$workspace_id/" < run.template.json > run.json
6469
run_result=$(curl --header "Authorization: Bearer $ATLAS_TOKEN" --header "Content-Type: application/vnd.api+json" --data @run.json https://${address}/api/v2/runs)
@@ -77,13 +82,31 @@ while [ $continue -ne 0 ]; do
7782
# Check the status of run
7883
check_result=$(curl --header "Authorization: Bearer $ATLAS_TOKEN" --header "Content-Type: application/vnd.api+json" https://${address}/api/v2/runs/${run_id})
7984

80-
# Parse out the run status
85+
# Parse out the run status and is-confirmable
8186
run_status=$(echo $check_result | python -c "import sys, json; print(json.load(sys.stdin)['data']['attributes']['status'])")
8287
echo "Run Status: " $run_status
88+
is_confirmable=$(echo $check_result | python -c "import sys, json; print(json.load(sys.stdin)['data']['attributes']['actions']['is-confirmable'])")
89+
echo "Run can be applied: " $is_confirmable
8390

8491
# Apply in some cases
92+
93+
# planned means plan finished and no Sentinel policies
94+
# exist or are applicable to the workspace
95+
if [[ "$run_status" == "planned" ]] && [[ "$is_confirmable" == "True" ]] && [[ "$override" == "no" ]] ; then
96+
continue=0
97+
echo "There are " $sentinel_policy_count "policies, but none of them are applicable to this workspace."
98+
echo "Check the run in Terraform Enterprise UI and apply there if desired."
99+
# planned means plan finished and no Sentinel policies
100+
# exist or are applicable to the workspace
101+
elif [[ "$run_status" == "planned" ]] && [[ "$is_confirmable" == "True" ]] && [[ "$override" == "yes" ]] ; then
102+
continue=0
103+
echo "There are " $sentinel_policy_count "policies, but none of them are applicable to this workspace."
104+
echo "Since override was set to \"yes\", we are applying."
105+
# Do the apply
106+
echo "Doing Apply"
107+
apply_result=$(curl --header "Authorization: Bearer $ATLAS_TOKEN" --header "Content-Type: application/vnd.api+json" --data @apply.json https://${address}/api/v2/runs/${run_id}/actions/apply)
85108
# policy_checked means all Sentinel policies passed
86-
if [[ "$run_status" == "policy_checked" ]] ; then
109+
elif [[ "$run_status" == "policy_checked" ]] ; then
87110
continue=0
88111
# Do the apply
89112
echo "Policies passed. Doing Apply"
@@ -118,6 +141,6 @@ while [ $continue -ne 0 ]; do
118141
continue=0
119142
else
120143
# Sleep a bit and then check status again in next loop
121-
sleep $sleep_duration
144+
echo "We will sleep a bit and try again soon."
122145
fi
123146
done

0 commit comments

Comments
 (0)