Use GitHub Actions with User-Assigned Managed Identity

Before we can automate our infrastructure as code, there is always to need to grant the required permissions to our release pipelines.  For GitHub Actions, this typically involved creating a Service Principal with a client secret.  By storing those credentials as GitHub secrets, your GitHub actions were able to connect to Azure.  Thanks to Federated Credentialswe can avoid the need of managing secrets and avoid the pain of potential expirations.

Service principal vs Managed Identity

This passwordless authentication was already available on Service Principals and became recently available on User-Assigned Managed Identities.  What you choose strongly depends on your use case.  For my situation, I identified the following advantages of using this with a Managed Identity:

  • It’s an Azure (not AAD) resource, so we can manage it through Bicep
  • We can reuse this identity for the deploymentScripts, so all deploy actions run under the same identity

How to configure it?

Before you execute these steps, I assume that a GitHub repository is available and you have Admin rights. Execute the following steps for every environment. A user with Owner permissions on the Azure subscription(s) is needed.

Create Managed Identity

Let’s start by creating the Identity:

  • Create a User-Assigned Managed Identity:

  • In the Federated credentials tab, click + Add Credential and choose the GitHub Actions scenario.
  • Configure all requested parameters.  The most important aspect is that you restrict access to a specific environment.  Later, during the GitHub setup, you will see the concept of that environment again.

Assign Azure Permissions

The identity must have sufficient permission to deploy.  Grant the following subscription permissions, via the Azure role assignments tab:

  • Contributor: required to create all Azure resources
  • User Access Administrator: required to perform role assignments on managed identities

One remark: the fact that we require User Access Administrator rights to perform role-assignments on managed identities is a security issue.  On one hand, it’s more secure, because we use secretless managed identities.  On the other hand, it’s less secure, because we get too many access rights than actually needed.  The Azure engineering teams are aware of this issue and are working an a promising solution for this.

Configure GitHub Credentials

Execute the following steps in your GitHub repository:

  • Create a new environment (with the same name as above), in the Settings section of your GitHub repo:

  • Within the environment, add the following secrets:
    • AZURE_CLIENT_ID: the Client ID of the managed identity
    • AZURE_TENANT_ID: the Azure AD tenant ID
    • AZURE_SUBSCRIPTION_ID: the ID of the appropriate subscription

Configure your GitHub workflow

Last, but not least, you have to configure your GitHub workflow to use Open ID Connect with the specified environment secrets.  You can find a working example here.

permissions:
  id-token: write
  contents: read
  • Link the job to the correct environment
jobs: 
  deploy-infra:
    name: Deploy Infra
    runs-on: windows-latest
    environment: prd
  • Use the azure/login@v1 action to connect to Azure with the created secrets
- name: Log into Azure
  uses: azure/login@v1
  with:
    client-id: ${{ secrets.AZURE_CLIENT_ID }}
    tenant-id: ${{ secrets.AZURE_TENANT_ID }}
    subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

Conclusion

A fairly simple way to allow GitHub runners to authenticate against your Azure environment, without the hassle of shared secrets!  That’s a great addition to both products and a nice example of a shared strategy vision GitHub and Azure.

Remember: sharing is caring!

Thanks
Toon

ABOUT

MEET THE YOUR AZURE COACH TEAM

Your Azure Coach is specialized in organizing Azure trainings that are infused with real-life experience. All our coaches are active consultants, who are very passionate and who love to share their Azure expertise with you.