App Deployment to Azure =================================== .. _deployment: Manual Deployment ------------------------ 1. Log in to Azure 2. Create a new Azure Container Registry (ACR) named “insurancemodel.azurecr.io” 3. Authenticate with Azure credentials :: docker login insurancemodel.azurecr.io The username is name of the registry, in this example “insurancemodel”. The password can be found in Azure Container Registry > Access keys. Tick the box “admin user” to reveal the password. 4. Push the image to the Azure registry :: docker push insurancemodel.azurecr.io/mlops-insurance-prediction:latest This will take some time, depending on the size of the image. The image should appear in the ACR. 5. Create a web app on Azure Azure portal > create a resource > web app > create > Choose a name (e.g. insurance-predictions) Select the following options: - Publish : Choose Container - Choose a region and a pricing plan (there is a free plan called “Free F1”). 6. Link the ACR image to your application Go to the Docker tab and fill the following details: - **Source** : ``Azure Container Registry`` - **Registry** : ``insurancemodel`` - **Image** : ``mlops-insurance-prediction`` - **Tag** : ``latest`` - **Port** : ``5000`` 7. The app is running and deployed to `https://insurance-predictions.azurewebsites.net `__ Continuous Deployment with GitHub Actions ------------------------------------------------ Prerequisites ------------- - Azure CLI installed and logged in - Azure Container Registry: ``insurancemodel`` - Azure Web App: ``insurance-predictions`` - GitHub repository with appropriate permissions Step 1: Create Azure Service Principal -------------------------------------- Run the following commands in Azure CLI to create a service principal with the necessary permissions. Get Resource IDs ^^^^^^^^^^^^^^^^ .. code-block:: bash # Get ACR resource ID ACR_ID=$(az acr show --name insurancemodel --query id -o tsv) # Get Web App resource ID WEBAPP_ID=$(az webapp show --name insurance-predictions --query id -o tsv --resource-group ) # Verify both IDs are retrieved echo "ACR ID: $ACR_ID" echo "WebApp ID: $WEBAPP_ID" Create Service Principal ^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: bash az ad sp create-for-rbac \ --name "github-actions-mlops-deployment" \ --role contributor \ --scopes $ACR_ID $WEBAPP_ID **Save the output!** It will look like: .. code-block:: json { "appId": "xxxx-xxxx-xxxx-xxxx", "displayName": "github-actions-mlops-deployment", "password": "xxxx-xxxx-xxxx-xxxx", "tenant": "xxxx-xxxx-xxxx-xxxx" } Grant ACR Push Permission ^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: bash az role assignment create \ --assignee \ --scope $ACR_ID \ --role AcrPush Step 2: Configure GitHub Secrets -------------------------------- Go to your GitHub repository → Settings → Secrets and variables → Actions → New repository secret Add the following secrets: 1. AZURE_CREDENTIALS ^^^^^^^^^^^^^^^^^^^^^ Format the service principal output as JSON: .. code-block:: json { "clientId": "", "clientSecret": "", "subscriptionId": "", "tenantId": "" } 2. AZURE_REGISTRY_USERNAME ^^^^^^^^^^^^^^^^^^^^^^^^^^ Value: ```` 3. AZURE_REGISTRY_PASSWORD ^^^^^^^^^^^^^^^^^^^^^^^^^^ Value: ```` Step 3: Verify Workflow Configuration ------------------------------------- The workflow file ``.github/workflows/azure-deploy.yml`` is configured with: - **Registry Name**: ``insurancemodel`` - **Image Name**: ``mlops-insurance-prediction`` - **Web App Name**: ``insurance-predictions`` If any of these need to be changed, edit the ``env:`` section in the workflow file. Step 4: Understanding Workflow Execution ---------------------------------------- Workflow Chain ^^^^^^^^^^^^^^ When you push to the ``main`` branch: 1. **Python Application** workflow runs first (tests and linting) 2. **Only if tests pass**, the Azure deployment workflow triggers automatically 3. If tests fail, deployment is skipped (preventing broken code from being deployed) Automatic Trigger ^^^^^^^^^^^^^^^^^ 1. Create a pull request and merge it to ``main`` 2. The Python application workflow runs first 3. If successful, the deployment workflow triggers automatically 4. Monitor progress in the Actions tab Manual Trigger ^^^^^^^^^^^^^^ 1. Go to Actions tab in GitHub 2. Select "Deploy to Azure Container Registry and Web App" 3. Click "Run workflow" 4. Select the ``main`` branch 5. Click "Run workflow" Troubleshooting --------------- Workflow fails at "Log in to Azure Container Registry" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Verify ``AZURE_REGISTRY_USERNAME`` and ``AZURE_REGISTRY_PASSWORD`` are correct - Check service principal has AcrPush role Workflow fails at "Deploy to Azure Web App" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Verify ``AZURE_CREDENTIALS`` secret is properly formatted JSON - Check service principal has contributor role on Web App - Ensure Web App is configured to use containers Docker build fails ^^^^^^^^^^^^^^^^^^ - Check Dockerfile syntax - Verify all required files are present in repository - Check build logs for specific errors Image Tags ---------- The workflow creates two tags for each deployment: - ``latest``: Always points to the most recent deployment - ````: Specific commit version (e.g., ``abc1234``) Full image path: ``insurancemodel.azurecr.io/mlops-insurance-prediction:latest`` Security Notes -------------- - Service principal credentials are stored as GitHub encrypted secrets - Credentials are never exposed in logs - Azure logout is performed after each workflow run - Consider rotating service principal credentials periodically