Azure Managed Disk 共享不灵,EventGrid + LogicApp 来搞

前言:

        童鞋们估计已经抱怨过n次这个问题,为啥托管磁盘不能被用来制作镜像或者制作快照后在其他订阅或其它区域(Region)来创建虚拟机,说好的 Infrastructure as a code 呢,刚刚激动的做好了镜像,把应用架构描述成 infra code,一键点亮。跨了订阅,跨了区域玩不转啦,XX**。不要慌,这个事儿并非没有解,就是稍微麻烦,你可以把托管磁盘做导出到目标订阅或区域的存储账户,然后在目标订阅内或区域内创建镜像。一两个订阅还好,一大把订阅那不是很坑,本文后面就带大家以玩的心态,边了解 Azure 的新服务 EventGrid,LogicApp,ACI,然后一起来配合使用来实现跨订阅或跨地域的托管磁盘的自动导出拷贝。

架构逻辑:

        通过 EventGrid 来监听 VM 创建事件,当事件发生后,LogicApp 作为该事件的 Subscriber 消费者,触发自动化流水线,将该虚拟机的磁盘拷贝到目的订阅或目的区域的存储账户中,拷贝过程通过azcopy来完成,选择azcopy的原因速度块。整个架构中采用 Severless 的思路,所以将 azcopy 封装到一个做好的容器镜像中,在调用时通过在 Serverless 的 Azure Container Instance 中进行执行,执行完毕资源回收,可以享受容器启动的敏捷性的同时实现按市场付费计算资源的要求。

