Learning to set up Azure Private Networking for GitHub-hosted runners. Based on this guide with some personal preferences with regards to using PowerShell and Bicep.
Why? You can use GitHub-hosted runners in an Azure VNET. This enables you to use GitHub-managed infrastructure for CI/CD while providing you with full control over the networking policies of your runners. See more details in the documentation.
- An Azure subscription with Contributor permissions
- An GitHub organization with CI/CD Admin (least privilege) or organization Owner
- GitHub CLI (tested with 2.51)
- PowerShell 7.x with Azure PowerShell modules (tested with Az.Resources 7.1)
- Azure Bicep (tested with 0.28.1)
Note that there is limited support for Azure Regions. See supported regions here.
-
Authenticate to GitHub CLI by running
gh auth login
-
Find your organization id by running the following script and providing the username of your GitHub organization:
./scripts/gh-api-prereqs.ps1 -OrganizationUsername <org-username>
# Output:
{
"data": {
"organization": {
"login": "<org-username>",
"databaseId": <id>
}
}
}
👉 Copy the value from the "databaseId"
field for the next step.
- Deploy a subnet
Option 1: Sandbox deployment: Run the following deployment script to create a new resource group, a new virtual network and configure a new subnet to be set up for private networking:
./scripts/deploy.ps1 -GitHubDatabaseId <databaseId>
# Output
Registring GitHub.Network resource provider...
Configuring resource group and virtual network...
Deploying template...
✅ Deployment complete!
Network Settings Resource Id:
<network settings resource id>
👉 Copy the Network Settings Resource Id
value for the next step.
Option 2: Deploy to existing vnet: If you want to set up a new subnet in an existing virtual network you can deploy the main.bicep
and provide the necessary parameters by editing the main.bicepparam
file, and then running the following command:
$resourceGroupName = "<existing resource group name>"
$deploy = New-AzResourceGroupDeployment -Name "gh-private-runners-$now" `
-ResourceGroupName $resourceGroupName -TemplateFile './bicep/main.bicep' `
-TemplateParameterFile "./bicep/main.bicepparam"
$networkSettings = Get-AzResource -ResourceId $deploy.Outputs.networkSettingsId.value
Write-Host "Network Settings Resource Id:"
Write-Host $networkSettings.Tags['GitHubId']
👉 Copy the Network Settings Resource Id
value for the next step.
- Configure the network configuration for your organization in GitHub
See steps here. Remember to connect the runner to a runner group and configure labels accordingly.
- Use the new privately networked GitHub-hosted runner!
You should be able to use the runner by following the same steps as in:
See details about deleting the configuration here.
After completing clean-up in Azure you can also delete the resource group if you have deployed it as a sandbox.
If you are considering running runners for GitHub Actions in your own Azure private networking, and this scenario does not suit you, you can also consider:
- Running self-hosted runners on Azure Container App Jobs (simple and cost-effective solution)
- Running self-hosted runners on whatever compute and infrastructure you like (can be a hassle..)