name: Deploy Azure Self-Hosted Runner
# This workflow deploys the Azure Windows VM with Bastion for Excel integration testing
# Uses OIDC (OpenID Connect) for secure Azure authentication
# Manual software installation required after deployment (Excel, .NET SDK, GitHub runner)
# Setup guide: infrastructure/azure/GITHUB_ACTIONS_DEPLOYMENT.md
permissions:
contents: read
id-token: write # Required for OIDC authentication with Azure
on:
workflow_dispatch:
inputs:
resource_group:
description: 'Azure Resource Group name'
required: true
default: 'rg-excel-runner'
admin_password:
description: 'VM Admin password (secure input)'
required: true
type: string
jobs:
deploy-infrastructure:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Azure Login (OIDC)
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Create Resource Group
run: |
az group create \
--name ${{ inputs.resource_group }} \
--location swedencentral
- name: Deploy Bicep Template
id: deploy
run: |
az deployment group create \
--resource-group ${{ inputs.resource_group }} \
--template-file infrastructure/azure/azure-runner.bicep \
--parameters \
location=swedencentral \
adminPassword='${{ inputs.admin_password }}'
- name: Get Deployment Outputs
id: outputs
run: |
VM_NAME=$(az deployment group show \
--resource-group ${{ inputs.resource_group }} \
--name azure-runner \
--query 'properties.outputs.vmName.value' \
--output tsv)
VM_PRIVATE_IP=$(az deployment group show \
--resource-group ${{ inputs.resource_group }} \
--name azure-runner \
--query 'properties.outputs.vmPrivateIP.value' \
--output tsv)
BASTION_NAME=$(az deployment group show \
--resource-group ${{ inputs.resource_group }} \
--name azure-runner \
--query 'properties.outputs.bastionName.value' \
--output tsv)
echo "vm_name=$VM_NAME" >> $GITHUB_OUTPUT
echo "vm_private_ip=$VM_PRIVATE_IP" >> $GITHUB_OUTPUT
echo "bastion_name=$BASTION_NAME" >> $GITHUB_OUTPUT
- name: Display Next Steps
run: |
echo "✅ Deployment complete!"
echo ""
echo "📋 Next Steps:"
echo "1. Connect via Azure Bastion:"
echo " - Go to Azure Portal"
echo " - Navigate to VM: ${{ steps.outputs.outputs.vm_name }}"
echo " - Click 'Connect' → 'Bastion'"
echo " - Username: azureuser"
echo " - Password: (the admin_password you provided)"
echo ""
echo "2. Install software manually (in order):"
echo " a) Office 365 Excel (https://portal.office.com)"
echo " b) .NET 10 SDK (https://dotnet.microsoft.com/download)"
echo " c) GitHub Actions Runner:"
echo " - Go to: https://github.com/${{ github.repository }}/settings/actions/runners"
echo " - Click 'New self-hosted runner' → Windows"
echo " - Follow setup commands on VM"
echo " - Use labels: self-hosted, windows, excel"
echo ""
echo "3. Reboot VM after installation"
echo ""
echo "💰 Cost: ~\$200/month (VM \$61 + Bastion Developer \$140)"
echo ""
echo "🔗 VM Private IP: ${{ steps.outputs.outputs.vm_private_ip }}"
echo "🔗 Bastion: ${{ steps.outputs.outputs.bastion_name }}"
echo ""
echo "📚 Full setup guide: infrastructure/azure/GITHUB_ACTIONS_DEPLOYMENT.md"