逻辑实现细节:

        整个逻辑实现的重点在LogicApp,也就是自动化流水线的实现,流水线的规程可以参阅如下 LogicApp 的 Code,大家可以导入自己的环境在里面进行学习和修改。犯懒的童鞋也别难过,借此安利一把,Image 共享这个服务 Azure 平台马上会当作功能给到大家 Preview,点我了解更多

  1 {
  2     "$connections": {
  3         "value": {
  4             "aci": {
  5                 "connectionId": "/subscriptions/c04b3c63-8dfe-4f98-be18-e71ff67a1f4e/resourceGroups/eventgrid/providers/Microsoft.Web/connections/aci",
  6                 "connectionName": "aci",
  7                 "id": "/subscriptions/c04b3c63-8dfe-4f98-be18-e71ff67a1f4e/providers/Microsoft.Web/locations/southeastasia/managedApis/aci"
  8             },
  9             "arm": {
 10                 "connectionId": "/subscriptions/c04b3c63-8dfe-4f98-be18-e71ff67a1f4e/resourceGroups/eventgrid/providers/Microsoft.Web/connections/arm",
 11                 "connectionName": "arm",
 12                 "id": "/subscriptions/c04b3c63-8dfe-4f98-be18-e71ff67a1f4e/providers/Microsoft.Web/locations/southeastasia/managedApis/arm"
 13             },
 14             "azureeventgrid": {
 15                 "connectionId": "/subscriptions/c04b3c63-8dfe-4f98-be18-e71ff67a1f4e/resourceGroups/eventgrid/providers/Microsoft.Web/connections/azureeventgrid",
 16                 "connectionName": "azureeventgrid",
 17                 "id": "/subscriptions/c04b3c63-8dfe-4f98-be18-e71ff67a1f4e/providers/Microsoft.Web/locations/southeastasia/managedApis/azureeventgrid"
 18             }
 19         }
 20     },
 21     "definition": {
 22         "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
 23         "actions": {
 24             "Compose": {
 25                 "inputs": {
 26                     "vmname": "@substring(body('Parse_JSON')?['subject'],add(16,lastIndexOf(body('Parse_JSON')?['subject'],'virtualMachines/')),sub(length(body('Parse_JSON')?['subject']),add(16,lastIndexOf(body('Parse_JSON')?['subject'],'virtualMachines/'))))"
 27                 },
 28                 "runAfter": {
 29                     "Parse_JSON": [
 30                         "Succeeded"
 31                     ]
 32                 },
 33                 "type": "Compose"
 34             },
 35             "Compose_2": {
 36                 "inputs": "@triggerBody()",
 37                 "runAfter": {},
 38                 "type": "Compose"
 39             },
 40             "Compose_3": {
 41                 "inputs": "@body('Parse_JSON_3')?['storageProfile']['osDisk']",
 42                 "runAfter": {
 43                     "Parse_JSON_3": [
 44                         "Succeeded"
 45                     ]
 46                 },
 47                 "type": "Compose"
 48             },
 49             "Create_container_group": {
 50                 "inputs": {
 51                     "body": {
 52                         "location": "southeastasia",
 53                         "properties": {
 54                             "containers": [
 55                                 {
 56                                     "name": "@{concat('azcp',rand(1,100))}",
 57                                     "properties": {
 58                                         "command": [
 59                                             "/bin/bash",
 60                                             "-c",
 61                                             "azcopy --destination $destination --source $source --dest-key $destkey"
 62                                         ],
 63                                         "environmentVariables": [
 64                                             {
 65                                                 "name": "destination",
 66                                                 "value": "@{concat('https://diskclone.blob.core.windows.net/diskclone/',outputs('Compose_3')?['name'])}"
 67                                             },
 68                                             {
 69                                                 "name": "source",
 70                                                 "value": "@body('mdsasurl')?['accessSAS']"
 71                                             },
 72                                             {
 73                                                 "name": "destkey",
 74                                                 "value": "yrbf9VRMOFN70+tAmoianfx1TGwJPAp+26aQ2g7EdB+4UqNBSoa3bJP9uEwJy2eGUz5y1NPnZx8XuKJP0W3p8w=="
 75                                             }
 76                                         ],
 77                                         "image": "acrbuildpilot.azurecr.io/azcopy:v1",
 78                                         "resources": {
 79                                             "requests": {
 80                                                 "cpu": 1,
 81                                                 "memoryInGB": 1
 82                                             }
 83                                         }
 84                                     }
 85                                 }
 86                             ],
 87                             "imageRegistryCredentials": [
 88                                 {
 89                                     "password": "iKccXllxyrn8aoSfPtQdUZTzDLIh/VRv",
 90                                     "server": "acrbuildpilot.azurecr.io",
 91                                     "username": "acrbuildpilot"
 92                                 }
 93                             ],
 94                             "osType": "Linux",
 95                             "restartPolicy": "Never"
 96                         }
 97                     },
 98                     "host": {
 99                         "connection": {
100                             "name": "@parameters('$connections')['aci']['connectionId']"
101                         }
102                     },
103                     "method": "put",
104                     "path": "/subscriptions/@{encodeURIComponent('4507938f-a0ac-4571-978e-7cc741a60af8')}/resourceGroups/@{encodeURIComponent('aci')}/providers/Microsoft.ContainerInstance/containerGroups/@{encodeURIComponent(concat('azcp', rand(1, 100)))}",
105                     "queries": {
106                         "x-ms-api-version": "2017-10-01-preview"
107                     }
108                 },
109                 "runAfter": {
110                     "mdsasurl": [
111                         "Succeeded"
112                     ]
113                 },
114                 "type": "ApiConnection"
115             },
116             "Parse_JSON": {
117                 "inputs": {
118                     "content": "@outputs('Compose_2')",
119                     "schema": {
120                         "properties": {
121                             "data": {
122                                 "properties": {
123                                     "authorization": {
124                                         "properties": {
125                                             "action": {
126                                                 "type": "string"
127                                             },
128                                             "evidence": {
129                                                 "properties": {
130                                                     "role": {
131                                                         "type": "string"
132                                                     }
133                                                 },
134                                                 "type": "object"
135                                             },
136                                             "scope": {
137                                                 "type": "string"
138                                             }
139                                         },
140                                         "type": "object"
141                                     },
142                                     "claims": {
143                                         "properties": {
144                                             "aio": {
145                                                 "type": "string"
146                                             },
147                                             "appid": {
148                                                 "type": "string"
149                                             },
150                                             "appidacr": {
151                                                 "type": "string"
152                                             },
153                                             "aud": {
154                                                 "type": "string"
155                                             },
156                                             "e_exp": {
157                                                 "type": "string"
158                                             },
159                                             "exp": {
160                                                 "type": "string"
161                                             },
162                                             "groups": {
163                                                 "type": "string"
164                                             },
165                                             "http://schemas.microsoft.com/2012/01/devicecontext/claims/identifier": {
166                                                 "type": "string"
167                                             },
168                                             "http://schemas.microsoft.com/claims/authnclassreference": {
169                                                 "type": "string"
170                                             },
171                                             "http://schemas.microsoft.com/claims/authnmethodsreferences": {
172                                                 "type": "string"
173                                             },
174                                             "http://schemas.microsoft.com/identity/claims/objectidentifier": {
175                                                 "type": "string"
176                                             },
177                                             "http://schemas.microsoft.com/identity/claims/scope": {
178                                                 "type": "string"
179                                             },
180                                             "http://schemas.microsoft.com/identity/claims/tenantid": {
181                                                 "type": "string"
182                                             },
183                                             "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname": {
184                                                 "type": "string"
185                                             },
186                                             "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": {
187                                                 "type": "string"
188                                             },
189                                             "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier": {
190                                                 "type": "string"
191                                             },
192                                             "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname": {
193                                                 "type": "string"
194                                             },
195                                             "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn": {
196                                                 "type": "string"
197                                             },
198                                             "iat": {
199                                                 "type": "string"
200                                             },
201                                             "in_corp": {
202                                                 "type": "string"
203                                             },
204                                             "ipaddr": {
205                                                 "type": "string"
206                                             },
207                                             "iss": {
208                                                 "type": "string"
209                                             },
210                                             "name": {
211                                                 "type": "string"
212                                             },
213                                             "nbf": {
214                                                 "type": "string"
215                                             },
216                                             "onprem_sid": {
217                                                 "type": "string"
218                                             },
219                                             "puid": {
220                                                 "type": "string"
221                                             },
222                                             "uti": {
223                                                 "type": "string"
224                                             },
225                                             "ver": {
226                                                 "type": "string"
227                                             }
228                                         },
229                                         "type": "object"
230                                     },
231                                     "correlationId": {
232                                         "type": "string"
233                                     },
234                                     "operationName": {
235                                         "type": "string"
236                                     },
237                                     "resourceProvider": {
238                                         "type": "string"
239                                     },
240                                     "resourceUri": {
241                                         "type": "string"
242                                     },
243                                     "status": {
244                                         "type": "string"
245                                     },
246                                     "subscriptionId": {
247                                         "type": "string"
248                                     },
249                                     "tenantId": {
250                                         "type": "string"
251                                     }
252                                 },
253                                 "type": "object"
254                             },
255                             "dataVersion": {
256                                 "type": "string"
257                             },
258                             "eventTime": {
259                                 "type": "string"
260                             },
261                             "eventType": {
262                                 "type": "string"
263                             },
264                             "id": {
265                                 "type": "string"
266                             },
267                             "metadataVersion": {
268                                 "type": "string"
269                             },
270                             "subject": {
271                                 "type": "string"
272                             },
273                             "topic": {
274                                 "type": "string"
275                             }
276                         },
277                         "type": "object"
278                     }
279                 },
280                 "runAfter": {
281                     "Compose_2": [
282                         "Succeeded"
283                     ]
284                 },
285                 "type": "ParseJson"
286             },
287             "Parse_JSON_2": {
288                 "inputs": {
289                     "content": "@outputs('Compose')",
290                     "schema": {
291                         "properties": {
292                             "vmname": {
293                                 "type": "string"
294                             }
295                         },
296                         "type": "object"
297                     }
298                 },
299                 "runAfter": {
300                     "Compose": [
301                         "Succeeded"
302                     ]
303                 },
304                 "type": "ParseJson"
305             },
306             "Parse_JSON_3": {
307                 "inputs": {
308                     "content": "@body('Read_a_resource')?['properties']",
309                     "schema": {
310                         "properties": {
311                             "hardwareProfile": {
312                                 "properties": {
313                                     "vmSize": {
314                                         "type": "string"
315                                     }
316                                 },
317                                 "type": "object"
318                             },
319                             "networkProfile": {
320                                 "properties": {
321                                     "networkInterfaces": {
322                                         "items": {
323                                             "properties": {
324                                                 "id": {
325                                                     "type": "string"
326                                                 }
327                                             },
328                                             "required": [
329                                                 "id"
330                                             ],
331                                             "type": "object"
332                                         },
333                                         "type": "array"
334                                     }
335                                 },
336                                 "type": "object"
337                             },
338                             "osProfile": {
339                                 "properties": {
340                                     "adminUsername": {
341                                         "type": "string"
342                                     },
343                                     "computerName": {
344                                         "type": "string"
345                                     },
346                                     "linuxConfiguration": {
347                                         "properties": {
348                                             "disablePasswordAuthentication": {
349                                                 "type": "boolean"
350                                             }
351                                         },
352                                         "type": "object"
353                                     },
354                                     "secrets": {
355                                         "type": "array"
356                                     }
357                                 },
358                                 "type": "object"
359                             },
360                             "provisioningState": {
361                                 "type": "string"
362                             },
363                             "storageProfile": {
364                                 "properties": {
365                                     "dataDisks": {
366                                         "type": "array"
367                                     },
368                                     "imageReference": {
369                                         "properties": {
370                                             "offer": {
371                                                 "type": "string"
372                                             },
373                                             "publisher": {
374                                                 "type": "string"
375                                             },
376                                             "sku": {
377                                                 "type": "string"
378                                             },
379                                             "version": {
380                                                 "type": "string"
381                                             }
382                                         },
383                                         "type": "object"
384                                     },
385                                     "osDisk": {
386                                         "properties": {
387                                             "caching": {
388                                                 "type": "string"
389                                             },
390                                             "createOption": {
391                                                 "type": "string"
392                                             },
393                                             "diskSizeGB": {
394                                                 "type": "number"
395                                             },
396                                             "managedDisk": {
397                                                 "properties": {
398                                                     "id": {
399                                                         "type": "string"
400                                                     },
401                                                     "storageAccountType": {
402                                                         "type": "string"
403                                                     }
404                                                 },
405                                                 "type": "object"
406                                             },
407                                             "name": {
408                                                 "type": "string"
409                                             },
410                                             "osType": {
411                                                 "type": "string"
412                                             }
413                                         },
414                                         "type": "object"
415                                     }
416                                 },
417                                 "type": "object"
418                             },
419                             "vmId": {
420                                 "type": "string"
421                             }
422                         },
423                         "type": "object"
424                     }
425                 },
426                 "runAfter": {
427                     "Read_a_resource": [
428                         "Succeeded"
429                     ]
430                 },
431                 "type": "ParseJson"
432             },
433             "Read_a_resource": {
434                 "inputs": {
435                     "host": {
436                         "connection": {
437                             "name": "@parameters('$connections')['arm']['connectionId']"
438                         }
439                     },
440                     "method": "get",
441                     "path": "/subscriptions/@{encodeURIComponent('c04b3c63-8dfe-4f98-be18-e71ff67a1f4e')}/resourcegroups/@{encodeURIComponent('eventgrid')}/providers/@{encodeURIComponent('Microsoft.Compute')}/@{encodeURIComponent(concat('virtualMachines/', body('Parse_JSON_2')?['vmname']))}",
442                     "queries": {
443                         "x-ms-api-version": "2017-12-01"
444                     }
445                 },
446                 "runAfter": {
447                     "Parse_JSON_2": [
448                         "Succeeded"
449                     ]
450                 },
451                 "type": "ApiConnection"
452             },
453             "deallocate_vm": {
454                 "inputs": {
455                     "host": {
456                         "connection": {
457                             "name": "@parameters('$connections')['arm']['connectionId']"
458                         }
459                     },
460                     "method": "post",
461                     "path": "/subscriptions/@{encodeURIComponent('c04b3c63-8dfe-4f98-be18-e71ff67a1f4e')}/resourcegroups/@{encodeURIComponent('eventgrid')}/providers/@{encodeURIComponent('Microsoft.Compute')}/@{encodeURIComponent(concat('virtualMachines/', body('Parse_JSON_2')?['vmname']))}/@{encodeURIComponent('deallocate')}",
462                     "queries": {
463                         "x-ms-api-version": "2017-12-01"
464                     }
465                 },
466                 "runAfter": {
467                     "Compose_3": [
468                         "Succeeded"
469                     ]
470                 },
471                 "type": "ApiConnection"
472             },
473             "mdsasurl": {
474                 "inputs": {
475                     "content": "@body('storage_sasurl')",
476                     "schema": {
477                         "properties": {
478                             "accessSAS": {
479                                 "type": "string"
480                             }
481                         },
482                         "type": "object"
483                     }
484                 },
485                 "runAfter": {
486                     "storage_sasurl": [
487                         "Succeeded"
488                     ]
489                 },
490                 "type": "ParseJson"
491             },
492             "storage_sasurl": {
493                 "inputs": {
494                     "body": {
495                         "access": "Read",
496                         "durationInSeconds": 3600
497                     },
498                     "host": {
499                         "connection": {
500                             "name": "@parameters('$connections')['arm']['connectionId']"
501                         }
502                     },
503                     "method": "post",
504                     "path": "/subscriptions/@{encodeURIComponent('c04b3c63-8dfe-4f98-be18-e71ff67a1f4e')}/resourcegroups/@{encodeURIComponent('eventgrid')}/providers/@{encodeURIComponent('Microsoft.Compute')}/@{encodeURIComponent(concat('disks/', outputs('Compose_3')?['name']))}/@{encodeURIComponent('beginGetAccess')}",
505                     "queries": {
506                         "x-ms-api-version": "2017-03-30"
507                     }
508                 },
509                 "runAfter": {
510                     "deallocate_vm": [
511                         "Succeeded"
512                     ]
513                 },
514                 "type": "ApiConnection"
515             }
516         },
517         "contentVersion": "1.0.0.0",
518         "outputs": {},
519         "parameters": {
520             "$connections": {
521                 "defaultValue": {},
522                 "type": "Object"
523             }
524         },
525         "triggers": {
526             "When_a_resource_event_occurs": {
527                 "inputs": {
528                     "body": {
529                         "properties": {
530                             "destination": {
531                                 "endpointType": "webhook",
532                                 "properties": {
533                                     "endpointUrl": "@{listCallbackUrl()}"
534                                 }
535                             },
536                             "filter": {
537                                 "includedEventTypes": [
538                                     "Microsoft.Resources.ResourceWriteSuccess"
539                                 ],
540                                 "subjectBeginsWith": "/subscriptions/c04b3c63-8dfe-4f98-be18-e71ff67a1f4e/resourcegroups/eventgrid/providers/Microsoft.Compute/virtualMachines"
541                             },
542                             "topic": "/subscriptions/c04b3c63-8dfe-4f98-be18-e71ff67a1f4e/resourceGroups/eventgrid"
543                         }
544                     },
545                     "host": {
546                         "connection": {
547                             "name": "@parameters('$connections')['azureeventgrid']['connectionId']"
548                         }
549                     },
550                     "path": "/subscriptions/@{encodeURIComponent('c04b3c63-8dfe-4f98-be18-e71ff67a1f4e')}/providers/@{encodeURIComponent('Microsoft.Resources.ResourceGroups')}/resource/eventSubscriptions",
551                     "queries": {
552                         "x-ms-api-version": "2017-09-15-preview"
553                     }
554                 },
555                 "splitOn": "@triggerBody()",
556                 "type": "ApiConnectionWebhook"
557             }
558         }
559     }
560 }

参考资料:

       因为 EventGrid 和 LogicApp 学习成本都非常低,所以没有 Step by Step 给大家说明操作步骤,这里为了方便大家学习,给大家列举几个文档,帮助大家快速上手。

EventGrid 入门:https://docs.microsoft.com/en-us/azure/event-grid/overview

EventGrid 消息格式:https://docs.microsoft.com/en-us/azure/event-grid/event-schema

LogicApp 入门:https://docs.microsoft.com/en-us/azure/logic-apps/logic-apps-overview

LogicApp Connector 手册:https://docs.microsoft.com/en-us/connectors/

LogicApp 内置函数手册:https://docs.microsoft.com/en-us/azure/logic-apps/workflow-definition-language-functions-reference

 

posted @ 2018-05-17 00:53 wekang 阅读(...) 评论(...) 编辑 收藏