Migrate a Python App to Azure

Migrate a local Flask app to Azure App Service using the Azure CLI.

Introduction

30 Second Summary

Every application starts on someone's laptop. But an app running locally is invisible to the rest of the world. To make it accessible, you need to move it to the cloud.

In this project, you will build a Python web application and migrate it to Azure's cloud using App Service. By the end, your app will be live on the internet with a public URL that anyone can visit.

What You'll Build

A Python Flask task tracker application deployed to Azure App Service using the Azure CLI.

By the end of this project, you'll have:

  • A working Python Flask web application with a homepage and API endpoint running locally on your machine.
  • A live deployment on Azure App Service with a public URL anyone can visit.
  • Hands-on experience with the replatform cloud migration strategy and the Azure CLI deployment workflow.
  • Secret Mission: Deploy an update to your live app to practice iterative cloud deployments.

Are there any prerequisites?

None. This guide includes full setup instructions for Python, VS Code, the Azure CLI, and a free Azure account. You do not need any prior cloud experience.

Set Up Your Development Environment

Before you can build and deploy your Flask application, you need the right tools installed on your machine.

In this step, you will install Python (the language your app is written in), VS Code (your code editor), and the Azure CLI (the tool that deploys your app to the cloud).

In this step, get ready to:
  • Install Python 3.11 and verify it works.
  • Install VS Code with the Python extension.
  • Install the Azure CLI and verify it works.
Install Python 3.11

Python is the programming language you will use to build your Flask web application. You need version 3.11 or higher installed on your machine.

  • Open your browser and go to python.org/downloads.
  • Download the Python 3.11 installer for your operating system.
  • Run the installer.

Windows users: check Add Python to PATH

During the Windows installer, you will see a checkbox at the bottom of the first screen that says Add Python to PATH. Check this box before clicking Install Now.

Without it, your terminal will not recognize the python command.

  • Once installation finishes, open a new terminal window.
  • Check your Python version by running this command:
python --version

✔️ I see version 3.11 or higher

Python is installed and available on your PATH. You are ready to move on.

ⓧ I see a version lower than 3.11

Your system has an older version of Python installed. You need 3.11 or higher for this project.

  • Go to python.org/downloads and download the 3.11 installer.
  • Run the installer. On Windows, check Add Python to PATH.
  • On macOS, the new installer adds Python 3.11 alongside your system Python. After installing, try running python3.11 --version to confirm it is available.
  • Close your terminal and open a new one, then run python --version again to confirm.

ⓧ Command not found

Python is not installed or not on your PATH.

  • Go to python.org/downloads and download the 3.11 installer for your operating system.
  • Run the installer. On Windows, check Add Python to PATH before clicking Install Now.
  • Close your terminal and open a new one after installation completes.
  • Run python --version again to verify.

macOS users may need python3

On macOS, the command may be python3 --version instead of python --version. Either works as long as you see 3.11 or higher in the output.

Install VS Code

VS Code is a free code editor that makes writing Python easy with syntax highlighting, autocompletion, and a built-in terminal.

  • Open your browser and go to code.visualstudio.com.
  • Download and install VS Code for your operating system.
  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Visual Studio Code and press Enter to open it.
  • Click the Extensions icon in the left sidebar (it looks like four small squares).
  • Type Python in the search box at the top.
  • Find the extension published by Microsoft and click Install.

Why the Python extension?

The Python extension adds syntax highlighting, error detection, and code completion for Python files. It also helps VS Code find the correct Python interpreter on your machine.

Install the Azure CLI

The Azure CLI is a command-line tool that lets you manage Azure resources directly from your terminal. You will use it to deploy your app to the cloud.

macOS

On macOS, you install the Azure CLI through Homebrew. If you do not have Homebrew installed, get it first from brew.sh.

  • Install the Azure CLI by running this command:
brew update && brew install azure-cli

What does this command do?

