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

Reading Time: ~10 mins

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
  • 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.

  • 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 😱

  • 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.

    • Azure Function App
    • Azure Storage Account
    • 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



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

    Final folder structure looks like below:


  • 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. 😎


  • 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: Publish Web 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

  • 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
      • Template parameters: East US
      • 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 🥂