-
Notifications
You must be signed in to change notification settings - Fork 11
/
launchpad.sh
executable file
·276 lines (214 loc) · 9.95 KB
/
launchpad.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
271
272
273
274
275
276
#!/bin/bash
# Initialize the launchpad first with ./launchpad.sh
# deploy a landing zone or a blueprint with ./launchpad.sh [blueprint_folder_name]
# capture the current path
current_path=$(pwd)
blueprint_name=$1
tf_action=$2
shift 2
tf_command=$@
echo "tf_action is : '$(echo ${tf_action})'"
echo "tf_command is : '$(echo ${tf_command})'"
echo "blueprint is : '$(echo ${blueprint_name})'"
set -e
function initialize_state {
echo "Initializing launchpad from ${blueprint_name}"
cd ${blueprint_name}
set +e
rm ./.terraform/terraform.tfstate
rm ./terraform.tfstate
rm backend.azurerm.tf
set -e
# Get the looged in user ObjectID
export TF_VAR_logged_user_objectId=$(az ad signed-in-user show --query objectId -o tsv)
terraform init
terraform apply -auto-approve
echo ""
upload_tfstate
cd "${current_path}"
}
function initialize_from_remote_state {
echo 'Connecting to the launchpad'
cd ${blueprint_name}
cp backend.azurerm backend.azurerm.tf
tf_name="${blueprint_name}.tfstate"
terraform init \
-backend=true \
-reconfigure=true \
-backend-config storage_account_name=${storage_account_name} \
-backend-config container_name=${container} \
-backend-config access_key=${access_key} \
-backend-config key=${tf_name}
terraform apply -refresh=true -auto-approve
rm backend.azurerm.tf
cd "${current_path}"
}
function plan {
echo "running terraform plan with $tf_command"
terraform plan $tf_command \
-out=${blueprint_name}.tfplan
}
function apply {
echo 'running terraform apply'
terraform apply \
-no-color \
${blueprint_name}.tfplan
cd "${current_path}"
}
function destroy {
echo 'running terraform destroy'
terraform destroy ${tf_command} \
-refresh=true
}
function deploy_blueprint {
cd ${blueprint_name}
export TF_VAR_tfstate_current_level=$(terraform output tfstate_map)
export TF_VAR_deployment_msi=$(terraform output deployment_msi)
export TF_VAR_keyvault_id=$(terraform output keyvault_id)
storage_account_name=$(terraform output storage_account_name)
echo ${storage_account_name}
resource_group=$(terraform output resource_group)
access_key=$(az storage account keys list --account-name ${storage_account_name} --resource-group ${resource_group} | jq -r .[0].value)
container=$(terraform output container)
tf_name="${blueprint_name}.tfstate"
# Set the security context under the devops app
export ARM_SUBSCRIPTION_ID=$(az account show | jq -r .id) && echo " - subscription id: ${ARM_SUBSCRIPTION_ID}"
export ARM_CLIENT_ID=$(terraform output devops_application_id)
export ARM_CLIENT_SECRET=$(terraform output devops_client_secret)
export ARM_TENANT_ID=$(az account show | jq -r .tenantId) && echo " - tenant id: ${ARM_TENANT_ID}"
cd "../${blueprint_name}"
pwd
terraform init \
-reconfigure \
-backend=true \
-lock=false \
-backend-config storage_account_name=${storage_account_name} \
-backend-config container_name=${container} \
-backend-config access_key=${access_key} \
-backend-config key=${tf_name}
if [ $tf_action == "plan" ]; then
plan
fi
if [ $tf_action == "apply" ]; then
plan
apply
echo "Blueprint successfuly deployed on its orbital layer"
fi
if [ ${tf_action} == "destroy" ]; then
destroy
fi
if [ -f ${blueprint_name}.tfplan ]; then
echo "Deleting file ${blueprint_name}.tfplan"
rm ${blueprint_name}.tfplan
fi
cd "${current_path}"
}
function upload_tfstate {
echo "Moving launchpad to the cloud"
storage_account_name=$(terraform output storage_account_name)
resource_group=$(terraform output resource_group)
access_key=$(az storage account keys list --account-name ${storage_account_name} --resource-group ${resource_group} | jq -r .[0].value)
container=$(terraform output container)
tf_name="${blueprint_name}.tfstate"
blobFileName=$(terraform output tfstate-blob-name)
az storage blob upload -f terraform.tfstate \
-c ${container} \
-n ${blobFileName} \
--account-key ${access_key} \
--account-name ${storage_account_name}
rm -f terraform.tfstate
}
function get_remote_state_details {
echo ""
echo "Getting level0 launchpad coordinates:"
stg=$(az storage account show --ids ${id})
export storage_account_name=$(echo ${stg} | jq -r .name) && echo " - storage_account_name: ${storage_account_name}"
export resource_group=$(echo ${stg} | jq -r .resourceGroup) && echo " - resource_group: ${resource_group}"
export access_key=$(az storage account keys list --account-name ${storage_account_name} --resource-group ${resource_group} | jq -r .[0].value) && echo " - storage_key: retrieved"
export container=$(echo ${stg} | jq -r .tags.container) && echo " - container: ${container}"
location=$(echo ${stg} | jq -r .location) && echo " - location: ${location}"
export tf_name="${blueprint_name}.tfstate"
}
function display_instructions {
echo "You can deploy a landing zone / blueprint from the launchpad by running ./launchpad.sh [blueprint_folder_name|launchpad_folder_name] [plan|apply|destroy]"
echo ""
echo "You must set a blueprint_name as in the list:"
for i in $(ls -d blueprint*/); do echo ${i%%/}; done
echo ""
echo "Or you must set a landing zone as in the list:"
for i in $(ls -d landingzone*/); do echo ${i%%/}; done
echo ""
}
# Trying to retrieve the terraform state storage account id
id=$(az resource list --tag stgtfstate=level0 | jq -r .[0].id)
# Initialise storage account to store remote terraform state
if [ "$id" == "null" ]; then
echo "Calling initialize_state"
blueprint_name="level0_launchpad"
initialize_state
id=$(az resource list --tag stgtfstate=level0 | jq -r .[0].id)
echo "Launchpad initialized and ready"
get_remote_state_details
else
echo ""
echo "Launchpad already initialized."
get_remote_state_details
echo ""
if [ -z "${blueprint_name}" ]; then
display_instructions
exit 1
fi
fi
if [ "${blueprint_name}" == "level0_launchpad" ]; then
if [ "${tf_action}" == "destroy" ]; then
echo "The moon launchpad is protected from deletion"
fi
display_instructions
else
echo "Deploying '${blueprint_name}'"
cd ${blueprint_name}
tf_name="${blueprint_name}.tfstate"
# Get parameters of the terraform state from keyvault. Note we are using tags to retrieve the level0
export keyvault=$(az resource list --tag kvtfstate=level0 | jq -r .[0].name) && echo " - keyvault_name: ${keyvault}"
# Set the security context under the devops app
echo ""
echo "Identity of the pilot in charge of delivering the landing zone"
export ARM_SUBSCRIPTION_ID=$(az keyvault secret show -n tfstate-sp-devops-subscription-id --vault-name ${keyvault} | jq -r .value) && echo " - subscription id: ${ARM_SUBSCRIPTION_ID}"
export ARM_CLIENT_ID=$(az keyvault secret show -n tfstate-sp-devops-client-id --vault-name ${keyvault} | jq -r .value) && echo " - client id: ${ARM_CLIENT_ID}"
export ARM_CLIENT_SECRET=$(az keyvault secret show -n tfstate-sp-devops-client-secret --vault-name ${keyvault} | jq -r .value)
export ARM_TENANT_ID=$(az keyvault secret show -n tfstate-sp-devops-tenant-id --vault-name ${keyvault} | jq -r .value) && echo " - tenant id: ${ARM_TENANT_ID}"
export TF_VAR_prefix=$(az keyvault secret show -n tfstate-prefix --vault-name ${keyvault} | jq -r .value)
echo ""
export TF_VAR_lowerlevel_storage_account_name=$(az keyvault secret show -n tfstate-storage-account-name --vault-name ${keyvault} | jq -r .value)
export TF_VAR_lowerlevel_resource_group_name=$(az keyvault secret show -n tfstate-resource-group --vault-name ${keyvault} | jq -r .value)
export TF_VAR_lowerlevel_key=$(az keyvault secret show -n tfstate-blob-name --vault-name ${keyvault} | jq -r .value)
export TF_VAR_lowerlevel_container_name=$(az keyvault secret show -n tfstate-container --vault-name ${keyvault} | jq -r .value)
# todo to be replaced with SAS key - short ttl or msi with the rover
export ARM_ACCESS_KEY=$(az storage account keys list --account-name ${storage_account_name} --resource-group ${resource_group} | jq -r .[0].value)
terraform init \
-reconfigure \
-backend=true \
-lock=false \
-backend-config storage_account_name=${storage_account_name} \
-backend-config container_name=${container} \
-backend-config access_key=${access_key} \
-backend-config key=${tf_name}
if [ ${tf_action} == "plan" ]; then
echo "calling plan"
plan
fi
if [ ${tf_action} == "apply" ]; then
echo "calling plan and apply"
plan
apply
fi
if [ ${tf_action} == "destroy" ]; then
echo "calling destroy"
destroy
fi
if [ -f ${blueprint_name}.tfplan ]; then
echo "Deleting file ${blueprint_name}.tfplan"
rm ${blueprint_name}.tfplan
fi
cd "${current_path}"
fi