The brew update part refreshes Homebrew's list of available packages. The brew install azure-cli part downloads and installs the Azure CLI.

Windows

On Windows, you can install the Azure CLI using WinGet (the Windows Package Manager) or the MSI installer.

  • Open PowerShell and install the Azure CLI by running this command:
winget install --exact --id Microsoft.AzureCLI

What does this command do?

WinGet is the Windows Package Manager. The --exact flag ensures you get the official Azure CLI package. The --id Microsoft.AzureCLI specifies the exact package to install.

  • After installation completes, close and reopen your terminal window before continuing.

Alternative: MSI installer

If WinGet is not available on your machine, download the MSI installer directly from the official Microsoft install page. Run the installer and follow the prompts.

  • Verify the Azure CLI is installed by running this command:
az --version

✔️ I see version information

The Azure CLI is installed and ready. You will see output listing the azure-cli version along with other components.

ⓧ Command not found

The Azure CLI is not on your PATH or did not install correctly.

  • On Windows, close and reopen your terminal. The CLI is only available in new terminal windows after installation.
  • On macOS, make sure Homebrew completed without errors. Re-run brew install azure-cli if needed.
  • If you still have trouble, visit the official Azure CLI install guide for detailed troubleshooting steps.

Your development environment is ready. Next up, you will build your Flask application and see it running locally.

Build Your Local Flask Application

Your development tools are ready. Now it is time to build the application you will eventually migrate to the cloud.

In this step, you will create a Python Flask web application with two routes: a homepage and a status API endpoint. You will run it locally to confirm everything works before deploying it to Azure.

In this step, get ready to:
  • Create a project folder and Python virtual environment.
  • Write a Flask application with a homepage and API endpoint.
  • Test the application locally in your browser.
Set up a virtual environment

A virtual environment is an isolated space where Python installs packages without affecting the rest of your system. Every Python project should have its own virtual environment.

  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your project folder and move into it by running these commands:
mkdir task-tracker
cd task-tracker
  • Confirm the folder was created by running:
ls ~/Desktop

You should see task-tracker listed in the output.

  • Create a virtual environment by running this command:
python -m venv venv

What does this command do?

python -m venv venv tells Python to create a virtual environment in a folder called venv. This folder holds a private copy of Python and any packages you install.

  • Activate the virtual environment by running the command for your operating system:

macOS

source venv/bin/activate

Windows

.\venv\Scripts\activate

You should see (venv) appear at the beginning of your terminal prompt. This confirms the virtual environment is active.

Don't see (venv) in your prompt?

Make sure you are inside the task-tracker folder when you run the activation command. The venv folder must exist in your current directory.

On Windows, if you see a permissions error, open PowerShell as Administrator and run Set-ExecutionPolicy RemoteSigned, then try activation again.

help me activate my Python virtual environment

  • Install Flask by running this command:
pip install flask==3.0.3

You should see output ending with a line that mentions Successfully installed followed by Flask and its dependencies.

Seeing a pip not found error?

Make sure your virtual environment is active. You should see (venv) in your prompt. If not, run the activation command again.

help me fix pip not found in my virtual environment

  • Create a requirements.txt file inside your task-tracker folder. In VS Code, click File, then Open Folder, and select the task-tracker folder on your Desktop.
  • In the Explorer sidebar, click the new file icon and name it requirements.txt.
  • Add this single line to requirements.txt:
flask==3.0.3

Why create requirements.txt?

This file lists every Python package your app needs. When you deploy to Azure, App Service reads this file and automatically installs your dependencies.

Pinning the exact version (flask==3.0.3) guarantees your app behaves identically in development and production.

  • Save requirements.txt.
Create the application

Azure App Service auto-detects Flask apps by looking for a file named app.py. Using this filename means zero configuration when you deploy later.

  • In the Explorer sidebar in VS Code, click the new file icon and name it app.py.
  • Add the following code to app.py to set up Flask and create your homepage route:
