I'm trying to upload a Dotnet core Azure Function to an app service hosted on Windows and I'm struggling to prove that it works or ensure the settings are correct.
I also have the aspiration that the deployment should be fully automated without having to go via the Azure Portal and tweak settings etc.
Build process: currently it looks like this...
The c# function compiles and all unit tests pass locally and on the Azure DevOps build agents
Build completes and generates the zip file
I wrap the zip file within a versioned Nuget package
Nuget package is hosted in Azure DevOps Artifacts repo
So all looks good at this point.
Release Process
I restore and unpack the nuget package on the Azure DevOps build agent.
I confirm the zip file exists with a Powershell task - all good.
I then use the Azure DevOps Release pipeline task; "Azure Functions"
https://github.com/Microsoft/azure-pipelines-tasks/blob/master/Tasks/AzureFunctionAppV1/README.md
I think I've configured this task correctly
Package or Folder: "The path I validated in step 2 above"
Deployment Method: Zip Deploy (I've alternated between this and Package deployment in different releases)
App Settings (see screenshot below)
name value pairs like -Name "value" -Name2 "value2" etc
I've also included -WEBSITE_RUN_FROM_PACKAGE "1" in the list of app settings (I've tried releases with and without this setting present)
The Results
The release passes, it says in the logs that its uploaded the package and the app settings.
However, when I go to the Azure Portal:
I don't see my app settings that I thought I'd uploaded in the release.
It retains dummy app settings that I added via the Azure Portal directly
Questions
Should I create an empty Azure Function within the AppServive using the Azure Portal before I start the Release with this task?
The very first time I ran the release it failed because it said it couldn't find the slot I'd specified. I was under the impression that the Azure Function pipeline task would create everything but it appears that it expects there to be an empty function with slots predefined and maybe app settings predefined. Any thoughts please?
Do I have to create app settings in the Portal before the release? In other words does the Pipeline task only allow updates to existing Portal created app settings.
Is there a better Pipeline task to use - that can create an new Azure Function if it doesn't exist already?
As is often the case with help documentation, the info I've seen follows a happy path, or sometimes too much with lots of ifs, buts and maybe advice.
Any guidance would be truly appreciated as I feel I'm going round in circles here and it should be simple.
Thankyou.
You can deploy the Azure Function via Azure-Resource-Manager Templates. You can find samples on GitHub. With this step you create the required infrastructure on Azure before your deployment. In your case the Azure Function and a Consumption Plan. In your deployment, the infrastructure is therefore provided in step one and then the actual deployment of the package to your function.
For the infrastructure look at the Azure DevOps Step for Create or Update Resource Groups.
YAML sample for both steps:
- task: AzureResourceGroupDeployment#2
displayName: 'Create Or Update Resource Group'
inputs:
deploymentMode: 'Incremental'
azureSubscription: 'Your-Subscription'
resourceGroupName: '${{ parameters.resourceGroupName }}'
location: '${{ parameters.location }}'
csmFile: '${{ parameters.csmFile }}'
csmParametersFile: '${{ parameters.csmParametersFile }}'
- task: AzureRmWebAppDeployment#4
displayName: 'Azure App Service Deploy'
inputs:
azureSubscription: 'Your-Subscription'
appType: functionApp
WebAppName: '${{ parameters.function }}'
packageForLinux: '$(Agent.BuildDirectory)/${{ parameters.dropfolder }}/$(Build.Repository.Name)-$(version)-$(Build.SourceBranchName)-$(Build.BuildNumber).zip'
After you've done a build in your Azure Devops pipeline you will create a package to make a release from. You have to make sure that the contents in that package matches to correct folder structure. The contents of your app should have the following structure according to Requirements for continuous deployment.
FunctionApp
| - host.json
| - MyFirstFunction
| | - function.json
| | - ...
| - MySecondFunction
| | - function.json
| | - ...
| - SharedCode
| - bin
After the build you can check the contents of the generated package by going to the summary for that particular build and clicking on the published artifact. There you can download the contents and make sure that it has the following structure and content:
| - host.json
| - MyFirstFunction
| | - function.json
| | - ...
| - MySecondFunction
| | - function.json
| | - ...
| - SharedCode (might not be there)
| - bin
Once deployed you can browser your deployed files through Kudu by using the CMD or Powershell Debug Console. If you have chosen to run from package you can see the package used at /data/SitePackages/. The packagename.txt points to the latest package used. The contents of the package are extracted to /site/wwwroot/. There you should see at least a host.json, a bin folder, and the folders containing your functions. Nothing else. The function app content should not be deployed to a sub folder of /site/wwwroot/, like for example /site/wwwroot/FunctionApp/.
If the content and folder structure in wwwroot isn't correct, you might still see a successful deployment, you Function App shows up but there are no functions showing up.
Related
I'm trying to publish a small .NET Core 3.1 Web App on Azure App Service (Linux), and the app won't start.
No matter if I'm publishing using Visual Studio, or Azure DevOps, i'm getting the following error on my Linux Azure App Service (which, by the way, already contains two other apps):
2021-06-23T22:19:47.102376527Z _____
2021-06-23T22:19:47.102415627Z / _ \ __________ _________ ____
2021-06-23T22:19:47.102422327Z / /_\ \___ / | \_ __ \_/ __ \
2021-06-23T22:19:47.102426627Z / | \/ /| | /| | \/\ ___/
2021-06-23T22:19:47.102430627Z \____|__ /_____ \____/ |__| \___ >
2021-06-23T22:19:47.102434927Z \/ \/ \/
2021-06-23T22:19:47.102438927Z A P P S E R V I C E O N L I N U X
2021-06-23T22:19:47.102442827Z
2021-06-23T22:19:47.102446327Z Documentation: http://aka.ms/webapp-linux
2021-06-23T22:19:47.102449927Z Dotnet quickstart: https://aka.ms/dotnet-qs
2021-06-23T22:19:47.102453427Z ASP .NETCore Version: 3.1.13
2021-06-23T22:19:47.102457227Z Note: Any data outside '/home' is not persisted
2021-06-23T22:19:47.307988432Z Running oryx create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -defaultAppFilePath /defaulthome/hostingstart/hostingstart.dll -bindPort 8080 -userStartupCommand 'dotnet WebApplication1.dll'
2021-06-23T22:19:47.378242802Z Cound not find build manifest file at '/home/site/wwwroot/oryx-manifest.toml'
2021-06-23T22:19:47.382799606Z Could not find operation ID in manifest. Generating an operation id...
2021-06-23T22:19:47.382816206Z Build Operation ID: 7f48597c-0791-46e5-bffd-b0007d8b27b7
2021-06-23T22:19:49.335414280Z Writing output script to '/opt/startup/startup.sh'
2021-06-23T22:19:49.567879341Z Running user provided startup command...
2021-06-23T22:19:49.610748271Z A compatible installed .NET Core SDK for global.json version [3.1.409] from [/home/site/wwwroot/global.json] was not found
2021-06-23T22:19:49.610783071Z Install the [3.1.409] .NET Core SDK or update [/home/site/wwwroot/global.json] with an installed .NET Core SDK:
2021-06-23T22:19:49.610825071Z It was not possible to find any installed .NET Core SDKs
2021-06-23T22:19:49.610829471Z Did you mean to run .NET Core SDK commands? Install a .NET Core SDK from:
2021-06-23T22:19:49.610835971Z https://aka.ms/dotnet-download
2021-06-23T22:19:50.944Z ERROR - Container procoding-me_0_8935305e for site procoding-me has exited, failing site start
2021-06-23T22:19:50.961Z ERROR - Container procoding-me_0_8935305e didn't respond to HTTP pings on port: 8080, failing site start. See container logs for debugging.
2021-06-23T22:19:50.978Z INFO - Stopping site procoding-me because it failed during startup.```
I've tried to create the web app on azure again, and even tried to publish the same code of the other apps, and the same problem occurs.
Anybody has a hint of the cause of this problem?
So, after a long day of trying to figure this thing out I managed to publish and app to an app service running linux. I'm using an App Service Plan (Linux, B1) that lives in a "shared" resource group since I want to run multiple apps on it. I'm also deploying the infrastructure using Bicep and the pipeline is yaml.
The issue was, as it seems, that when I was deploying the app through Azure DevOps, it was nesting the app archive in another zip-file. The app zip-file needs to be the root-folder in the app, not obvious unless you download the files that are being executed in the app service itself.
Yeah, also I'm using the self-contained version of deployment here. You can read more about it here. I had no success doing it with the framework-dependent way unless I published the app from Visual Studio 2022.
So, in the end, here are the snippets that made the thing work for me:
azure-pipelines.yaml - Build stage
- task: DotNetCoreCLI#2
inputs:
command: 'publish'
projects: '**/*Api.csproj'
arguments: '--configuration $(buildConfiguration) -r linux-x64 --self-contained true --output $(Build.ArtifactStagingDirectory)'
modifyOutputPath: false
publishWebProjects: false
zipAfterPublish: true
displayName: 'Dotnet Publish'
- task: PublishBuildArtifacts#1
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)'
ArtifactName: drop
azure-pipelines.yaml - Deploy stage
- task: AzureRmWebAppDeployment#4
inputs:
azureSubscription: '$(azureSubscription)'
appType: webAppLinux
WebAppName: '$(output_appServiceName)'
packageForLinux: '$(Pipeline.Workspace)/**/a.zip' #Since we are not specifying the folder name in the steps prior, the folder will be called just a.zip, this is fine since the deployment is going to rename it any way in the app service file system anyway(in Kudu)
The app service resource in Bicep
resource appService 'Microsoft.Web/sites#2021-01-01' = {
name: '${serviceName}-${environment}-app'
location: resourceGroup().location
kind: 'app'
properties: {
serverFarmId: planId
siteConfig: {
alwaysOn: true
http20Enabled: true
linuxFxVersion: 'DOTNETCORE|5.0'
appSettings: [
{
name: 'WEBSITE_RUN_FROM_PACKAGE'
value: '1'
}
]
}
}
}
Hope this helps.
P.S. Having "corrupted" zip-files in the app service (Kudu) can cause the app to fail. I suggest anyone having this issue to either delete all files from wwwroot or simply delete the app service resource and deploy it from scratch to make sure it can start properly.
Hi I've got a solution that has multiple projects held within it where I'm hoping to automate the build and deployment of the webapplication within the project.
on my HD the dir looks like C:\Users\mleip\source\repos\edocs.utils.bluebeam-api\edocs.utils.bluebeam-api.Caller\edocs.utils.CDEComms , however, when I run the below yaml
i get
MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
steps:
- script: dotnet restore
- powershell: |
Write-Host "Your parameter is now: $env:Param"
Write-Host "When outputting standard variable build id: $(Build.BuildId)"
Write-Host "When outputting standard variable build id via env: $env:BuildNumber"
Write-Host "The repo name is: $(Build.Repository.Name)"
Write-Host "The build definition name is: $(Build.DefinitionName)"
- script: dotnet build --configuration $(buildConfiguration)
displayName: 'dotnet build $(buildConfiguration)'
- task: DotNetCoreCLI#2
inputs:
command: 'build'
projects: '**/edocs.utils.bluebeam-api.Caller/edocs.utils.CDEComms/edocs.utils.CDEComms.csproj'
So far I have tried several combinations of dir for where azure should locate the build file, however, each time it fails. The solution has several projects within it. CDEComms is the only project within that folder so I'm left quite confused as to what's going on.
I'm quite new to building pipelines and any help as to why this is failing would be greatly appreciated.
In order to narrow down the issue, try to simply specify **/*.csproj in the YAML file to check the build result. And set variable system.debug to True, to check whether the path is correct in C:\hostedtoolcache\windows\dotnet\dotnet.exe build {path}. Also, clone the repo to your local machine to run build it locally, to check the result.
From the description you have provided, you will first have to push your code/solution i.e. the content of your C:\ drive to your repository.
I am trying to use new tool pipelines from bitbucket. I have multiple .NET console application (not Core app) than i want to build and download. I found this page that says that I can use mono to build my project. I use this .yml file to build it.
image: mono
pipelines:
default:
- step:
script:
- nuget restore
- MONO_IOMAP=case xbuild /t:Build /p:Configuration="Release" /p:Platform="Any CPU" Solution.sln
Build was successful but now I am stuck with downloading my app (exe with all dlls). I found here that I can use bitbucket downloads. But how to download my deploy folder? Here I found that I can zip some files and then put it to bitbucket downloads. But how I can use this with mono, and how I can zip a whole folder, and then download it? I don't mind to use something else like mono.
Mono is built on debian:wheezy, any linux commands you run in the script portion of the YML file can help you extract the file before BitBucket Pipelines pulls down the container. In the example you included there is a POST command at the end which deploys the artefact to Downloads in Bitbucket.
curl -v -u $BB_ACCESS -X POST https://api.bitbucket.org/2.0/repositories/$BITBUCKET_REPO_OWNER/$BITBUCKET_REPO_SLUG/downloads/ -F files=#aqua_lambda.zip
It explains the environment variables $BB_ACCESS further down, others are loaded in at runtime for you.
You'll need to find the file path mono compiles to and adjust the example's code to push to Bitbucket Downloads, or Amazon s3 is a good option too.
A bit late for this answer...
Firstly, use msbuild instead of xbuild as xbuild is deprecated.
Now, what you want is a successful build as well push the release to bitbucket downloads.
Here is how you do it:
1. Create an App password for the repository owner
Log in to Bitbucket as the repository owner (also the user who will upload the files) and go to Bitbucket Settings > App Passwords.
Create a new app password with write permissions to your repositories, and take note of the generated password that pops up. The name of the password is only for your reference, so use "Pipelines" or any other name you like.
You should now have two values that you will need for the next step.
<username>: Bitbucket username of the repository owner (and also the user who will upload the artifacts)
<password>: App password as generated by bitbucket
2. Create a Pipelines environment variable with the authentication token
Define a new secure environment variable in your Pipelines settings:
Parameter name: BB_AUTH_STRING
Parameter value: <username>:<password> (using the values from step 1)
You can define this environment variable either in the repository settings, or in the settings for the account that owns the repository.
The example below shows the settings for an individual account environment variable, where the repository is owned by an individual. (Note that in the case where a team owns the repository, you must configure environment variables in the team settings for them to be visible in Pipelines.)
3. Enable your Pipeline to deploy your artifacts using curl and the Bitbucket REST API
First add line to zip your release dir:
- zip -j bin/Release.zip bin/Release/
It may be possible that the pipeline bash does not have zip installed. To install zip, add the following lines to your pipeline before the above command:
- apt-get update
- apt-get -y install zip
Now finally add the curl command that uses Bitbucket REST API:
- curl -X POST --user "${BB_AUTH_STRING}" "https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/downloads" --form files=#"bin/Release.zip"
If you wish, you can remove the unneeded release zip file from the bin dir as the zip is now already in Bitbucket downloads:
- rm -f bin/Release.zip
Here is the full pipeline.yml:
image: mono
pipelines:
default:
- step:
script:
- nuget restore
- MONO_IOMAP=case msbuild /p:Configuration="Release" /p:Platform="AnyCPU" Solution.sln
- apt-get update
- apt-get -y install zip
- zip -r bin/Release.zip bin/Release/
- curl -X POST --user "${BB_AUTH_STRING}" "https://api.bitbucket.org/2.0/repositories/${BITBUCKET_REPO_OWNER}/${BITBUCKET_REPO_SLUG}/downloads" --form files=#"bin/Release.zip"
- rm -f bin/Release.zip
Note that your release directory may differ from the sample above
I'm getting this problem using VSTS continuous deployment to azure
Web Deploy cannot modify the file 'XXX' on the destination because it is locked by an external process
the solution provided in this thread is to manually restart my app in azure, however he's not using VSTS and the question was asked 2 years ago, is this issue fixed on the current VSTS and if so, I would like to know how because I'm having the same problem as the link referenced above.
Thanks
You can use "EnableMSDeployAppOffline" feature to set your app offline before deployment by following the instruction here: Web publishing updates for app offline and usechecksum.
If it does not work, you can also create a PowerShell script as following to stop the app, deploy and then restart the app:
param($websiteName, $packOutput)
$website = Get-AzureWebsite -Name $websiteName
# get the scm url to use with MSDeploy. By default this will be the second in the array
$msdeployurl = $website.EnabledHostNames[1]
$publishProperties = #{'WebPublishMethod'='MSDeploy';
'MSDeployServiceUrl'=$msdeployurl;
'DeployIisAppPath'=$website.Name;
'Username'=$website.PublishingUsername;
'Password'=$website.PublishingPassword}
Write-Output "Stopping web app..."
Stop-AzureWebsite -Name $websiteName
Write-Output "Publishing web app..."
$publishScript = "${env:ProgramFiles(x86)}\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Web Tools\Publish\Scripts\default-publish.ps1"
. $publishScript -publishProperties $publishProperties -packOutput $packOutput
Write-Output "Starting web app..."
Start-AzureWebsite -Name $websiteName
PowerShell Script from: Build and Deploy your ASP.NET 5 Application to an Azure Web App.
Essentially you need to stop - deploy - restart .
You have many options to do it but to more easy would be:
1- Extention: Azure App Services - Start and Stop
you can try the extension "Azure App Services - Start and Stop" https://marketplace.visualstudio.com/items?itemName=rbengtsson.appservices-start-stop
2- AzureCLI task
From the build or Deployment windows Add am Azure CLI task (currently in Preview)
Add one before the Deployment task
with Inline script:
azure webapp stop --resource-group NAME_OF_YOUR_RESOURCE_GROUP --name WEBAPP_NAME
Add another one after the Deployment task
with Inline script:
azure webapp start --resource-group NAME_OF_YOUR_RESOURCE_GROUP --name WEBAPP_NAME
I hope that help.
My Project Configuration:
I have a web application project (Visual Studio 2015 update 1 + c#) that includes an Azure Webjob. The Webjob is part of the project configuration. Looks like this (location: ProjName -> Properties -> webjobs_list.json):
{
"$schema": "http://schemastore.org/schemas/json/webjobs-list.json",
"WebJobs": [
{
"filePath": "../Jobs/XXX/XXX.csproj"
}
]
}
My Azure Configuration:
I created a new website ("Web app") and published (to "production" environment) my project. Working great. Including my webjob.
So far, all good. Now, I created a new environment (within my web app site) that called "Staging". Go back to my Visual studio project, download the newly created publish profile (staging) and publish it.
The Problem
Visual studio refuse to publish my project to the staging environment with this error:
An error occurred while creating the WebJob schedule: No website could
be found which matches the WebSiteName [XXX__stage] and
WebSiteUrl [http://XXX-stage.azurewebsites.net] supplied.
What the...? Why?
By publishing the same project to "Production" environment, it's prove that the project configuration is OK (including webjob).
Any solution for this strange?
Thank you.
There are some known issues with configuring the Azure Scheduler from Visual Studio. The suggested approach is to avoid the use of the Azure Scheduler, and instead use the newer CRON based scheduler feature described in the docs here.
Basically, you create the WebJobs as manual (not scheduled), and then add a settings.job to it with a CRON expression, e.g. to run every 15 minutes:
{
"schedule": "0 */15 * * * *"
}
Going forward, this will be the default in VS.