DEV Community

Usama Ansari
Usama Ansari

Posted on • Edited on

Create & Deploy Azure Function ⚡ using VS code and Azure DevOps (CI/CD)

Azure Function 🚀 is Microsoft faas (function as a service) offering. Where you can build apps without worrying about server and infrastructure that scale to meet demands. You can use your choice of programming language.

Let's get started...

Pre-requisites
  1. Azure Devops Account (Get for Free)
  2. Azure Account (Sign up for Free)
  3. Visual Studio Code (Download)

This article is quite long. please feel free to jump to the desired section

  1. Create an Azure DevOps Project
  2. Create Azure function locally
  3. Add Azure Resource Manager (ARM) Template
  4. Push code to git Repository
  5. Create Build / CI (Continuous Integration) Pipeline
  6. Create Release / CD (Continuous Delivery) Pipeline
  1. Create an Azure DevOps Project

    Follow the below steps to Create a new Azure DevOps Project:

    1. Login to Your Azure DevOps tenant http://dev.azure.com/[username] replace [Username with your tenant name] e.g http://dev.azure.com/usmslm102
    2. Click on Create Project and Provide the required details Create Account
    3. Once the project is created you will be redirected to welcome page.
  2. Create Azure function locally

    Follow the below steps to create and run azure function locally

    1. Open Visual Studio Code and install Azure Functions and C# extensions if you already have it installed then skip.
    2. click on extensions from the sidebar and search for Azure Functions and click on the install button
    3. Search for C# extension and click install
    4. Create a new folder named AzureFunctions and open in vs code
    5. Press ctrl/cmd (on MAC) + shift + p and type Create Function
    6. Select Create Function and select current folder
    7. You will get a prompt saying "The selected folder is not a function app project. Initialize Project?" click Yes
    8. Select C# as a language
    9. VS code will initialize function app and will ask to select the function template
    10. Select HttpTrigger and press enter with default "HttpTriggerCSharp" function name and "Company.Function" for namespace
    11. Select Access Rights as Function and press enter
    12. Press F5 to test our function locally and copy the function URL
    13. Navigate to copied URL and provide the parameter called name e.g. ?name=World
    14. Voila, our function is up and running 😱
  3. Add Azure Resource Manager (ARM) Template

We need to create Azure Resources before deploying our function. we will use ARM template to create below Azure resources.

  1. Azure Function App
  2. Azure Storage Account
  3. Consumption app service plan

Below ARM template will create all 3 resources:

  1. Create a functionapp.json file inside folder Templates and paste below content

    functionapp.json

  2. Create a functionapp.parameters.json file inside folder Templates and paste below content

    functionapp.parameters.json

    Note: Change the appName value to unique name in functionapp.parameters.json

    Final folder structure looks like below:


  1. Push code to git Repository

We are all set to push the code to our git repository. When we created Azure DevOps project we get the default git repository same as the project name.
Navigate to Azure DevOps project and click on Repos on the left navigation. You will see we have an empty repository named "AzureFunction" same as our project name.

There are several ways to push our code changes to a remote repository:

  1. Clone remote repository to your computer and start adding files
  2. Push existing local repository to remote repository

As we have already created our project lets use 2nd option and push our project to a remote repository.
Open your favorite command prompt and navigate to our project folder or as we are using VS code we can use it's integrated terminal press ctrl + ` to open it.

Copy the git remote push command from Azure DevOps Repos page.

> git init
> git add .
> git commit -am "Add function app"
> git remote add origin <git Repo Url>
> git push -u origin --all

Refresh your Azure DevOps Repos page and you should see the function app files. 😎



  1. Create Build / CI (Continuous Integration) Pipeline