from flask import Flask, jsonify

app = Flask(__name__)


@app.route("/")
def home():
    return "<h1>Task Tracker</h1><p>Welcome to the Task Tracker app. This application has been migrated to Azure!</p>"

What does this code do?

  • from flask import Flask, jsonify imports the Flask framework and a helper for returning JSON responses.
  • app = Flask(__name__) creates your application instance. Flask uses __name__ to know where to find your project files.
  • @app.route("/") maps the root URL to the home() function. When someone visits your site, they see this HTML response.
  • Add the status endpoint and the startup block below your home() function:
@app.route("/status")
def status():
    return jsonify({"status": "running", "platform": "Azure App Service", "version": "1.0.0"})


if __name__ == "__main__":
    app.run()

What does this code do?

  • @app.route("/status") creates a second endpoint at /status. This is an API route that returns structured JSON data instead of HTML.
  • jsonify() converts a Python dictionary into a proper JSON response with the correct headers.
  • if __name__ == "__main__" ensures the app only starts when you run the file directly. This block is needed for local testing.
  • Save app.py.

Seeing red underlines in VS Code?

If VS Code shows import errors for Flask, it might be using the wrong Python interpreter. Press Cmd+Shift+P (macOS) or Ctrl+Shift+P (Windows), type Python: Select Interpreter, and choose the one inside your venv folder.

help me fix Flask import errors in VS Code

✔️ Awesome, I've got everything!

Great. Double check you have saved app.py before moving on.

ⓧ I'd like to double check the full code

Here is the full app.py file:

from flask import Flask, jsonify

app = Flask(__name__)


@app.route("/")
def home():
    return "<h1>Task Tracker</h1><p>Welcome to the Task Tracker app. This application has been migrated to Azure!</p>"


@app.route("/status")
def status():
    return jsonify({"status": "running", "platform": "Azure App Service", "version": "1.0.0"})


if __name__ == "__main__":
    app.run()

And here is requirements.txt:

flask==3.0.3
Test locally

Before migrating anything to the cloud, you need to confirm your app runs correctly on your own machine. This is a core principle of any cloud migration.

  • In your VS Code terminal (make sure (venv) is still showing in your prompt), start your Flask app by running:
flask run

What does this command do?

flask run starts a local development server. Flask automatically finds your app.py file and serves your application at http://localhost:5000.

  • Open your browser and go to http://localhost:5000.

You should see a page with the heading Task Tracker and a welcome message below it.

  • Now visit http://localhost:5000/status in your browser.

You should see a JSON response showing "status": "running" along with the platform and version values.

  • Go back to your terminal and press Ctrl+C to stop the Flask server.

Don't see your app in the browser?

Make sure the Flask server is still running in your terminal. You should see output like Running on http://127.0.0.1:5000. If the server stopped, run flask run again.

Check that you saved app.py before running the command. Unsaved changes will not be picked up by the server.

help me get my Flask app running locally

Your application runs perfectly on your local machine. Next up, you will set up your Azure account so you can migrate this app to the cloud.

Set Up Your Azure Account

Your Flask app runs perfectly on your machine. Now you need somewhere in the cloud to run it.

To deploy your app, you need an Azure account and a way to talk to Azure from your terminal. In this step, you will create a free Azure account, log in through the Azure CLI, and confirm everything is connected.

In this step, get ready to:
  • Create a free Azure account with $200 in credits.
  • Log in to Azure via the CLI.
  • Verify your subscription is active.
Create a free Azure account

Azure offers a free account that includes $200 in credits for 30 days and access to the App Service Free plan at $0 indefinitely. You do not need to pay anything to complete this project.

  • Open your browser and go to azure.microsoft.com/free.
  • Click Start free.
  • Sign in with an existing Microsoft account or create a new one.
  • Complete the sign-up form. Azure requires a credit card for verification but will not charge you unless you manually upgrade later.

What do I get with the free account?

