How To Create and Deploy a Python Azure Function Using Azure DevOps CI/CD
An Azure Function is a simple way of running small pieces of code in the cloud. You don’t have to worry about the infrastructure required to host that code. You can write the Function in C#, Java, JavaScript, PowerShell, Python, or any of the languages that are listed in the Supported languages in the Azure Functions article.
There are a lot of deployment strategies when you deploy your Azure functions to production and your deployment strategy entirely depends on your application architecture and the DevOps tools you are using. For example, If you are using Jenkins you can set up the build pipeline and deploy the application in Jenkins.
Using Azure DevOps, you have a ready-made template to deploy your function app. In this post, we will see how we can deploy an Azure function app using Azure DevOps.
- Introduction
- Prerequisites
- Create Local Project
- Create Azure Function App.
- Build Pipeline
- Release Pipeline
- Demo
- Summary
- Conclusion
1- Introduction
The function app contains individual functions in which your function code resides. Each function app contains either one or more than one function serving as an individual endpoint. When the function app’s authorization level is anonymous, you can access the function app endpoints directly from the internet.
We can directly deploy our Azure functions to the function app from VSCode with the Azure Functions extension for Visual Studio Code. But, when you are working in a team, deploying directly from the local machine is not an ideal solution. We need to build a pipeline in which the entire team can collaborate.
We have to build two pipelines to deploy this application using Azure DevOps: Build Pipeline and Release Pipeline
Build Pipeline
This pipeline takes the code from the Azure Repos or any version control and goes through a series of actions such as install, test, build and finally, generate the artifacts ready for the deployment.
Release Pipeline
This pipeline takes the artifact and deploys it into the function app. You can have pre-deployment conditions such as approvals, deployment triggers, etc for the release to production environment.
2- Prerequisites
First you need to set up a Microsoft Azure Account to deploy that code using Function App Service. Let’s create the account by following the links below.
- Microsoft Azure Account
- Login into Azure DevOps
- Visual Studio Code
- The Azure Functions Core Tools version 3.x.
- The Python extension for Visual Studio Code.
- Azure Function App Extension for Visual Studio Code.
- GIT For Windows
- Function App on Azure.
3- Create Local Project
In this section, you use Visual Studio Code to create a local Azure Functions project in Python. Later in this article, you’ll publish your function code to Azure.
- Choose the Azure icon in the Activity bar, then in the Azure: Functions area, select the “Create new project…” icon.
2. Choose a directory location for your project workspace and choose Select.
3. Provide the following information at the prompts:
- Select a language for your function project: Choose Python.
- Select a Python alias to create a virtual environment: Choose the location of — your Python interpreter.
If the location isn’t shown, type in the full path to your Python binary. - Select a template for your project’s first function: Choose HTTP trigger.
- Provide a function name: Type HttpExample.
- Authorization level: Choose Anonymous, which enables anyone to call your function endpoint. Select how you would like to open your project: Choose Add to workspace.
4. Using this information, Visual Studio Code generates an Azure Functions project with an HTTP trigger. You can view the local project files in the Explorer.
Run the function locally
Visual Studio Code integrates with Azure Functions Core tools to let you run this project locally on your computer.
- Press F5 to start the function app project. Output from Core Tools is displayed in the Terminal panel. Your app starts in the Terminal panel. You can see the URL endpoint of your HTTP-triggered function running locally.
2. With Core Tools running, go to the Azure: Functions area. Under Functions, expand Local Project > Functions. Right-click (Windows) the HttpExampleProject function and choose Execute Function Now.
3. In the “Enter request body,” you see the request message body value of { “name”: “Azure” }. Press Enter to send this request message to your function.
4. When the function executes locally and returns a response, a notification is raised in Visual Studio Code. Information about the function execution is shown in the Terminal panel.
5. Press Ctrl + C to stop Core Tools and disconnect the debugger.
After you’ve verified that the function runs correctly on your local computer, it’s time to use Azure DevOps to create CI/CD pipeline to deploy this function to Azure Function App.
Before creating Pipeline in Azure Devops, first we need to create a function app on Azure Portal as below:
4- Create Azure Function App
Login into the portal and click on Create Resource or you can search for Function app from the search bar to create and give required fields such as app name, storage account, and resource group, runtime stack, etc.
Your provisioning should be completed after some time.
Here is the function app created and you can access the APIs with that URL as long as its authorization level is anonymous.
5- Build Pipeline
We need to build pipelines as part of Continuous Integration first. The way this pipeline works is that the moment you check-in code into Github or Azure Repos, this pipeline builds the project, tests it and makes the build artifact ready for deployment. Let’s follow all the steps to set up this pipeline.
- Create a Project in Azure DevOps
- Create a Repo and Put your code in Azure Repos
- Create a pipeline that takes it from the source repository.
- Install all dependencies
- Run the tests
- Build the code
- Copy files from source for staging
- Archive all the copied files
- Finally, publish the artifact.
- Enable Continuous Integration with triggers
Let’s create a project in your Azure DevOps account. I named the project Azure_function_demo which is a Private project. You can make the project public or private as per your choice of visibility.
Put your code in Azure Repos
It’s time to create a repo and place all the code from the example project from above and push the code into this repo. I created a repo called Azure_function_demo and pushed all the code into this repo.
Create a Build Pipeline
Let’s create a pipeline by selecting a source and repository branch and by selecting a classic editor.
On the next page, select the Azure Function for the Python template as Azure provides ready to use templates for us.
Once you click on the Apply button, you can see the next screen with all these tasks. You can change the pipeline name as you want. I have changed it to Azure_function_demo-CI. If you notice the tasks it is using the Python version 3.6, install dependencies, build extensions, archive files, and publish the artifact.
Click on the save to save this into any folder. Let’s define the trigger.
Define The Trigger
Let’s define the trigger for this build. Click on the Triggers tab and enable Continuous Integration. Any commit to the Azure_function_demo repo master branch triggers this pipeline.
Let’s build the pipeline manually this time by clicking on the Queue.
Click on Agent Job 1 to see the results.
Click on the artifact link from the logs screen. You will be able to see the created artifact in a zip file as below.
You can download the zip file to cross verify if all the functions you have created are present in it or not.
6- Release Pipeline
We are done with the Continuous Integration part and let’s build a release pipeline for Continuous Delivery. Click on the releases, New Release and follow the instructions below.
- Define Artifact.
- Select the template for deployment.
- Give a name to the stage.
- Define the tasks on stage.
- Add Artifact.
- Enable the trigger for continuous deployment.
Define the Artifact
The first step is to define the artifact so that it takes that particular artifact after the build pipeline is completed. Make sure you have a trigger placed.
When you click on the releases you see an empty page with a new pipeline button. Click on it to create a new release pipeline. Select a template called Deploy a function app to Azure Functions.
You can name the stage name. I named it Dev.
Click on the Job task section of the stage to define the tasks.
We need to add an artifact by selecting the source pipeline
Once it is added, you can have a trigger defined. Click on the flash icon
7- Demo
It’s time for the demo. As soon as you check-in the code to master, it triggers the build pipeline. Usually, you don’t check in the code directly into master instead you create a pull request. I have used a master branch for simplicity.
I am manually triggering the Build Pipeline which will then trigger the release pipeline automatically. As soon as the build is completed, the artifact created will trigger the release pipeline.
Once it succeeds, you can go to the function app in the portal and verify the function.
You can test the function either directly in the portal or you can use the function URL and hit it in the browser or in the postman. You can see the response below from the portal as well as using the function URL.
After hitting the below URL of the deployed function you will see the below response.
https://demo-fun-api.azurewebsites.net/api/HTTPExampleProject?name=Abhilash
8- Summary
- One way of building a Python REST API is to use the Azure function app.
- There are lots of deployment strategies when you deploy your Azure functions to production. The deployment strategy entirely depends on your application architecture and the DevOps tools you are using.
- Using Azure DevOps, you have a ready to use template to deploy your function app.
- You have to build two pipelines to deploy this application using Azure DevOps: Build pipeline and Release pipeline.
- The build pipeline generates the artifact as soon as there is a commit in the source repository.
- The Release pipeline takes the artifact and releases it to the appropriate environment.
- Appropriate service connections should be present/created to work with pipelines for authentication purpose
- You can use task groups to put the common tasks in one place across the environments.
- You can use Azure key vault to store the access keys for your storage account.
- You can make use of Pipeline Variables while creating tasks. It’s a convenient way to get key bits of data into various stages of the pipeline.
9- Conclusion
This is a basic way of deploying a function app using Azure DevOps. I didn’t use variables, Azure key vault, task groups in these pipelines because we are deploying into one environment. Those are out of scope for this article.