I’m attempting to use Azure Resource manager (ARM) template files to deploy as ASP.net website and am hitting a roadblock. This is a nascent feature of Azure so there isn’t much know-how out on the web about it, hoping someone here can help instead.
I can successfully create a new site (i.e. a Microsoft.Web/sites resource) in a new resource group i.e. it works when I define a website in the ARM template like so:
{
"apiVersion": "2014-06-01",
"name": "[parameters('siteName')]",
"type": "Microsoft.Web/sites",
"location": "[parameters('siteLocation')]",
"tags": {
"[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]": "Resource",
"displayName": "Website"
},
"dependsOn": [
"[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]"
],
"properties": {
"name": "[parameters('siteName')]",
"serverFarm": "[parameters('hostingPlanName')]"
}
}
My problem comes when I try to deploy an ASP.net website into it. Here’s what I have added to my ARM template:
{
"apiVersion": "2014-06-01",
"name": "[parameters('siteName')]",
"type": "Microsoft.Web/sites",
"location": "[parameters('siteLocation')]",
"tags": {
"[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]": "Resource",
"displayName": "Website"
},
"dependsOn": [
"[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]"
],
"properties": {
"name": "[parameters('siteName')]",
"serverFarm": "[parameters('hostingPlanName')]"
},
"resources": [
{
"apiVersion": "2014-06-01",
"type": "extensions",
"name": "MSDeploy",
"dependsOn": [ "[concat('Microsoft.Web/sites/', parameters('siteName'))]" ],
"properties": {
"connectionString": "",
"dbType": "",
"packageUri": "file:///D:/svn/dh.PSP.Conductor/dh.PSP.Conductor.AzureResourceGroup/obj/Release/ProjectReferences/dh.PSP.Conductor.Api/package.zip"
}
}
]
}
I’m deploying from PowerShell and it fails with:
New-AzureResourceGroup : 16:00:35 - Resource
Microsoft.Web/sites/extensions 'ARMTest20150604/MSDeploy' failed with
message 'The resource operation completed with terminal provisioning
state 'Failed'.'
If I look in the portal I see a slightly more useful error:
statusCode:Conflict
statusMessage:{"status":"Failed","error":{"code":"ResourceDeploymentFailure","message":"The
resource operation completed with terminal provisioning state
'Failed'."}}
I’m none the wiser as to why this is failing however. Can anyone suggest how I might investigate further?
Fault is mine (as you might expect). Its not possible to reference a local file for the packageUri property, the file needs to be uploaded to blob storage first.
Something else useful I've found out, a deployment log is available by browsing to https://websitename.scm.azurewebsites.net/DebugConsole, "cd logfiles\siteextensions\msdeploy", open appManagerLog.xml. Much more useful information in there. In my case:
<entry time="2015-06-04T15:28:12.0718158+00:00" type="Error">
<message>AppGallery Deploy Failed: 'System.UriFormatException: Invalid URI: The URI is empty.
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
at System.Uri..ctor(String uriString)
at Microsoft.Web.Deployment.WebApi.AppGalleryPackage.IsPremiumApp()
at Microsoft.Web.Deployment.WebApi.DeploymentController.CheckCanDeployIfAppIsPremium(AppGalleryPackageInfo packageInfo, Boolean& isPremium)'</message>
</entry>
<entry time="2015-06-04T15:28:12.1186872Z" type="Message">
<message>Downloading package path 'D:\svn\dh.PSP.Conductor\dh.PSP.Conductor.AzureResourceGroup\obj\Release\ProjectReferences\dh.PSP.Conductor.Api\package.zip' from blob ''</message>
</entry>
<entry time="2015-06-04T15:28:12.1186872Z" type="Error">
<message>Failed to download package.</message>
</entry>
Related
I have a real chicken and egg situation. Also i am quite new to ARM so maybe missing something glaringly obvious.
Previously we had an arm template that worked using a certificate from a keyvault which was fine.
hostnamebindings resources created the custom domain and binding.
However we want to move to use the explicit self managed certificates in azure for the web service but are hitting some issues at the last hurdle.
The certificate is dependant on the custom domain as without it it fails to deploy but we can not reference the same resource twice in the template without it erroring.
Order must be:
Create custom domain
Create certificate
Bind certificate
ARM template extract below.
{
"condition": "[equals(parameters('UseCustomDomain'),'True')]",
"Comments": "If custom domain is selected then add to the webapplication",
"type": "Microsoft.Web/sites/hostnameBindings",
"apiVersion": "2022-03-01",
"name": "[concat(variables('appName'), '/', variables('DomainName'))]",
"location": "[ResourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('appName'))]"
],
"properties": {
"domainId": null,
"hostNameType": "Verified",
"siteName": "variables('DomainName')"
}
},
{
"type": "Microsoft.Web/certificates",
"apiVersion": "2021-03-01",
"name": "[variables('DomainName')]",
"Comments": "Creating Subdomain Certificate",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('AppName'))]",
"[resourceId('Microsoft.Web/sites/hostnameBindings/',variables('appName'), variables('DomainName'))]"
],
"properties": {
"hostNames": [
"[variables('DomainName')]"
],
"canonicalName": "[variables('DomainName')]",
"serverFarmId": "[variables('ServerFarmID')]"
}
},
What I would like to do is add the following properties after the the certificate is created to the hostnamebindings resource.
"sslState": "[if(variables('enableSSL'), 'SniEnabled', json('null'))]",
"thumbprint": "[if(variables('enableSSL'), reference(resourceId('Microsoft.Web/certificates', variables('DomainName'))).Thumbprint, json('null'))]"
Is there a way to make individual properties dependant on a resource? When i try the below in the hostname bindings properities i get a "Deployment template validation failed: 'Circular dependency detected on resource"
"properties": { "domainId": null, "hostNameType": "Verified", "siteName": "variables('DomainName')", "dependsOn": [ "[resourceId('Microsoft.Web/certificates', variables('DomainName'))]" ], "sslState": "[if(variables('enableSSL'), 'SniEnabled', json('null'))]", "thumbprint": "[if(variables('enableSSL'), reference(resourceId('Microsoft.Web/certificates', variables('DomainName'))).Thumbprint, json('null'))]" }
Any help greatly appreciated.
Background Information
I have function app with 3 different functions inside. I also have written a powershell script that deploys these functions upstream to Azure portal. It basically just calls this function:
func azure functionapp publish $FUNCTION_APP.name --publish-local-settings -i --overwrite-settings -y
Whenever I run the powershell script, I see the following error message:
Setting PExtStorageQueue = ****
Syncing triggers...
Syncing triggers...
Syncing triggers...
Syncing triggers...
Syncing triggers...
Syncing triggers...
Error calling sync triggers (BadRequest). Request ID = 'b4a22cd4-5c5b-4b2b-a9d4-537cb9cdf96a'.
The functions do end up being deployed and I can trigger them. But none of them have URLs in the "Get URL" option.
What I've checked so far
Based on other posts, it seems that enabling slots might cause issues so I've verified that I DO NOT have slots enabled.
Container OS. I'm using Linux containers. The version of the Linux container is dotnet|3.1 for the function app. I've also tried to change it to "dotnetcore|6.0" per this article: https://medium.com/medialesson/solved-the-parameter-linuxfxversion-has-an-invalid-value-net6-linux-533c759456cd. But that just causes the script to die with the following error when I use dotnetcore:
Line |
38 | New-AzResourceGroupDeployment -ResourceGroupName $currentEnv.AZ_RESOU …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 3:05:27 PM - The deployment 'myresourcegroupname-resources' failed with error(s). Showing 1 out of 1 error(s). Status Message: The parameter LinuxFxVersion has an invalid value. (Code: BadRequest)
| - The parameter LinuxFxVersion has an invalid value. (Code:) - (Code:BadRequest) - (Code:) CorrelationId: 6f7e4efb-a0b9-46c1-9d4a-df8f6c8d155e
ARM Template for App Plan
Here's the section in the template for the app service plan:
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2020-06-01",
"name": "[variables('appServicePlanPortalName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Y1",
"tier": "Dynamic",
"size": "Y1",
"family": "Y",
"capacity": 0
},
"kind": "functionapp,linux",
"properties": {
"name": "[variables('appServicePlanPortalName')]",
"reserved": true,
"computeMode": "Dynamic"
}
},
ARM Template for the Function App
And here's a snippet from the ARM template showing you what I'm doing for the function app itself:
{
"type": "Microsoft.Web/sites",
"apiVersion": "2020-06-01",
"name": "[parameters('functionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp,linux",
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]": {}
}
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanPortalName'))]",
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]"
],
"properties": {
"reserved": true,
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanPortalName'))]",
"siteConfig": {
"linuxFxVersion": "dotnet|3.1",
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('Microsoft.Insights/components', variables('appInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageAccountName'), ';EndpointSuffix=', environment().suffixes.storage, ';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value)]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~4"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "dotnet"
}
]
}
}
}
Any help would be appreciated.
EDIT 1
In case it helps, I've been testing these changes to the ARM template: (git diff showing you what's been changed)
--- a/arm_templates/myresourcegroup-resources.json
+++ b/arm_templates/myresourcegroup-resources.json
## -168,17 +168,13 ##
"name": "[variables('appServicePlanPortalName')]",
"location": "[parameters('location')]",
"sku": {
- "name": "Y1",
- "tier": "Dynamic",
- "size": "Y1",
- "family": "Y",
- "capacity": 0
+ "tier": "Standard",
+ "name": "S1"
},
"kind": "functionapp,linux",
"properties": {
"name": "[variables('appServicePlanPortalName')]",
- "reserved": true,
- "computeMode": "Dynamic"
+ "reserved": true
}
},
{
## -201,7 +197,7 ##
"reserved": true,
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanPortalName'))]",
"siteConfig": {
- "linuxFxVersion": "dotnet|3.1",
+ "linuxFxVersion": "DOTNETCORE|6.0",
"appSettings": [
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
It takes a super long time to publish but it eventually finishes.
It isn't able to list all my functions though, but I think I'm ok with that. This is what I see in the powershell script window:
Getting site publishing info...
Creating archive for current directory...
Uploading 13 MB [#################################################################################]
Upload completed successfully.
Deployment completed successfully.
App setting AzureWebJobsStorage is different between azure and local.settings.json
Overwriting setting in azure with local value because '--overwrite-settings [-y]' was specified.
Setting FUNCTIONS_WORKER_RUNTIME = ****
Setting PExtStorageTableName = ****
Setting PExtStorageQueue = ****
Functions in myresourcegroup-6z2ybl3tvqf6y-app:
PS C:\Users\me\src\azureTestDeploy>
But now I have URLs defined in the upstream functions!
Woot woot!
I'm going to revert each line again to try to narrow it down to the specific ARM change that solved the issue.
I'm guessing it'll be some combination, including the DOTNETCORE|6.0 change.
EDIT 2
I've been trying to play around with the different versions of the APIs to see how I can define a dynamic application service plan (Y1).
but I can't seem to get it working. I know our subscription supports Y1 in eastus for Windows. But I can't seem to get it working for Linux.
Anytime I use dynamic it gives me an error saying "The parameter LinuxFxVersion has an invalid value. (Code: BadRequest)"
I am currently deploying a VM Scale Set (VMSS) using an ARM template which has a resource inside VMSS to install Azure extension for Azure DevOps (ADO) Deployment Agent. All is deployed successfully and a node is registered in ADO with all details as are in the ARM template. However the problem is that it installs the agent only on first node and (as far as I see) ignores the rest of the nodes. I've tested this with multiple nodes during creation of the scale set and with auto-scale as well. Both scenarios result in only first agent registered.
This is the code layout I'm using (I've removed the VMSS bits to reduce the template length here, there are of course OS, storage and network settings inside):
{
"type": "Microsoft.Compute/virtualMachineScaleSets",
"name": "[parameters('VMSSName')]",
"apiVersion": "2018-10-01",
"location": "[resourceGroup().location]",
"sku": {
"name": "[parameters('VMSSSize')]",
"capacity": "[parameters('VMSSCount')]",
"tier": "Standard"
},
"dependsOn": [],
"properties": {
"overprovision": "[variables('overProvision')]",
"upgradePolicy": {
"mode": "Automatic"
},
"virtualMachineProfile": {},
"storageProfile": {},
"networkProfile": {},
"extensionProfile": {
"extensions": [
{
"type": "Microsoft.Compute/virtualMachineScaleSets/extensions",
"name": "VMSS-NetworkWatcher",
"location": "[resourceGroup().location]",
"properties": {
"publisher": "Microsoft.Azure.NetworkWatcher",
"type": "[if(equals(parameters('Platform'), 'Windows'), 'NetworkWatcherAgentWindows', 'NetworkWatcherAgentLinux')]",
"typeHandlerVersion": "1.4",
"autoUpgradeMinorVersion": true
}
},
{
"type": "Microsoft.Compute/virtualMachineScaleSets/extensions",
"name": "VMSS-TeamServicesAgent",
"location": "[resourceGroup().location]",
"properties": {
"publisher": "Microsoft.VisualStudio.Services",
"type": "[if(equals(parameters('Platform'), 'Windows'), 'TeamServicesAgent', 'TeamServicesAgentLinux')]",
"typeHandlerVersion": "1.0",
"autoUpgradeMinorVersion": true,
"settings": {
"VSTSAccountName": "[parameters('VSTSAccountName')]",
"TeamProject": "[parameters('VSTSTeamProjectName')]",
"DeploymentGroup": "[parameters('VSTSDeploymentGroupName')]",
"AgentName": "[concat(parameters('VMSSName'),'-DG')]",
"Tags": "[parameters('VSTSDeploymentAgentTags')]"
},
"protectedSettings": {
"PATToken": "[parameters('VSTSPATToken')]"
}
}
}
]
}
}
}
}
Now the desired state, of course, is that all nodes will have agent installed so that I can use the Deployment Group inside Release pipeline.
your problem is in the fact that all agents have the same AgentName, so it effectively overwrites the agent and only the latest one "survives". I dont think there is anything you can do, unless you just amend the AgentName and it auto assigns based on computer name.
You can convert this to a script\dsc extension, that way you can calculate everything on the fly.
I have created an ARM template which successfully creates an Automation Account in Azure and then creates a module and DSC configuration in that account.
When I add a Microsoft.Automation/automationAccounts/Compilationjobs resource to compile the DSC configuration, the template deployment fails at this step with 404 - File or directory not found.
The Compilationjobs resource exists as a top level resource in the template as follows:
{
"apiVersion": "2015-10-31",
"type": "Microsoft.Automation/automationAccounts/Compilationjobs",
"name": "automationAccountName/jobId123",
"location": "[variables('location')]",
"tags": {
},
"dependsOn": [
"Microsoft.Automation/automationAccounts/automationAccountName",
"modulesResourceLoop"
],
"properties": {
"configuration": {
"name": "DSCConfigurationName"
}
}
}
When I call Start-AzureRmAutomationDscCompilationJob with the same details the compilation job is created and completes successfully.
Compiling the configuration involves creating a compliationJob. Under the hood it's a PUT call to /CompiliationJobs/{guid}. so the trick here is to pass a new guid into the arm template when invoking compilation job.
Something like the following, you will need to define the parameter compilationJobGuid:
{
"name": "[parameters('compilationJobGuid')]",
"apiVersion": "2015-10-31",
"type": "Microsoft.Automation/automationAccounts/Compilationjobs",
"location": "[variables('location')]",
"tags": {
},
"dependsOn": [
"Microsoft.Automation/automationAccounts/automationAccountName",
"modulesResourceLoop"
],
"properties": {
"configuration": {
"name": "DSCConfigurationName"
}
}
}
I am trying to provision some resources on Azure using the Azure Resource Manager with a template I have put together;
I am provisioning several web apps with independent Service Plans concurrently. Of course each web app resource "dependsOn" its Service plan.
Everyone once in a while when I deploy using Powershell I get the following error:
New-AzureRmResourceGroupDeployment : 4:21:22 PM - Resource Microsoft.Web/serverfarms 'ServicePlanA' failed with message 'Cannot find Web space
ExampleResourceGroup-AustraliaEastwebspace for subscription ...'
This fails randomly on one or more of the Service Plans.
I also found this GitHub issue, but since I am not using the CLI I couldn't see how this would help https://github.com/Azure/azure-xplat-cli/issues/1646
I also have the latest AzureRM packages from https://www.powershellgallery.com/packages/AzureRM/
The API version I am using is "2015-08-01", and the schema of the deployment template is https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#
Here is a segment from the template that creates the mentioned resources:
{
"name": "[variables('WebFrontServicePlanAName')]",
"type": "Microsoft.Web/serverfarms",
"location": "[parameters('DataCenterALocation')]",
"apiVersion": "2015-08-01",
"dependsOn": [ ],
"tags": {
"displayName": "WebFrontServicePlanA"
},
"sku": {
"name": "[parameters('WebFrontServicePlanSKU')]"
},
"properties": {
"name": "[variables('WebFrontServicePlanAName')]",
"workerSize": "[parameters('WebFrontServicePlanAWorkerSize')]",
"numberOfWorkers": 1
}
},
....
{
"name": "[variables('webAppName')]",
"type": "Microsoft.Web/sites",
"location": "[parameters('DataCenterALocation')]",
"apiVersion": "2015-08-01",
"dependsOn": [
"[concat('Microsoft.Web/serverfarms/', variables('WebFrontServicePlanAName'))]"
],
"tags": {
"[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', variables('WebFrontServicePlanAName'))]": "Resource",
"displayName": "webApp"
},
"properties": {
"name": "[variables('webAppName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms/', variables('WebFrontServicePlanAName'))]"
},
}
Do you already have an existing resource group that you're deploying to? If not try using the cmdlet New-AzureRmResourceGroupinstead of New-AzureRmResourceGroupDeployment.
In Azure Web Apps, resource groups are backed by webspaces. Thus a resource group may contain multiple webspaces each in a different geo region. If you don't have the resource group, and you're not creating it, then you wouldn't have the corresponding webspace, which would cause the error you're seeing.