New Azure accounts receive $200 in credit for 30 days, 12 months of select free services, and 65+ always-free services. The App Service F1 Free plan is always free regardless of whether your credits expire.

Having trouble signing up?

Make sure your credit card is valid and has not been used for a previous Azure free trial. Azure allows one free account per credit card.

help me sign up for an Azure free account

Log in via the Azure CLI

The Azure CLI needs to know who you are before it can create resources on your behalf. The az login command opens your browser so you can authenticate with your new Azure account.

  • Log in to Azure from your terminal by running this command:
az login

What happens when you run this?

The Azure CLI opens your default browser and loads an Azure sign-in page. Sign in with the Microsoft account you just created. After successful authentication, your browser shows a confirmation message and your terminal displays a list of subscriptions linked to your account.

If your browser does not open automatically, the CLI will display a URL and a code. Open the URL manually and enter the code to complete sign-in.

  • Sign in with the same Microsoft account you used to create your Azure free account.
  • If prompted to select a subscription, press Enter to accept the default.

After successful login, your terminal displays JSON output listing your subscription details.

Login not working?

Make sure you have a working internet connection. If your browser does not open, try running az login --use-device-code instead. This gives you a code to enter manually at a URL.

help me troubleshoot az login

Verify your account

Before deploying anything, confirm that your CLI is connected to the correct subscription. The az account show command displays your current active subscription details.

  • Confirm you are logged in by running this command:
az account show

What should I see?

You should see JSON output that includes fields like "isDefault": true and "state": "Enabled". The name field shows your subscription name, and the user field shows the email you signed in with.

If you see your subscription name and email address in the output, your Azure CLI is fully connected and ready for deployment.

Seeing the wrong subscription?

If you have multiple Azure subscriptions and the wrong one is showing, you can switch using az account set --subscription followed by the subscription name or ID from the az account list output.

help me select the right Azure subscription

Your Azure account is live and your CLI is authenticated. Next up, you will deploy your Flask app to Azure App Service with a single command.

Migrate Your Application to Azure

You have logged into Azure and confirmed your subscription is active. Now it's time for the main event: deploying your local Flask application to the cloud.

This is the replatform migration strategy in action. You will take your existing code and deploy it to Azure App Service, a managed platform that handles servers, scaling, and infrastructure for you.

In this step, get ready to:
  • Deploy your application to Azure with a single command.
  • Understand the cloud resources Azure provisions for you.
  • Confirm your app is live at a public URL.
Deploy with a single command

Azure CLI has a command called az webapp up that creates all necessary cloud resources and deploys your application in a single step. You need to choose a unique name for your app because it becomes part of your public URL.

Choosing your app name

Your app name must be globally unique across all of Azure. It can only contain lowercase letters, numbers, and hyphens. Try something like task-tracker-yourname or task-tracker-2026.

  • Make sure your terminal is inside your project folder (the folder containing app.py and requirements.txt).
  • Deploy your application to Azure by running this command:
az webapp up --runtime PYTHON:3.11 --sku F1 --name [[APP_NAME="your-app-name"]] --location eastus

What does this command do?

  • --runtime PYTHON:3.11 tells Azure to run your app on Python 3.11.
  • --sku F1 selects the Free tier, which costs $0/month.
  • --name sets your app's unique name (and its public URL).
  • --location eastus deploys to the East US data center.

This single command creates a resource group, an App Service plan, and a web app. Then it packages your code, uploads it, and installs your dependencies from requirements.txt.

This takes a minute or two

Azure is creating cloud infrastructure and deploying your code. You will see progress messages in your terminal as it provisions each resource. Wait for it to finish before moving on.

Understand what was created

When the command completes, Azure has provisioned three resources working together to host your application.

