-
Notifications
You must be signed in to change notification settings - Fork 0
/
setup.sh
executable file
·270 lines (241 loc) · 7.78 KB
/
setup.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
#! /bin/bash
set -euo pipefail
info() {
printf "\r\033[00;35m$1\033[0m\n"
}
success() {
printf "\r\033[00;32m$1\033[0m\n"
}
fail() {
printf "\r\033[0;31m$1\033[0m\n"
}
divider() {
printf "\r\033[0;1m========================================================================\033[0m\n"
}
pause_for_confirmation() {
read -rsp $'Press any key to continue (ctrl-c to quit):\n' -n1 key
}
# Set up an interrupt handler so we can exit gracefully
interrupt_count=0
interrupt_handler() {
((interrupt_count += 1))
echo ""
if [[ $interrupt_count -eq 1 ]]; then
fail "Really quit? Hit ctrl-c again to confirm."
else
echo "Goodbye!"
exit
fi
}
trap interrupt_handler SIGINT SIGTERM
# This setup script does all the magic.
# Check for required tools
declare -a req_tools=("terraform" "sed" "curl" "jq")
for tool in "${req_tools[@]}"; do
if ! command -v "$tool" > /dev/null; then
fail "It looks like '${tool}' is not installed; please install it and run this setup script again."
exit 1
fi
done
# Check for required Terraform version
if ! terraform version -json | jq -r '.terraform_version' &> /dev/null; then
echo
fail "Terraform 0.13 or later is required for this setup script!"
echo "You are currently running:"
terraform version
exit 1
fi
# Set up some variables we'll need
HOST="${1:-app.terraform.io}"
BACKEND_TF=$(dirname ${BASH_SOURCE[0]})/../backend.tf
PROVIDER_TF=$(dirname ${BASH_SOURCE[0]})/../provider.tf
TERRAFORM_VERSION=$(terraform version -json | jq -r '.terraform_version')
# Check that we've already authenticated via Terraform in the static credentials
# file. Note that if you configure your token via a credentials helper or any
# other method besides the static file, this script will not take that in to
# account - but we do this to avoid embedding a Go binary in this simple script
# and you hopefully do not need this Getting Started project if you're using one
# already!
CREDENTIALS_FILE="$HOME/.terraform.d/credentials.tfrc.json"
TOKEN=$(jq -j --arg h "$HOST" '.credentials[$h].token' $CREDENTIALS_FILE)
if [[ ! -f $CREDENTIALS_FILE || $TOKEN == null ]]; then
fail "We couldn't find a token in the Terraform credentials file at $CREDENTIALS_FILE."
fail "Please run 'terraform login', then run this setup script again."
exit 1
fi
# Check that this is your first time running this script. If not, we'll reset
# all local state and restart from scratch!
if ! git diff-index --quiet --no-ext-diff HEAD --; then
echo "It looks like you may have run this script before! Re-running it will reset any
changes you've made to backend.tf and provider.tf."
echo
pause_for_confirmation
git checkout HEAD backend.tf provider.tf
rm -rf .terraform
rm -f *.lock.hcl
fi
echo
printf "\r\033[00;35;1m
--------------------------------------------------------------------------
Getting Started with Terraform Cloud
-------------------------------------------------------------------------\033[0m"
echo
echo
echo "Terraform Cloud offers secure, easy-to-use remote state management and allows
you to run Terraform remotely in a controlled environment. Terraform Cloud runs
can be performed on demand or triggered automatically by various events."
echo
echo "This script will set up everything you need to get started. You'll be
applying some example infrastructure - for free - in less than a minute."
echo
info "First, we'll do some setup and configure Terraform to use Terraform Cloud."
echo
pause_for_confirmation
# Create a Terraform Cloud organization
echo
echo "Creating an organization and workspace..."
sleep 1
setup() {
curl https://$HOST/api/getting-started/setup \
--request POST \
--silent \
--header "Content-Type: application/vnd.api+json" \
--header "Authorization: Bearer $TOKEN" \
--header "User-Agent: tfc-getting-started" \
--data @- << REQUEST_BODY
{
"workflow": "remote-operations",
"terraform-version": "$TERRAFORM_VERSION"
}
REQUEST_BODY
}
response=$(setup)
if [[ $(echo $response | jq -r '.errors') != null ]]; then
fail "An unknown error occurred: ${response}"
exit 1
fi
api_error=$(echo $response | jq -r '.error')
if [[ $api_error != null ]]; then
fail "\n${api_error}"
exit 1
fi
# TODO: If there's an active trial, we should just retrieve that and configure
# it instead (especially if it has no state yet)
info=$(echo $response | jq -r '.info')
if [[ $info != null ]]; then
info "\n${info}"
exit 0
fi
organization_name=$(echo $response | jq -r '.data."organization-name"')
workspace_name=$(echo $response | jq -r '.data."workspace-name"')
echo
echo "Writing remote backend configuration to backend.tf..."
sleep 2
# We don't sed -i because MacOS's sed has problems with it.
TEMP=$(mktemp)
cat $BACKEND_TF |
# add backend config for the hostname if necessary
if [[ "$HOST" != "app.terraform.io" ]]; then sed "5a\\
\ hostname = \"$HOST\"
"; else cat; fi |
# replace the organization and workspace names
sed "s/{{ORGANIZATION_NAME}}/${organization_name}/" |
sed "s/{{WORKSPACE_NAME}}/${workspace_name}/" \
> $TEMP
mv $TEMP $BACKEND_TF
# add extra provider config for the hostname if necessary
if [[ "$HOST" != "app.terraform.io" ]]; then
TEMP=$(mktemp)
cat $PROVIDER_TF |
sed "11a\\
\ hostname = var.provider_hostname
" \
> $TEMP
echo "
variable \"provider_hostname\" {
type = string
}" >> $TEMP
mv $TEMP $PROVIDER_TF
fi
echo
divider
echo
success "Ready to go; the example configuration is set up to use Terraform Cloud!"
echo
echo "An example workspace named '${workspace_name}' was created for you."
echo "You can view this workspace in the Terraform Cloud UI here:"
echo "https://$HOST/app/${organization_name}/workspaces/${workspace_name}"
echo
info "Next, we'll run 'terraform init' to initialize the backend and providers:"
echo
echo "$ terraform init"
echo
pause_for_confirmation
echo
terraform init
echo
echo "..."
sleep 2
echo
divider
echo
info "Now it’s time for 'terraform plan', to see what changes Terraform will perform:"
echo
echo "$ terraform plan"
echo
pause_for_confirmation
echo
terraform plan
echo
echo "..."
sleep 3
echo
divider
echo
success "The plan is complete!"
echo
echo "This plan was initiated from your local machine, but executed within
Terraform Cloud!"
echo
echo "Terraform Cloud runs Terraform on disposable virtual machines in
its own cloud infrastructure. This 'remote execution' helps provide consistency
and visibility for critical provisioning operations. It also enables notifications,
version control integration, and powerful features like Sentinel policy enforcement
and cost estimation (shown in the output above)."
echo
info "To actually make changes, we'll run 'terraform apply'. We'll also auto-approve
the result, since this is an example:"
echo
echo "$ terraform apply -auto-approve"
echo
pause_for_confirmation
echo
terraform apply -auto-approve
echo
echo "..."
sleep 3
echo
divider
echo
success "You did it! You just provisioned infrastructure with Terraform Cloud!"
echo
info "The organization we created here has a 30-day free trial of the Team &
Governance tier features. After the trial ends, you'll be moved to the Free tier."
echo
echo "You now have:"
echo
echo " * Workspaces for organizing your infrastructure. Terraform Cloud manages"
echo " infrastructure collections with workspaces instead of directories. You"
echo " can view your workspace here:"
echo " https://$HOST/app/$organization_name/workspaces/$workspace_name"
echo " * Remote state management, with the ability to share outputs across"
echo " workspaces. We've set up state management for you in your current"
echo " workspace, and you can reference state from other workspaces using"
echo " the 'terraform_remote_state' data source."
echo " * Much more!"
echo
info "To see the mock infrastructure you just provisioned and continue exploring
Terraform Cloud, visit:
https://$HOST/fake-web-services"
echo
exit 0