Connect GitHub Actions to Azure using OpenID Connect
published: 01-14-2023
Until recently it was recommended to connect to Azure from a GitHub Action using a service principal, you can find documentation on that here. However, the new way is a connection through OpenID Connect. This did give me some trouble in the beginning but through a little trial and error I was able to get it working with the script below:
Step 1: Connect to Azure using OpenID Connect
NOTE: Replace the values in the script with your own and be sure you have proper permission to create app registrations/service principals and edit them in Azure AD.
Param(
[Parameter(Mandatory = $true)]
[String]
$AppName
)
# -------------------------------------------------
# Create an Azure AD application
# -------------------------------------------------
$APP_JSON = az ad app create `
--display-name "${AppName}" `
$APP_DATA = $APP_JSON | ConvertFrom-Json
$APP_ID = $APP_DATA.appId
$APP_OBJECT_ID = $APP_DATA.id
# -------------------------------------------------
# Create a service principal for above app
# -------------------------------------------------
$SP_JSON = az ad sp create `
--id $APP_ID
$SP_DATA = $SP_JSON | ConvertFrom-Json
$SP_ASSIGNEE_OBJECT_ID = $SP_DATA.id
# -------------------------------------------------
# Assign role to the service principal
# -------------------------------------------------
$ROLE_NAME = "Contributor"
$SUBSCRIPTION_ID = az account show --query id --output tsv # Returns the current subscription ID
az role assignment create `
--role $ROLE_NAME `
--subscription $SUBSCRIPTION_ID `
--assignee-object-id $SP_ASSIGNEE_OBJECT_ID `
--assignee-principal-type ServicePrincipal `
--scope "/subscriptions/${SUBSCRIPTION_ID}"
# -------------------------------------------------
# Add federated credentials for GitHub Actions
# -------------------------------------------------
$CREDENTIAL_NAME = $AppName
$GITHUB_ORG = "<Name of GitHub Org or GitHub Username>"
$GITHUB_REPO = "<Name of GitHub Repo>"
$GITHUB_REPO_BRANCH = "<Name of GitHub Repo Branch>"
$REQUEST = @{
name = $CREDENTIAL_NAME
issuer = "https://token.actions.githubusercontent.com"
subject = "repo:${GITHUB_ORG}/${GITHUB_REPO}:ref:refs/heads/${GITHUB_REPO_BRANCH}"
description = "Federate GitHub Action"
audiences = @("api://AzureADTokenExchange")
}
$REQUEST_JSON = ($REQUEST | ConvertTo-Json -Compress) -replace '"', '\"'
az rest `
--headers "Content-Type=application/json" `
--method POST `
--uri "https://graph.microsoft.com/beta/applications/${APP_OBJECT_ID}/federatedIdentityCredentials" `
--body $REQUEST_JSON
The above script will create the required App Registration and Service Principal in Azure Active Directory with a contributor role assignment. It will then create a federated credential for the App Registration that will be used to connect to Azure from GitHub Actions.
Step 2: Manually :( add secrets to GitHub repo
After running the above script, you will need to add the following secrets to your GitHub repo:
|GitHub Secret Name|Azure Active Directory Application| |---|---| |AZURE_CLIENT_ID|Application (client) ID| |AZURE_TENANT_ID|Directory (tenant) ID| |AZURE_SUBSCRIPTION_ID|Subscription ID|
Step 3: Connect to Azure from GitHub Actions
This is an example of a GitHub Actions workflow that will connect to Azure using the OpenID Connect method. You can find details on the permissions required for this action here.
name: Azure Login with OpenID Connect
on:
push:
branches: [ main ]
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
jobs:
login:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: 'Az CLI login'
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Show Subscription
run: |
az account show
I hope this saves you some time and frustration. If you have any questions or comments, please feel free to reach out to me.