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'
The
trigger
section specifies when the pipeline should run. In this case, it triggers when there are changes to themain
branch.The
pool
section specifies the agent and environment for the pipeline. It uses theubuntu-latest
image.This step sets up the Python environment for the pipeline. It specifies to use
Python 3. x
, adding Python to thePATH
, and using thex64
architecture.
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 (
ubuntu-vm.pem
) securely.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 root@20.30.40.50 "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 root@20.30.40.50 "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
main
branch, and pulling the latest code from Git.The second script activates a virtual environment and installs Python package requirements from
requirements.txt
.
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 root@20.30.40.50 "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_USERNAME
andAZURE_DEVOPS_PAT
variables 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 root@20.30.40.50 "cd /home/root/backend/fastcraft && sudo systemctl restart backend && exit"
displayName: 'Deploy 🤘'
- This script restarts the backend service using
systemctl
to 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 forPipelines
andReleases
. Click onPipelines
.Create a New Pipeline: Click the
New Pipeline
button 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_USERNAME)
and$(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.