Our Repository contains the source code for function app which needs to be compiled before publishing to Azure. As our function app is .net core project let's create the CI pipeline to build function app project and publish the required artifices.

  1. Navigate to Azure DevOps project and click on build under pipelines. currently, we don't have any CI Pipeline. Let's create one. click on New Pipeline button.

  2. Azure DevOps will ask us where our source code resides. Azure DevOps supports multiple SCM providers such as Azure Repos, GitHub, BitBucket, Subversion etc. As our source code is hosted on Azure Repos select "Azure Repos Git" and provide the required details and click on continue button.

  3. click on "Empty Job" as we will define our tasks

  4. As our function based on .net core let's add restore, build and publish task to generate our build artifacts

  5. Click on "+" button and search for .net core task and click on add button. Select .NET core task and change values as follows dotnet restore:

  6. dotnet restore:

    • Display name: dotnet restore
    • Command: restore
    • Path to project(s): **/*.csproj This step will restore the nuget packages for our project
  7. Repeat above step for Build and publish task

  8. dotnet build:

    • Display name: dotnet build
    • Command: build
    • Path to project(s): **/*.csproj This step will build our project
  9. dotnet publish:

    • Display name: dotnet publish
    • Command: publish
    • Un-Checked: Publish Web Projects
    • Path to project(s): **/*.csproj
    • Arguments: --no-restore --configuration Release --output $(Build.ArtifactStagingDirectory)
    • Checked: Zip Published Projects
    • Checked: Add project name to publish path This step will take our build files and zip it and put in ArtifactStagingDirectory
  10. Now we need to published the compiled code and ARM templates as build artifacts so we can use these packages in our Release pipeline. Click on '+' and search for task publish build Artifacts. select the task and click add

    • Display name: Publish Artifact: drop
    • Path to publish: $(Build.ArtifactStagingDirectory)
    • Artifact name: drop
    • Artifact publish location: Azure Pipelines/TFS This step will take our zip files from ArtifactStagingDirectory and publish it to Azure Pipelines build artifacts in the drop folder
  11. Let's publish our ARM templates to drop folder as well. Click on '+' and search for task publish build Artifacts. select the task and click add

    • Display name: Publish ARM: drop
    • Path to publish: Templates
    • Artifact name: drop
    • Artifact publish location: Azure Pipelines/TFS This step will take our ARM files from SourceDirectory and publish it to Azure Pipelines build artifacts in the drop folder
  12. Our final pipeline looks like:

  13. Let's Save and queue our pipeline. click on "Save & Queue" drop down from the top and select Agent pool: "Hosted VS2017" and Branch: "master" then click on the button "Save & Queue". Azure DevOps will find the available agent and run our tasks.

  14. Navigate to builds pipeline page from left navigation and select our build pipeline. we can see all our build on this page. click on latest build. It will show us the logs of the specified tasks in our build pipeline. on top right click on Artifacts drop down and select drop. It will open artifacts explorer. expand drop folder and we can see our ARM template and compiled function app in the zip package. We will use these artifacts in our Release pipeline.

  15. We don't want every-time to open Azure DevOps and click on queue button to build our code changes. we want if our code changes then the build should automatically trigger. Let's enable Continuous integration to achieve this.

    Edit our build pipeline and navigate to Triggers tab and check "Enable continuous integration" and select master as branch filter and click on the Save & queue drop down and select Save.

  16. We are done with our CI pipeline and we are getting build artifacts as well. let's use these artifacts and deploy to Azure using Release/CD pipeline


  1. Create Release / CD (Continuous Delivery) Pipeline

Our Repository contains the source code for function app which needs to be compiled before publishing to Azure. As our function app is .net core project let's create the CI pipeline to build function app project and publish the required artifices.

  1. Navigate to Azure DevOps project and click on Releases under pipelines. currently, we don't have any CD Pipeline. Let's create one. click on New Pipeline button.
  2. Azure DevOps will ask us to select a pre-defined template. As we will define our own tasks let start with an Empty Job.
  3. Click on Empty Job.
  4. We have to define the deployment stage. type stage name as Production and close the pop-up by clicking on x.
  5. We need to tell our release pipeline from where to get the deployment artifacts. click on big "Add an artifact" button.
  6. Select source type as Build and select our build pipeline in "Source (build pipeline)" section.
  7. select Default version as Latest. so that every release will take the latest artifacts by default.
  8. click on the Add button.
  9. Before we define our deployment tasks lets enable the Continuous deployment trigger to automatically deploy our changes as soon as new build artifacts are available. click on the ⚡ icon and enable Continuous deployment trigger and close the pop-up by clicking on x.
  10. Let's define our tasks by clicking on "1 job, 0 task" link under our production stage. This will open the task window same as build pipeline.
  11. We need to create two tasks first we have to create Azure function app and its dependencies using our ARM template then we will deploy Azure function package on it.
  12. click on "+" and search for Azure Resource Group Deployment and click add. This step needs our Azure account details and ARM template files
    • Azure subscription: select Azure subscription from drop down. if required click on the Authorize button to configure an Azure service connection.
    • Action: Create or update resource group
    • Resource group: type AzureFunction as
    • Location: East US
    • Template location: Linked artifact
    • Template: click on ... and select functionapp.json from drop folder. final URL will like this $(System.DefaultWorkingDirectory)/_AzureFunction-CI/drop/functionapp.json
    • Deployment mode: Incremental This step will deploy our ARM template to create function app and its dependencies in the defined Resource group under defined subscription
  13. click on "+" and search for Azure App Service Deploy and click add. This step needs our Azure account details and zip package file.
    • Azure subscription: select Azure subscription from drop down. if required click on the Authorize button to configure an Azure service connection.
    • App Service type: Function App on Windows
    • App Service name: type app Name which you specified in the functionapp.parameters.json file under Add Azure Resource Manager (ARM) Template section.
    • Package or folder: $(System.DefaultWorkingDirectory)/**/*.zip
  14. Before we save our pipeline lets rename it to AzureFunction-CD and click on Save button.
  15. Let's create a release and deploy our resources to Azure.😎
  16. Click on Release > Create a Release. Finally, click on the Create button
  17. Navigate to Releases pipeline page from left navigation and select our Release pipeline. we can see all our Release on this page. click on latest Release and see the progress.
  18. Once the release is finished. navigate to the Azure portal and open the AzureFunction Resource Group. Voila, function app and its dependencies are created now.
  19. open function app and get the function URL to test it.

