-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaz-tf-storage-statefiles.ps1
321 lines (294 loc) · 12 KB
/
az-tf-storage-statefiles.ps1
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
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
#Log into Azure
#az login
#az account set --subscription "xxxxxx"
# Setup Variables.
$randomInt = Get-Random -Maximum 9999
#$randomInt = 4140 #you can reuse same code if you know randomInt
$subscriptionId=$(az account show --query id -o tsv)
$resourceGroupName = "rg-tf-core"
$storageNameDEV = "sttfstatedev$randomInt"
$storageNameUAT = "sttfstateuat$randomInt"
$storageNamePRD = "sttfstateprd$randomInt"
$kvName = "kv-tfstate-backend$randomInt"
$appName="sp-tfstate-github$randomInt"
$region = "eastus"
$keyName = "key-tfstate-cmk"
$MyIdentityDEV = "umi-dev-tfcore$randomInt"
$MyIdentityUAT = "umi-uat-tfcore$randomInt"
$MyIdentityPRD = "umi-prd-tfcore$randomInt"
# Create a resource resourceGroupName
az group create --name "$resourceGroupName" --location "$region"
# Create a Key Vault
az keyvault create `
--name "$kvName" `
--resource-group "$resourceGroupName" `
--location "$region" `
--enable-rbac-authorization `
--enable-purge-protection true `
--retention-days 90
#set kv Resource ID
$kvResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.KeyVault/vaults/$kvName"
# Authorize the operation to create a few secrets/keys - Signed in User (Key Vault Secrets Officer)
az ad signed-in-user show --query id -o tsv | foreach-object {
az role assignment create `
--role "Key Vault Secrets Officer" `
--assignee "$_" `
--scope $kvResourceId
az role assignment create `
--role "Key Vault Crypto Service Encryption User" `
--assignee "$_" `
--scope $kvResourceId
az role assignment create `
--role "Key Vault Crypto Officer" `
--assignee "$_" `
--scope $kvResourceId
}
#set var for exp date 1 year from today
$ExpDate = (Get-Date).AddYears(1).ToString("yyyy-MM-dTH:mZ")
# create kv key for storage cmk
az keyvault key create --name $keyName --vault-name $kvName --kty RSA --size 2048 --expires $ExpDate
# set json policy for key rotation
$jsonpolicy = '{
"lifetimeActions": [
{
"trigger": {
"timeAfterCreate": null,
"timeBeforeExpiry" : "P10D"
},
"action": {
"type": "Rotate"
}
},
{
"trigger": {
"timeBeforeExpiry" : "P30D"
},
"action": {
"type": "Notify"
}
}
],
"attributes": {
"expiryTime": "P1Y"
}
}'
# update kv with rotation policy
az keyvault key rotation-policy update -n $keyName --vault-name $kvName --value $jsonpolicy
# create user managed identity to set to storage account
az identity create `
--name $MyIdentityDEV `
--resource-group $resourceGroupName `
--location "$region"
az identity create `
--name $MyIdentityUAT `
--resource-group $resourceGroupName `
--location "$region"
az identity create `
--name $MyIdentityPRD `
--resource-group $resourceGroupName `
--location "$region"
# get identityResourceId
$identityResourceIdDEV=$(az identity show --name $MyIdentityDEV `
--resource-group $resourceGroupName `
--query id `
--output tsv)
$identityResourceIdUAT=$(az identity show --name $MyIdentityUAT `
--resource-group $resourceGroupName `
--query id `
--output tsv)
$identityResourceIdPRD=$(az identity show --name $MyIdentityPRD `
--resource-group $resourceGroupName `
--query id `
--output tsv)
# get principal id
$principalIdDEV=$(az identity show --name $MyIdentityDEV `
--resource-group $resourceGroupName `
--query principalId `
--output tsv)
$principalIdUAT=$(az identity show --name $MyIdentityUAT `
--resource-group $resourceGroupName `
--query principalId `
--output tsv)
$principalIdPRD=$(az identity show --name $MyIdentityPRD `
--resource-group $resourceGroupName `
--query principalId `
--output tsv)
# set rbac in kv for managed id
az role assignment create `
--role "Key Vault Crypto Service Encryption User" `
--assignee $principalIdDEV `
--scope $kvResourceId
az role assignment create `
--role "Key Vault Crypto Service Encryption User" `
--assignee $principalIdUAT `
--scope $kvResourceId
az role assignment create `
--role "Key Vault Crypto Service Encryption User" `
--assignee $principalIdPRD `
--scope $kvResourceId
#set kv uri
$vaultUri = "https://$kvName.vault.azure.net/"
# Create an azure storage account - Terraform Backend Storage Account
az storage account create `
--name "$storageNameDEV" `
--location "$region" `
--resource-group "$resourceGroupName" `
--sku "Standard_GRS" `
--kind "StorageV2" `
--https-only true `
--min-tls-version "TLS1_2" `
--allow-blob-public-access false `
--require-infrastructure-encryption true `
--identity-type SystemAssigned,UserAssigned `
--user-identity-id $identityResourceIdDEV `
--encryption-key-vault $vaultUri `
--encryption-key-name $keyName `
--encryption-key-source Microsoft.Keyvault `
--key-vault-user-identity-id $identityResourceIdDEV
az storage account create `
--name "$storageNameUAT" `
--location "$region" `
--resource-group "$resourceGroupName" `
--sku "Standard_GRS" `
--kind "StorageV2" `
--https-only true `
--min-tls-version "TLS1_2" `
--allow-blob-public-access false `
--require-infrastructure-encryption true `
--identity-type SystemAssigned,UserAssigned `
--user-identity-id $identityResourceIdUAT `
--encryption-key-vault $vaultUri `
--encryption-key-name $keyName `
--encryption-key-source Microsoft.Keyvault `
--key-vault-user-identity-id $identityResourceIdUAT
az storage account create `
--name "$storageNamePRD" `
--location "$region" `
--resource-group "$resourceGroupName" `
--sku "Standard_GRS" `
--kind "StorageV2" `
--https-only true `
--min-tls-version "TLS1_2" `
--allow-blob-public-access false `
--require-infrastructure-encryption true `
--identity-type SystemAssigned,UserAssigned `
--user-identity-id $identityResourceIdPRD `
--encryption-key-vault $vaultUri `
--encryption-key-name $keyName `
--encryption-key-source Microsoft.Keyvault `
--key-vault-user-identity-id $identityResourceIdPRD
# Authorize the operation to create the container - Signed in User (Storage Blob Data Contributor Role)
az ad signed-in-user show --query id -o tsv | foreach-object {
az role assignment create `
--role "Storage Blob Data Contributor" `
--assignee "$_" `
--scope "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Storage/storageAccounts/$storageNameDEV"
}
az ad signed-in-user show --query id -o tsv | foreach-object {
az role assignment create `
--role "Storage Blob Data Contributor" `
--assignee "$_" `
--scope "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Storage/storageAccounts/$storageNameUAT"
}
az ad signed-in-user show --query id -o tsv | foreach-object {
az role assignment create `
--role "Storage Blob Data Contributor" `
--assignee "$_" `
--scope "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Storage/storageAccounts/$storageNamePRD"
}
#Create Upload container in storage account to store terraform state files
Start-Sleep -s 30
az storage container create `
--account-name "$storageNameDEV" `
--name "tfstate" `
--auth-mode login
az storage container create `
--account-name "$storageNameUAT" `
--name "tfstate" `
--auth-mode login
az storage container create `
--account-name "$storageNamePRD" `
--name "tfstate" `
--auth-mode login
#set soft delete, retention and verzioning
az storage account blob-service-properties update --account-name "$storageNameDEV" `
--resource-group $resourceGroupName `
--enable-change-feed true `
--enable-delete-retention true `
--enable-container-delete-retention true `
--enable-versioning true `
--enable-restore-policy true `
--restore-days 6 `
--container-delete-retention-days 7 `
--delete-retention-days 7
az storage account blob-service-properties update --account-name "$storageNameUAT" `
--resource-group $resourceGroupName `
--enable-change-feed true `
--enable-delete-retention true `
--enable-container-delete-retention true `
--enable-versioning true `
--enable-restore-policy true `
--restore-days 6 `
--container-delete-retention-days 7 `
--delete-retention-days 7
az storage account blob-service-properties update --account-name "$storageNamePRD" `
--resource-group $resourceGroupName `
--enable-change-feed true `
--enable-delete-retention true `
--enable-container-delete-retention true `
--enable-versioning true `
--enable-restore-policy true `
--restore-days 6 `
--container-delete-retention-days 7 `
--delete-retention-days 7
az storage account management-policy create `
--account-name "$storageNameDEV" `
--resource-group $resourceGroupName `
--policy '@policyblob.json'
az storage account management-policy create `
--account-name "$storageNameUAT" `
--resource-group $resourceGroupName `
--policy '@policyblob.json'
az storage account management-policy create `
--account-name "$storageNamePRD" `
--resource-group $resourceGroupName `
--policy '@policyblob.json'
# Create Terraform Service Principal and assign RBAC Role on Key Vault
$spnJSON = az ad sp create-for-rbac --name $appName `
--role "Key Vault Secrets Officer" `
--scopes /subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.KeyVault/vaults/$kvName
# Save new Terraform Service Principal details to key vault
$spnObj = $spnJSON | ConvertFrom-Json
foreach($object_properties in $spnObj.psobject.properties) {
If ($object_properties.Name -eq "appId") {
$null = az keyvault secret set --vault-name $kvName --name "ARM-CLIENT-ID" --value $object_properties.Value
}
If ($object_properties.Name -eq "password") {
$null = az keyvault secret set --vault-name $kvName --name "ARM-CLIENT-SECRET" --value $object_properties.Value
}
If ($object_properties.Name -eq "tenant") {
$null = az keyvault secret set --vault-name $kvName --name "ARM-TENANT-ID" --value $object_properties.Value
}
}
$null = az keyvault secret set --vault-name $kvName --name "ARM-SUBSCRIPTION-ID" --value $subscriptionId
# Assign additional RBAC role to Terraform Service Principal Subscription as Contributor and access to backend storage
az ad sp list --display-name $appName --query [].appId -o tsv | ForEach-Object {
az role assignment create --assignee "$_" `
--role "Owner" `
--subscription $subscriptionId `
--scope "/subscriptions/$subscriptionId"
az role assignment create --assignee "$_" `
--role "Storage Blob Data Contributor" `
--scope "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Storage/storageAccounts/$storageNameDEV"
az role assignment create --assignee "$_" `
--role "Storage Blob Data Contributor" `
--scope "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Storage/storageAccounts/$storageNameUAT"
az role assignment create --assignee "$_" `
--role "Storage Blob Data Contributor" `
--scope "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Storage/storageAccounts/$storageNamePRD" `
}
#lock rg delete
az group lock create --lock-type CanNotDelete `
--name "DoNotDelete" `
--resource-group $resourceGroupName `
--notes "Protect tf state rg"