无法使用已装载存储的 Linux 部署 Azure 应用服务的 ARM 模板
Posted
技术标签:
【中文标题】无法使用已装载存储的 Linux 部署 Azure 应用服务的 ARM 模板【英文标题】:Can not deploy ARM template of Azure App Service with Linux that has mounted storage 【发布时间】:2021-11-08 23:53:54 【问题描述】:我们正在尝试部署 Azure Linux 应用服务,该服务也已挂载存储。这是我们的 ARM 模板
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters":
"Environment":
"type": "String",
"allowedValues": [
"dev",
"stg",
"prd"
]
,
"Region":
"type": "string",
"allowedValues": [
"eu",
"we"
]
,
"MagentoMediaFileShareName":
"type": "string"
,
"StorageAccountName":
"type": "string"
,
"StorageAccountAccessKey":
"type": "securestring"
,
"MagentoMediaMountPath":
"type": "string",
"defaultValue": "/var/www/html/pub/external_media"
,
"variables":
"Location": "[resourceGroup().location]",
"ResourcePrefix": "[format('ariva-0-1-magento', parameters('Environment'), parameters('Region'))]",
"WebSiteName": "[concat(variables('ResourcePrefix'), '-web')]",
"ServicePlanId": "[format('/subscriptions/0/resourceGroups/ariva-1-2/providers/Microsoft.Web/serverfarms/ariva-1-2-asp', subscription().subscriptionId, parameters('Environment'), parameters('Region'))]"
,
"resources": [
"type": "Microsoft.Web/sites",
"apiVersion": "2020-12-01",
"name": "[variables('WebSiteName')]",
"location": "[variables('Location')]",
"kind": "app,linux,container",
"properties":
"enabled": true,
"hostNameSslStates": [
"name": "[concat(variables('WebSiteName'), '.azurewebsites.net')]",
"sslState": "Disabled",
"hostType": "Standard"
,
"name": "[concat(variables('WebSiteName'), '.scm.azurewebsites.net')]",
"sslState": "Disabled",
"hostType": "Repository"
],
"serverFarmId": "[variables('ServicePlanId')]",
"reserved": true,
"isXenon": false,
"hyperV": false,
"siteConfig":
"numberOfWorkers": 1,
"linuxFxVersion": "DOCKER|mcr.microsoft.com/appsvc/staticsite:latest",
"acrUseManagedIdentityCreds": false,
"alwaysOn": false,
"http20Enabled": false,
"functionAppScaleLimit": 0,
"minimumElasticInstanceCount": 1
,
"scmSiteAlsoStopped": false,
"clientAffinityEnabled": false,
"clientCertEnabled": false,
"clientCertMode": "Required",
"hostNamesDisabled": false,
"customDomainVerificationId": "1071794BD68C78EC0A4569F03C034F6E1B21BD4E6D35725D99523AC00AE12AA1",
"containerSize": 0,
"dailyMemoryTimeQuota": 0,
"keyVaultReferenceIdentity": "SystemAssigned",
"httpsOnly": false,
"redundancyMode": "None",
"storageAccountRequired": false
,
"type": "Microsoft.Web/sites/basicPublishingCredentialsPolicies",
"apiVersion": "2020-12-01",
"name": "[concat(variables('WebSiteName'), '/ftp')]",
"location": "[variables('Location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('WebSiteName'))]"
],
"properties":
"allow": true
,
"type": "Microsoft.Web/sites/basicPublishingCredentialsPolicies",
"apiVersion": "2020-12-01",
"name": "[concat(variables('WebSiteName'), '/scm')]",
"location": "[variables('Location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('WebSiteName'))]"
],
"properties":
"allow": true
,
"type": "Microsoft.Web/sites/config",
"apiVersion": "2020-12-01",
"name": "[concat(variables('WebSiteName'), '/web')]",
"location": "[variables('Location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('WebSiteName'))]"
],
"properties":
"numberOfWorkers": 1,
"defaultDocuments": [
"Default.htm",
"Default.html",
"Default.asp",
"index.htm",
"index.html",
"iisstart.htm",
"default.aspx",
"index.php",
"hostingstart.html"
],
"netFrameworkVersion": "v4.0",
"linuxFxVersion": "DOCKER|mcr.microsoft.com/appsvc/staticsite:latest",
"requestTracingEnabled": false,
"remoteDebuggingEnabled": false,
"remoteDebuggingVersion": "VS2019",
"httpLoggingEnabled": false,
"acrUseManagedIdentityCreds": false,
"logsDirectorySizeLimit": 35,
"detailedErrorLoggingEnabled": false,
"publishingUsername": "[concat('$', variables('WebSiteName'))]",
"azureStorageAccounts":
"magento-media":
"type": "AzureFiles",
"accountName": "[parameters('StorageAccountName')]",
"shareName": "[parameters('MagentoMediaFileShareName')]",
"mountPath": "[parameters('MagentoMediaMountPath')]",
"accessKey": "[parameters('StorageAccountAccessKey')]"
,
"scmType": "None",
"use32BitWorkerProcess": true,
"webSocketsEnabled": true,
"alwaysOn": true,
"managedPipelineMode": "Integrated",
"virtualApplications": [
"virtualPath": "/",
"physicalPath": "site\\wwwroot",
"preloadEnabled": false
],
"loadBalancing": "LeastRequests",
"experiments":
"rampUpRules": []
,
"autoHealEnabled": false,
"vnetRouteAllEnabled": false,
"vnetPrivatePortsCount": 0,
"localmysqlEnabled": false,
"ipSecurityRestrictions": [
"ipAddress": "Any",
"action": "Allow",
"priority": 1,
"name": "Allow all",
"description": "Allow all access"
],
"scmIpSecurityRestrictions": [
"ipAddress": "Any",
"action": "Allow",
"priority": 1,
"name": "Allow all",
"description": "Allow all access"
],
"scmIpSecurityRestrictionsUseMain": false,
"http20Enabled": true,
"minTlsVersion": "1.2",
"scmMinTlsVersion": "1.0",
"ftpsState": "AllAllowed",
"preWarmedInstanceCount": 0,
"functionAppScaleLimit": 0,
//"healthCheckPath": "/health_check.php",
"functionsRuntimeScaleMonitoringEnabled": false,
"minimumElasticInstanceCount": 1
,
"type": "Microsoft.Web/sites/hostNameBindings",
"apiVersion": "2020-12-01",
"name": "[concat(variables('WebSiteName'), '/', variables('WebSiteName'), '.azurewebsites.net')]",
"location": "[variables('Location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('WebSiteName'))]"
],
"properties":
"siteName": "[variables('WebSiteName')]",
"hostNameType": "Verified"
]
如果我们执行这个确切的模板,我们将收到以下错误
"status": "Failed",
"error":
"code": "BadRequest",
"message": "Required parameter AccessKey is missing.",
"details": [
"message": "Required parameter AccessKey is missing."
,
"code": "BadRequest"
,
]
如果我们通过门户手动挂载存储并尝试更改配置或添加部署槽,我们会收到相同的错误。
一旦我删除了挂载的存储配置,一切正常。
我们需要在我们的 DevOps 管道中使用它,在部署之前和之后手动卸载-重新安装存储是不可接受的。这将导致重大问题和停机时间。我们可以做些什么来克服这个问题?
更新 1
我尝试手动创建一个完全独立的网络应用程序和存储帐户。例如,当我连接存储挂载并尝试启用运行状况检查时,我得到了同样的错误。我认为 Azure 中存在错误。
更新 2
这是部署依赖存储帐户的模板
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters":
"Environment":
"type": "String",
"allowedValues": [
"dev",
"stg",
"prd"
]
,
"Region":
"type": "string",
"allowedValues": [
"eu",
"we"
]
,
"variables":
"Location": "[resourceGroup().location]",
"StorageAccountName": "[format('ariva01magentostorage', parameters('Environment'), parameters('Region'))]",
"MagentoMediaFileShareName": "magento-media"
,
"resources": [
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-04-01",
"name": "[variables('StorageAccountName')]",
"location": "[variables('Location')]",
"sku":
"name": "Standard_LRS",
"tier": "Standard"
,
"kind": "StorageV2",
"properties":
"allowCrossTenantReplication": true,
"minimumTlsVersion": "TLS1_2",
"allowBlobPublicAccess": true,
"allowSharedKeyAccess": true,
"networkAcls":
"resourceAccessRules": [],
"bypass": "AzureServices",
"virtualNetworkRules": [],
"ipRules": [],
"defaultAction": "Allow"
,
"supportsHttpsTrafficOnly": true,
"encryption":
"services":
"file":
"keyType": "Account",
"enabled": true
,
"blob":
"keyType": "Account",
"enabled": true
,
"keySource": "Microsoft.Storage"
,
"accessTier": "Hot"
,
"type": "Microsoft.Storage/storageAccounts/blobServices",
"apiVersion": "2021-04-01",
"name": "[concat(variables('StorageAccountName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"
],
"sku":
"name": "Standard_LRS",
"tier": "Standard"
,
"properties":
"changeFeed":
"enabled": false
,
"restorePolicy":
"enabled": false
,
"containerDeleteRetentionPolicy":
"enabled": true,
"days": 7
,
"cors":
"corsRules": []
,
"deleteRetentionPolicy":
"enabled": true,
"days": 7
,
"isVersioningEnabled": false
,
"type": "Microsoft.Storage/storageAccounts/fileServices",
"apiVersion": "2021-04-01",
"name": "[concat(variables('StorageAccountName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"
],
"sku":
"name": "Standard_LRS",
"tier": "Standard"
,
"properties":
"shareDeleteRetentionPolicy":
"enabled": true,
"days": 7
,
"type": "Microsoft.Storage/storageAccounts/queueServices",
"apiVersion": "2021-04-01",
"name": "[concat(variables('StorageAccountName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"
],
"properties":
"cors":
"corsRules": []
,
"type": "Microsoft.Storage/storageAccounts/tableServices",
"apiVersion": "2021-04-01",
"name": "[concat(variables('StorageAccountName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"
],
"properties":
"cors":
"corsRules": []
,
"type": "Microsoft.Storage/storageAccounts/fileServices/shares",
"apiVersion": "2021-04-01",
"name": "[concat(variables('StorageAccountName'), '/default/', variables('MagentoMediaFileShareName'))]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('StorageAccountName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"
],
"properties":
"accessTier": "TransactionOptimized",
"shareQuota": 5120,
"enabledProtocols": "SMB"
],
"outputs":
"MagentoMediaFileShareName":
"type": "string",
"value": "[variables('MagentoMediaFileShareName')]"
,
"StorageAccountName":
"type": "string",
"value": "[variables('StorageAccountName')]"
,
"StorageAccountAccessKey":
"type": "securestring",
"value": "[listKeys(variables('StorageAccountName'), '2019-04-01').keys[0].value]"
更新 3 - 临时解决方法
我们找到了临时解决方法。我们没有通过 ARM 模板部署文件挂载,而是从 ARM 模板中删除了该位,之后,我们在 DevOps 管道中使用以下构建步骤通过 azure CLI 挂载存储
- task: AzureCLI@2
displayName: 'Attach media volume'
inputs:
azureSubscription: '$ parameters.azureSubscription '
scriptType: pscore
scriptLocation: inlineScript
inlineScript: |
az webapp config storage-account add `
--resource-group $ parameters.resourceGroup `
--name "$(WebSiteName)" `
--access-key "$(StorageAccountAccessKey)" `
--custom-id magento-media `
--storage-type AzureFiles `
--share-name "$(MagentoMediaFileShareName)" `
--account-name "$(StorageAccountName)" `
--mount-path "/var/www/html/pub/external_media"
这当然不能解决问题。
-
这样做,ARM 模板将实质上移除挂载,然后由脚本部署,导致停机
挂载完成后,我们仍然无法通过门户更改任何 WebApp 属性,我们将收到缺少 AccessKey 的错误
【问题讨论】:
如何配置存储帐户的安全性?也只是为了确认,当//"healthCheckPath": "/health_check.php",
被评论时,您的模板会部署,但如果不是,您会收到错误消息?
@RyanHill-MSFT 我们正在另一个 ARM 模板中部署存储。我们没有任何特定的安全设置。我已经使用我们使用的存储 ARM 模板更新了帖子。然后,我们输出 AccessKey 并将其作为此部署的输入参数提供。至于健康检查,它还没有配置。当我们使用它时,它不会改变行为,无论有没有健康检查,我们仍然会收到 AccessKey 失败。我提到健康检查的原因是,当您通过 GUI 挂载存储并尝试添加健康检查时,会引发相同的错误。
在 Azure 门户中,您设置的存储帐户是否具有访问密钥?我没有遇到你在mounting the storage account to the app service 时遇到的同样问题。
您的设置应该类似于i.imgur.com/Qbwl5cb.png
非常感谢瑞恩。根据以下建议更改 ARM 模板后,就存储安装而言一切正常))
【参考方案1】:
azureStorageAccounts
不是Microsoft.Web sites/config 2020-12-01 的一部分,但它在Microsoft.Web sites 2020-12-01 SiteConfig
属性下。这可能是没有找到、没有上传 accessKey 的原因。我会把azureStorageAccounts
移到siteConfig
下面
【讨论】:
谢谢瑞恩。你其实是对的。这部分回答了我的问题。问题是当您将 WebApp 导出为 ARM 模板时,它会提供不同的 API 版本 2021-01-15,这在 Microsoft 文档中不可用。可用的版本是 2020-12-01,我只是用它替换了导出模板中的值。这显然不起作用,因为架构不同。我们该如何解决这种情况? 您可以使用ARM template tool test kit。如果我没记错的话,ARM 和 Bicep VS Code Extensions 中使用的 linter 就是利用了这个。 确实如此。 Linter 确实帮了一点忙。但我看到的主要问题是,当您导出 WebApp ARM 模板时,它不能开箱即用。此外,它引用的 API 版本至少没有记录,甚至可能不存在,并且 linter 抱怨该版本 我会看看我能找到与 API 版本相关的文档更新的内容。 这真是太棒了!感谢更新。我希望 json 架构也将被发布,以便 VS Code 扩展识别它。以上是关于无法使用已装载存储的 Linux 部署 Azure 应用服务的 ARM 模板的主要内容,如果未能解决你的问题,请参考以下文章