18
18
"defaultValue" : " N/A"
19
19
},
20
20
"location" : {
21
+ "type" : " string"
22
+ },
23
+ "deploymentTimestamp" : {
21
24
"type" : " string" ,
22
- "defaultValue" : " UK South"
25
+ "defaultValue" : " [utcNow()]"
26
+ },
27
+ "devopsServicePrincipalId" : {
28
+ "type" : " string"
29
+ },
30
+ "adlsStorageAccountContainerName" : {
31
+ "type" : " string" ,
32
+ "defaultValue" : " test"
23
33
}
24
34
},
25
35
"variables" : {
26
- "storageAccountApiVersion" : " 2019-06-01" ,
27
- "storageAccountName" : " [concat('adls', substring(uniqueString(parameters('branch')), 0, 4), 'xxxx', substring(parameters('commit'), 0, min(length(parameters('commit')), 7)))]" ,
28
- "storageAccountResourceId" : " [resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
36
+ "storageAccountApiVersion" : " 2021-04-01" ,
37
+ "adlsStorageAccountName" : " [concat('adls', substring(uniqueString(parameters('branch')), 0, 4), 'xxxx', substring(parameters('commit'), 0, min(length(parameters('commit')), 7)))]" ,
38
+ "adlsStorageAccountResourceId" : " [resourceId('Microsoft.Storage/storageAccounts', variables('adlsStorageAccountName'))]" ,
39
+ //"adlsStorageAccountContainerName": "test",
40
+
41
+ "functionsAppApiVersion" : " 2015-08-01" ,
42
+ "functionsAppBlobStorageAccountName" : " [concat('funcblob', substring(uniqueString(parameters('branch')), 0, 4), 'xxxx', substring(parameters('commit'), 0, min(length(parameters('commit')), 7)))]" ,
43
+ "functionsAppName" : " [concat('func', substring(uniqueString(parameters('branch')), 0, 4), 'xxxx', substring(parameters('commit'), 0, min(length(parameters('commit')), 7)))]" ,
44
+
45
+ "authorizationApiVersion" : " 2018-09-01-preview" ,
46
+
47
+ "owner" : " [concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]" ,
48
+ "contributor" : " [concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]" ,
49
+ "reader" : " [concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]" ,
50
+
51
+ "storageBlobDataContributor" : " [concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')]" ,
52
+ "storageBlobDatareader" : " [concat('/subscriptions/', subscription().subscriptionId, '/providers/Microsoft.Authorization/roleDefinitions/', '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1')]"
29
53
},
30
54
"resources" : [
55
+ /********************************************************************************************************************************************
56
+ **** Resource group permissions
57
+ ********************************************************************************************************************************************/
58
+
59
+ // Add the devops service principal as a contributor on the resource group (DevTest Labs is configured to create an RG for
60
+ // each lab).
61
+
62
+ // 'Reader' scoped to the resource group
63
+ {
64
+ "type" : " Microsoft.Authorization/roleAssignments" ,
65
+ "apiVersion" : " [variables('authorizationApiVersion')]" ,
66
+ "name" : " [guid(resourceGroup().id, 'devopsServicePrincipal_rg_contributor')]" ,
67
+ "properties" : {
68
+ "roleDefinitionId" : " [variables('contributor')]" ,
69
+ "principalId" : " [parameters('devopsServicePrincipalId')]"
70
+ }
71
+ },
72
+
73
+ // 'Storage Blob Data Reader' scoped to the storage account
74
+ {
75
+ "type" : " Microsoft.Storage/storageAccounts/providers/roleAssignments" ,
76
+ "name" : " [concat(variables('adlsStorageAccountName'),'/Microsoft.Authorization/',guid(resourceGroup().id, 'devopsServicePrincipal_adlsStorageAccount_storageBlobDataReader'))]" ,
77
+ "apiVersion" : " [variables('authorizationApiVersion')]" ,
78
+ "properties" : {
79
+ "roleDefinitionId" : " [variables('storageBlobDatareader')]" ,
80
+ "principalId" : " [parameters('devopsServicePrincipalId')]"
81
+ },
82
+ "dependsOn" : [
83
+ " [concat('Microsoft.Storage/storageAccounts/', variables('adlsStorageAccountName'))]"
84
+ ]
85
+ },
86
+
87
+ // 'Storage Blob Data Contributor' scoped to the storage account container
88
+ {
89
+ "type" : " Microsoft.Storage/storageAccounts/blobServices/containers/providers/roleAssignments" ,
90
+ //"name": "[concat(variables('adlsStorageAccountName'), '/default/', parameters('adlsStorageAccountContainerName'), '/Microsoft.Authorization/', guid(resourceGroup().id, 'devopsServicePrincipal_adlsStorageAccountContainer', parameters('adlsStorageAccountContainerName'), 'test_storageBlobDataContributor'))]",
91
+ "name" : " [concat(variables('adlsStorageAccountName'), '/default/', parameters('adlsStorageAccountContainerName'), '/Microsoft.Authorization/', guid(resourceGroup().id, parameters('devopsServicePrincipalId'), variables('adlsStorageAccountName'), parameters('adlsStorageAccountContainerName'), variables('storageBlobDataContributor')))]" ,
92
+ "apiVersion" : " [variables('authorizationApiVersion')]" ,
93
+ //"scope": "[concat(resourceGroup().id, '/providers/Microsoft.Storage/storageAccounts/', variables('adlsStorageAccountName'), '/blobServices/containers/containers/', variables('adlsStorageAccountContainerName'))]",
94
+ "properties" : {
95
+ "roleDefinitionId" : " [variables('storageBlobDataContributor')]" ,
96
+ "principalId" : " [parameters('devopsServicePrincipalId')]"
97
+ },
98
+ "dependsOn" : [
99
+ " [concat('Microsoft.Storage/storageAccounts/', variables('adlsStorageAccountName'), '/blobServices/default/containers/', parameters('adlsStorageAccountContainerName'))]"
100
+ ]
101
+ },
102
+
103
+ // Add IAM access for functions app. See the following page for details of how to get the object id for the SPN
104
+ // https://www.codeisahighway.com/there-is-a-new-way-to-reference-managed-identity-in-arm-template/
105
+
106
+ // 'Reader' scoped to the storage account
107
+ {
108
+ "type" : " Microsoft.Storage/storageAccounts/providers/roleAssignments" ,
109
+ "name" : " [concat(variables('adlsStorageAccountName'),'/Microsoft.Authorization/',guid(resourceGroup().id, variables('functionsAppName'), variables('adlsStorageAccountName'), parameters('adlsStorageAccountContainerName'), variables('reader')))]" ,
110
+ "apiVersion" : " [variables('authorizationApiVersion')]" ,
111
+ "properties" : {
112
+ "roleDefinitionId" : " [variables('reader')]" ,
113
+ "principalId" : " [reference(resourceId('Microsoft.Web/sites', variables('functionsAppName')), variables('functionsAppApiVersion'), 'full').identity.principalId]"
114
+ },
115
+ "dependsOn" : [
116
+ " [concat('Microsoft.Storage/storageAccounts/', variables('adlsStorageAccountName'))]" ,
117
+ " [resourceId('Microsoft.Web/sites', variables('functionsAppName'))]"
118
+ ]
119
+ },
120
+
121
+ // 'Storage Blob Data Reader' scoped to the storage account
122
+ {
123
+ "type" : " Microsoft.Storage/storageAccounts/blobServices/containers/providers/roleAssignments" ,
124
+ "name" : " [concat(variables('adlsStorageAccountName'), '/default/', parameters('adlsStorageAccountContainerName'), '/Microsoft.Authorization/', guid(resourceGroup().id, variables('functionsAppName'), variables('adlsStorageAccountName'), parameters('adlsStorageAccountContainerName'), variables('storageBlobDatareader')))]" ,
125
+ "apiVersion" : " [variables('authorizationApiVersion')]" ,
126
+ "properties" : {
127
+ "roleDefinitionId" : " [variables('storageBlobDatareader')]" ,
128
+ "principalId" : " [reference(resourceId('Microsoft.Web/sites', variables('functionsAppName')), variables('functionsAppApiVersion'), 'full').identity.principalId]"
129
+ },
130
+ "dependsOn" : [
131
+ " [concat('Microsoft.Storage/storageAccounts/', variables('adlsStorageAccountName'))]" ,
132
+ " [resourceId('Microsoft.Web/sites', variables('functionsAppName'))]"
133
+ ]
134
+ },
135
+
136
+ /********************************************************************************************************************************************
137
+ **** ADLS storage
138
+ ********************************************************************************************************************************************/
31
139
{
32
- "name" : " [variables('storageAccountName ')]" ,
140
+ "name" : " [variables('adlsStorageAccountName ')]" ,
33
141
"type" : " Microsoft.Storage/storageAccounts" ,
34
142
"apiVersion" : " [variables('storageAccountApiVersion')]" ,
35
143
"location" : " [parameters('location')]" ,
36
144
"properties" : {
37
145
"accessTier" : " Hot" ,
38
146
"minimumTlsVersion" : " TLS1_2" ,
39
147
"supportsHttpsTrafficOnly" : true ,
40
- "allowBlobPublicAccess" : true ,
148
+ "allowBlobPublicAccess" : false ,
41
149
"allowSharedKeyAccess" : true ,
42
150
"isHnsEnabled" : true ,
43
151
"networkAcls" : {
44
152
"bypass" : " AzureServices" ,
45
153
"defaultAction" : " Allow"
46
154
}
47
155
},
48
- "dependsOn" : [],
156
+ "dependsOn" : [
157
+ " [resourceId('Microsoft.Web/sites', variables('functionsAppName'))]"
158
+ ],
49
159
"sku" : {
50
160
"name" : " Standard_LRS"
51
161
},
55
165
"Commit" : " [parameters('commit')]" ,
56
166
"Branch" : " [parameters('branch')]" ,
57
167
"Pull Request" : " [parameters('pullRequest')]" ,
58
- "Create Date Time" : " 2021-04-28T12:08:00"
168
+ "Create Date Time" : " [parameters('deploymentTimestamp')]" ,
169
+ "Git Project Resource Code" : " ADLS" ,
170
+ "RG" : " [resourceGroup().name]"
171
+ },
172
+ "resources" : [
173
+ // Add a container to the storage account
174
+ {
175
+ "name" : " [concat('default/', parameters('adlsStorageAccountContainerName'))]" ,
176
+ "type" : " blobServices/containers" ,
177
+ "apiVersion" : " [variables('storageAccountApiVersion')]" ,
178
+ "properties" : {
179
+ "publicAccess" : " None"
180
+ },
181
+ "dependsOn" : [
182
+ " [variables('adlsStorageAccountName')]"
183
+ ]
184
+ }
185
+ ]
186
+ },
187
+
188
+
189
+ /********************************************************************************************************************************************
190
+ **** Functions Apps
191
+ ********************************************************************************************************************************************/
192
+
193
+ // Blob storage for the functions app
194
+ {
195
+ "apiVersion" : " [variables('storageAccountApiVersion')]" ,
196
+ "type" : " Microsoft.Storage/storageAccounts" ,
197
+ "name" : " [variables('functionsAppBlobStorageAccountName')]" ,
198
+ "location" : " [parameters('location')]" ,
199
+ "tags" : {
200
+ "Git Project" : " [parameters('gitProject')]" ,
201
+ "Commit" : " [parameters('commit')]" ,
202
+ "Branch" : " [parameters('branch')]" ,
203
+ "Pull Request" : " [parameters('pullRequest')]" ,
204
+ "Create Date Time" : " [parameters('deploymentTimestamp')]" ,
205
+ "Git Project Resource Code" : " FunctionsAppStorage"
206
+ },
207
+ "sku" : {
208
+ "name" : " Standard_LRS"
209
+ },
210
+ "properties" : {
211
+ "supportsHttpsTrafficOnly" : true ,
212
+ "minimumTlsVersion" : " TLS1_2"
213
+ }
214
+ },
215
+
216
+ // Functions app, cofigured to use .Net Core 3.X with the blob storage above
217
+ {
218
+ "apiVersion" : " [variables('functionsAppApiVersion')]" ,
219
+ "type" : " Microsoft.Web/sites" ,
220
+ "name" : " [variables('functionsAppName')]" ,
221
+ "location" : " [parameters('location')]" ,
222
+ "kind" : " functionapp" ,
223
+ "identity" : {
224
+ "type" : " SystemAssigned"
225
+ },
226
+ "dependsOn" : [
227
+ " [resourceId('Microsoft.Storage/storageAccounts', variables('functionsAppBlobStorageAccountName'))]"
228
+ ],
229
+ "tags" : {
230
+ "Git Project" : " [parameters('gitProject')]" ,
231
+ "Commit" : " [parameters('commit')]" ,
232
+ "Branch" : " [parameters('branch')]" ,
233
+ "Pull Request" : " [parameters('pullRequest')]" ,
234
+ "Create Date Time" : " [parameters('deploymentTimestamp')]" ,
235
+ "Git Project Resource Code" : " FunctionsApp"
236
+ },
237
+ "properties" : {
238
+ "siteConfig" : {
239
+ "appSettings" : [
240
+ {
241
+ "name" : " FUNCTIONS_EXTENSION_VERSION" ,
242
+ "value" : " ~3"
243
+ },
244
+ {
245
+ "name" : " FUNCTIONS_WORKER_RUNTIME" ,
246
+ "value" : " dotnet"
247
+ },
248
+ {
249
+ "name" : " AzureWebJobsStorage" ,
250
+ "value" : " [concat('DefaultEndpointsProtocol=https;AccountName=',variables('functionsAppBlobStorageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('functionsAppBlobStorageAccountName')), variables('storageAccountApiVersion')).keys[0].value,';EndpointSuffix=','core.windows.net')]"
251
+ }
252
+ ]
253
+ }
59
254
}
60
255
}
61
256
],
257
+
258
+ /********************************************************************************************************************************************
259
+ **** Outputs, does not seem to help when deploying uzing the Azure CLI 'az lab environment create' command
260
+ ********************************************************************************************************************************************/
261
+
62
262
"outputs" : {
63
263
"storageAccountName" : {
64
264
"type" : " string" ,
65
- "value" : " [variables('storageAccountName ')]"
265
+ "value" : " [variables('adlsStorageAccountName ')]"
66
266
},
67
267
"storageAccountConnectionString" : {
68
268
"type" : " string" ,
69
- "value" : " [concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName '), ';AccountKey=', listKeys(variables('storageAccountResourceId '), variables('storageAccountApiVersion')).keys[0].value)]"
269
+ "value" : " [concat('DefaultEndpointsProtocol=https;AccountName=', variables('adlsStorageAccountName '), ';AccountKey=', listKeys(variables('adlsStorageAccountResourceId '), variables('storageAccountApiVersion')).keys[0].value)]"
70
270
}
71
271
}
72
272
}
0 commit comments