Cheers 🥂

Top comments (14)

Collapse
 
shajay99 profile image
ajay sharma

Usama Sir, I am getting this error while running the Pipeline.

**##[error]d:\a\1\s\Hermes.sln.metaproj(0,0): Error MSB3202: The project file "d:\a\1\s..\Hermes.Test\Hermes.Test.csproj"

Sir, please post the azure-pipelines.yml file, which is created with above azure function.

Collapse
 
usmslm102 profile image
Usama Ansari

Can you post the complete error message. If possible please dm me on Twitter.

Collapse
 
shajay99 profile image
ajay sharma

Sir, on twitter, i could not send all text.

Build started 11/17/2019 10:44:54 AM.
Project "d:\a\1\s\Hermes.sln" on node 1 (default targets).
ValidateSolutionConfiguration:
Building solution configuration "Release|Any CPU".

[error]d:\a\1\s\Hermes.sln.metaproj(0,0): Error MSB3202: The project file "d:\a\1\s..\Hermes.Test\Hermes.Test.csproj" was not found.

d:\a\1\s\Hermes.sln.metaproj : error MSB3202: The project file "d:\a\1\s..\Hermes.Test\Hermes.Test.csproj" was not found. [d:\a\1\s\Hermes.sln]
Project "d:\a\1\s\Hermes.sln" (1) is building "d:\a\1\s\Hermes.csproj" (2) on node 1 (default targets).
PrepareForBuild:

Thread Thread
 
usmslm102 profile image
Usama Ansari

It seems you have deleted the test project but the reference is still there in solution file. If you delete the project from file explorer you have to remove the reference from solution file as well. If you can provide me more details the project structure and the build yaml file I can help you more on this.

Thread Thread
 
shajay99 profile image
ajay sharma • Edited

Usama Sir, Request you to please check if the stages of the Pipeline is OKay, as now all the stages are passing. And here it the YAML file. sorry the formatting is not OKay.

trigger:

  • master

pool:
vmImage: 'windows-latest'

variables:
solution: '*/.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'

steps:

  • task: NuGetToolInstaller@1

  • task: NuGetCommand@2
    inputs:
    restoreSolution: '$(solution)'

  • task: VSBuild@1
    inputs:
    solution: '$(solution)'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

  • task: VSTest@2
    inputs:
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

Thread Thread
 
usmslm102 profile image
Usama Ansari

Build pipeline looks ok. There might be the issue with your solution file. You might have a reference of "Hermes.Test.csproj" in your solution file but the actual csproj file doesn't exist.

Thread Thread
 
shajay99 profile image
ajay sharma

Thanks Usama Sir.. thanks for guiding me..
Sir, in my pipeline, PUBLISH and PUBLISH ARTIFACT are not visible. Have I selected wrong template ??

Collapse
 
bananbe profile image
Mateusz

Nice post, it was useful for me :)
One minor thing from me:
you have linked wrong files for jsons ie. for functionapp.parameters.json there is functionapp.json and for functionapp.json there is content from functionapp.parameters.json.

Collapse
 
anderslundgren profile image
Anders Lundgren

Great post, very helpful!
Two minor cut-and-paste typos:
CI pipeline step #9: Checked: Publish Web Projects should be removed (States correctly that this should be un-checked a couple of lines above)
CD pipeline step #12: Template parameters: East US should be the template param file instead

Collapse
 
usmslm102 profile image
Usama Ansari

I'm glad this post helped you and thanks for pointing out those typos.

Collapse
 
arihjain profile image
Arihant Jain

Very good post it was very helpful for me to start my DevOps journey in Azure. Appreciate it.

Collapse
 
shajay99 profile image
ajay sharma

Hi Usama Ansari, Sir, request you to please create a Video on Youtube on this CICD DevOps Azure Pipeline

Collapse
 
shajay99 profile image
ajay sharma

Usama Sir, Great tutorial by you, Please post some more Azure DevOps Tutorials.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.