In today's fast-paced development world, keeping your application up to date manually is crucial. However, manual updates can be time-consuming and error-prone. That's where Azure Pipelines comes to the rescue. In this article, I will explore how to set up an automated deployment pipeline that makes updating your FastAPI app as simple as a few clicks.
Prerequisites: Before diving into the nitty-gritty, here's what you'll need:
An Azure account (if you don't have one, sign up for a free one).
Your source code is hosted on Azure repos.
A secure shell (SSH) key to access your server.
A target server (in our case, an Ubuntu VM).
I am assuming that you can deploy the FastAPI application in the Ubuntu server with Nginx. If you are not able to do this, no worries. Just follow the article here.
Firstly, let’s create a file named
azure-pipelines.yml and follow the below instructions.
trigger: - main pool: vmImage: 'ubuntu-latest' steps: - task: UsePythonVersion@0 inputs: versionSpec: '3.x' addToPath: true architecture: 'x64'
triggersection specifies when the pipeline should run. In this case, it triggers when there are changes to the
poolsection specifies the agent and environment for the pipeline. It uses the
This step sets up the Python environment for the pipeline. It specifies to use
Python 3. x, adding Python to the
PATH, and using the
The next steps focus on downloading the
SSH key, preparing it, and using it for secure server access. It is important that I have stored the
ubuntu-vm.pem file in the
Secure files of the Azure Pipelines
library for security reasons.
- task: DownloadSecureFile@1 displayName: 'Download SSH Key' inputs: secureFile: ubuntu-vm.pem' - script: | echo 'The PEM file has been downloaded to $(Agent.TempDirectory)' chmod 600 $(Agent.TempDirectory)/ubuntu-vm.pem displayName: 'Prepare SSH Key'
The DownloadSecureFile task fetches the SSH key (
The subsequent script task prepares the key by ensuring it has the appropriate permissions.
Now, the script starts the server-related actions, such as updating the application and installing requirements:
- script: | ssh -i $(Agent.TempDirectory)/ubuntu-vm.pem -o StrictHostKeyChecking=no email@example.com "cd /home/root/backend/fastcraft && git checkout main && git pull && exit" displayName: 'Update from Git' - script: | ssh -i $(Agent.TempDirectory)/ubuntu-vm.pem -o StrictHostKeyChecking=no firstname.lastname@example.org "cd /home/root/backend/fastcraft && source venv/bin/activate && pip install -r requirements.txt && exit" displayName: 'Install Requirements'
The first script updates the application by logging into the server, navigating to the project directory, checking out the
mainbranch, and pulling the latest code from Git.
The second script activates a virtual environment and installs Python package requirements from
After that, I move on to installing custom packages from
Azure Repos. One of these packages I have installed and are using is called
luminous which is a custom package and it's private. It's like adding an extra layer of security and a better logging facility.
- script: | # Install the 'luminous' package from the azure repos ssh -i $(Agent.TempDirectory)/ubuntu-vm.pem -o StrictHostKeyChecking=no email@example.com "cd /home/root/backend/fastcraft && source venv/bin/activate && pip uninstall -y luminous && pip install --no-cache-dir git+https://$(AZURE_DEVOPS_USERNAME):$(AZURE_DEVOPS_PAT)@dev.roni.com/Software-Porjects/Security%20Research/_git/luminous@main#egg=luminous" displayName: 'Install luminous package'
These scripts install custom Python packages (
luminous) from Azure Repos.
To add the
AZURE_DEVOPS_PATvariables in Azure Pipelines, navigate to your pipeline settings, and you can easily configure these variables as shown in the attached screenshot. This ensures secure access to your repository within your pipeline.
The final step restarts the backend service to apply the updates:
- script: | ssh -i $(Agent.TempDirectory)/ubuntu-vm.pem -o StrictHostKeyChecking=no firstname.lastname@example.org "cd /home/root/backend/fastcraft && sudo systemctl restart backend && exit" displayName: 'Deploy 🤘'
- This script restarts the backend service using
systemctlto ensure the updates take effect.
I think you already pushed this
.yml file in Azure Repos
main branch. So let’s do the rest of the things in the Azure DevOpsportal. Now Just follow the blew instructions:
Navigate to Pipelines: Inside your project, go to
Pipelines. You should see options for
Releases. Click on
Create a New Pipeline: Click the
New Pipelinebutton to start creating a new pipeline.
Connect to Your Repository: Azure DevOps will guide you to connect to your repository. Select the repository you want to build a pipeline for.
Configure Your Pipeline: You will be prompted to choose how you want to set up your pipeline. Select "YAML" since you have a YAML script.
YAML Configuration: Copy and paste your provided YAML script into the YAML editor.
Variable Substitution (Optional): If your YAML script contains variables like
$(AZURE_DEVOPS_PAT), you need to define these variables in the pipeline settings. Click on "Variables" to define them. I have already included a screenshot a little earlier, which demonstrates the process.
Save and Run: Once you have pasted the script and defined any necessary variables, save the pipeline configuration. You can also set up triggers (e.g., branch triggers) as per your project's needs.
By following these steps, you can configure and run your pipeline for your repository. The pipeline will execute the tasks specified in your YAML script, automating the deployment of your FastAPI application on the Ubuntu server.