Continuous Deployment, Continuous Delivery – The CD of CI/CD (GitHub / Python / DevOps)

In this blog post I take my Flask (Python) web application and deployment to Microsoft Azure, and instead of doing it manually I do it via a CI/CD. I’ve previously discussed Continuous Integration (CI) in blog posts around CI, GitHub actions and recently Code Coverage. The CD of CI/CD can stand for Continuous Deployment or Continuous Delivery, depending on who you ask. I take it as Deployment, and will be using my previous assignment as the code to deploy.

A Diversion into Infrastructure as Code

The first step to deploying the code is to choose a location to deploy it too. I previously (manually) deployed the it to an Azure compute instance, so I’m going to use Azure again. This time however I don’t want to manually create instances or manually deploy the application. With this in mind I’m using some Bicep (Infrastructure as Code for Azure) to deploy a Microsoft Web App Service Plan and a Web App Service to use the plan.

Continuous Deployment, Continuous Delivery – The CD of CI/CD (GitHub / Python / DevOps)
Bicep for deploying Azure App Service Plan and App Service

I’ve got the Bicep running in its own pipeline to auto deploy the infrastructure. I’ve gone with a B1 SKU for the App Service Plan, which isn’t free but is one of the cheaper SKUs available. Also deploying to the Resource Group is a MySQL database instance.

Once the infrastructure has deployed correctly, the “Publish Profile” is required. The “Download publish profile” from the Web App Service Plan toolbar provides the profile as a file (if you are following along make sure to keep the profile secure, safe and secret!).

Web App Service Plan Toolbar showing options such as stop, restart, deleted, download publish profile
Web App Service Plan Toolbar

Add Profile To GitHub

Within the repository containing the Flask app I’ve added the publish profile as a “Repository Secret” called “AZURE_WEBAPP_PUBLISH_PROFILE”. The option for this can be found in the repositories Settings > Security > Secrets and variables > Actions.

GitHub repository settings showing General, Access, Code and Automation, Security and Integration options
GitHub repository settings

Add The Pipeline For Continuous Deployment / Delivery

I recommend creating a new branch (i.e. CD_Pipeline) and then adding a new YAML workflow under the .github/workflows/ folder. If you’ve not got a previous workflow I recommend having one for testing before creating one for deployment to help limit the chances of a code change breaking the deployment.

A YAML file that GitHub Actions can run, the jobs deploy the Flask app
GitHub Action to deploy the Flask app

I’ve got the pipeline to run each time a push is made to the ‘main’ branch, but tags or other branches could be used instead. The pipeline reads the ‘Publish Profile’ stored in the repositories secrets using a ‘with’ option. After a pull request to merge the branch the new pipeline, the app automatically deploys to Azure. Now every change to the main branch will see the app automatically be deployed.

Note: If you are using Microsoft Azure’s Web App Service Plan / Web App and have a domain / sub-domain available, then check out to learn how to get a free certificate to make the site HTTPS.