What did Azure create?

  • Resource group: a container that groups related Azure resources together. Azure auto-named it based on your app name (something like your-app-name_rg_eastus).
  • App Service plan: defines the compute resources (CPU, memory) your app runs on. Yours is on the F1 (Free) tier with shared cores, 1 GB RAM, and 1 GB storage.
  • Web app: the actual application running on a managed Linux container with Python 3.11. Azure automatically created a virtual environment and installed Flask from your requirements.txt.
Confirm your deployment

The command output includes your app's public URL. It follows the format https://your-app-name.azurewebsites.net where your-app-name is the name you chose.

  • Find the URL in your terminal output.
  • Open it in your browser.

You should see your Task Tracker homepage with the heading "Task Tracker" and the welcome message below it.

Seeing an error or blank page?

  • If you see "Application Error", wait 1-2 minutes and refresh. Azure may still be starting your app for the first time.
  • If the name was already taken, Azure will show an error during deployment. Pick a different name and run the command again with the new --name value.
  • Make sure you ran the command from the folder containing app.py. If you were in the wrong directory, Azure deployed empty content.

Still stuck? Help me troubleshoot my Azure App Service deployment.

Your application is live on the internet. Next up, you will explore your deployed app further by testing endpoints, streaming live logs, and navigating the Azure Portal.

Verify and Explore Your Live Application

Your Flask application is now live on Azure with a public URL. Anyone in the world can visit it.

In this step, you'll confirm both endpoints respond correctly. You'll also stream real-time logs from the cloud and explore the Azure Portal to see how your application is managed.

In this step, get ready to:
  • Test your homepage and API endpoint on the live URL.
  • Stream real-time logs from your deployed app.
  • Explore the Azure Portal to view your app's metrics and settings.
Test your live endpoints

Your app has two routes: a homepage and a /status API endpoint. Testing both confirms that your deployment succeeded and your code is running correctly in the cloud.

  • Open your browser and navigate to your app's URL:
https://[[APP_NAME="your-app-name"]].azurewebsites.net
  • You should see a page with the heading "Task Tracker" and a welcome message saying the application has been migrated to Azure.
  • Now test the API endpoint by appending /status to the URL:
https://[[APP_NAME="your-app-name"]].azurewebsites.net/status
  • You should see a JSON response showing the status, platform, and version of your application.

What should I see?

The /status endpoint returns a JSON object like this:

{"status": "running", "platform": "Azure App Service", "version": "1.0.0"}

This confirms your Flask app is running on Azure App Service and serving responses to the public internet.

Seeing an error page instead?

If you see a generic Azure error page, your app may still be starting up. Wait 30 seconds and refresh.

If the error persists, double-check that app.py is in the root of your project folder (not inside a subfolder). Azure App Service looks for app.py at the top level.

help me debug why my Azure App Service is showing an error page

Stream live logs

Live log streaming lets you see real-time output from your cloud application. This is how you debug issues or confirm requests are reaching your app.

  • First, enable container logging so that log streaming has output to show. Run this command:
az webapp log config --name [[APP_NAME="your-app-name"]] --resource-group [[RESOURCE_GROUP="your-resource-group-name"]] --docker-container-logging filesystem

What does this command do?

The --docker-container-logging filesystem flag tells Azure to capture stdout and stderr output from your app's Linux container. Without this, log streaming has nothing to display.

  • Now start live log streaming by running:
az webapp log tail --name [[APP_NAME="your-app-name"]] --resource-group [[RESOURCE_GROUP="your-resource-group-name"]]

What does this command do?

This opens a live stream of logs from your deployed app. You'll see HTTP requests, startup messages, and any errors in real time.

  • While the log stream is running, open a new browser tab and visit your app's homepage URL again.
  • Switch back to your terminal. You should see a new log entry showing the incoming GET request.
  • Press Ctrl+C to stop the log stream when you're done.

Not seeing any log output?

Make sure you ran the az webapp log config command first. Without it, log streaming has no data source.

Also confirm that your --name and --resource-group values match what was created in the previous step. Check the output from your earlier az webapp up command for the exact names.

help me fix my Azure log streaming

Explore the Azure Portal

The Azure Portal is the web-based management interface for all your Azure resources. It gives you a visual dashboard for everything the CLI can do.

  • Open your browser and navigate to:
https://portal.azure.com
  • Sign in with the same account you used for the Azure CLI.
  • In the search bar at the top of the portal, type the name of your app and select it from the results.
  • You'll land on the Overview page for your App Service. Take a moment to look around.

What can you see in the portal?

The App Service overview page shows your app's URL, status, runtime, and resource group at a glance.

In the left sidebar, you'll find sections for metrics (CPU, memory, requests), configuration (environment variables, connection strings), and deployment options. This is where you'd manage your app in a production environment.

  • Click on Configuration in the left sidebar under Settings to see your app's environment variables.
  • Click on Log stream in the left sidebar under Monitoring to see the same live logs you streamed from the CLI, now in the browser.

Bookmark the portal

You can pin your App Service to the portal dashboard for quick access. Click the pin icon on the overview page.

Secret mission

Deploy an Update

Your app is live on Azure. But in the real world, deploying once is just the beginning. Can you add new features and push an update to your live application using a single command?

Clean Up Your Resources

Clean Up Your Resources

This project uses the Azure App Service F1 Free plan, which costs $0 per month. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • 1 Resource Group (container for your Azure resources).
  • 1 App Service Plan (F1 Free tier).
  • 1 App Service Web App.
  • Local project files (app.py, requirements.txt, virtual environment).

Keep everything running

No action needed. Choose this if you are still actively building or want your app to stay live at its public URL.

  • Your app remains accessible at its .azurewebsites.net URL.
  • The F1 Free plan costs $0 per month. No charges will accrue.
  • Your local project files stay on your Desktop.
  • The Azure CLI remains installed on your machine for future projects.

Pause - I'll come back to this later

Stop your web app so it no longer serves traffic, but keep all resources in place for a quick restart later.

  • Stop your web app by running this command:
  • Replace the --name and --resource-group values with the ones you used during deployment.
az webapp stop --name [[APPNAME="your-app-name"]] --resource-group [[RESOURCEGROUP="your-resource-group-name"]]
  • When you are ready to resume, start it again by running:
az webapp start --name [[APPNAME="your-app-name"]] --resource-group [[RESOURCEGROUP="your-resource-group-name"]]

Why pause if it's free?

Since the F1 plan costs nothing, pausing is purely optional. Stopping the app frees up your daily CPU minutes allocation and prevents anyone from accessing your URL while you are away.

Delete - I don't want to use this again

Remove all project resources permanently. This cannot be undone.

  • Delete all Azure resources by removing the resource group. Run this command:
az group delete --name [[RESOURCEGROUP="your-resource-group-name"]] --yes

What does this command do?

Deleting a resource group removes everything inside it. This includes the App Service plan, the web app, and all deployment history. The --yes flag skips the confirmation prompt.

  • Delete your local project folder by running these commands:
cd ~/Desktop
rm -rf azure-flask-app

Windows users

If you are on Windows, use this command instead to delete the local folder:

cd ~\Desktop
rmdir /s /q azure-flask-app
  • Uninstall the Azure CLI if you do not plan to use it again.
  • On macOS, run:
brew uninstall azure-cli
  • On Windows, open Settings, then Apps, then Installed apps.
  • Search for Azure CLI and click Uninstall.

That's a Wrap!

That's a Wrap!

Nice work! You just migrated your first application from a local machine to the Azure cloud.

Here's what you accomplished:

  • Built a Python Flask web application with a homepage route and a /status API endpoint.
  • Deployed your app to Azure App Service using the replatform cloud migration strategy and a single az webapp up command.
  • Streamed live logs with the Azure CLI and explored your running app in the Azure Portal.
  • Secret Mission: Deployed an iterative update to your live app to practice the cloud deployment workflow.

Ready to quiz yourself?