Urgent.News

What's breaking now, across thousands of outlets.

Tech

Migrating CI/CD from Azure DevOps to GitHub Actions with Azure OIDC and ACR

Introduction As part of learning and preparing for a migration from Azure DevOps pipelines to GitHub Actions , I decided to build a small practice project before working with a real application. Project repository: github url The goal for this exercise was straightforward: Build a Go application, create a GitHub Actions pipeline, authenticate securely to Azure, build a Docker image, and push it…

Introduction

A report is being written detailing the process of migrating Continuous Integration/Continuous Deployment (CI/CD) pipelines from Azure DevOps to GitHub Actions using Azure OpenID Connect (OIDC) and Azure Container Registry (ACR).

Project Repository

The source code for the practice project is available at the following GitHub URL. The main objective of this exercise was to build a Go application, set up a GitHub Actions pipeline, authenticate securely to Azure, build a Docker image, and push it to Azure Container Registry.

Pipeline Goals

The goal was to create a workflow that could:

1. Run when a Pull Request is created

2. Build and test the Go application

3. Build a Docker image

4. Authenticate to Azure without using a client secret

5. Push the image to Azure Container Registry (ACR)

Workflow Overview

The final flow of the pipeline is as follows:

Pull Request → GitHub Actions → Go Build & Test → Docker Build → GitHub OIDC → Microsoft Entra ID → Azure Container Registry → Docker Image

Practice Project

A small Go REST API project was used for the exercise. The application's main focus was to be able to:

1. Build successfully with Go

2. Run inside Docker

3. Expose an HTTP endpoint

Verification of the application was done locally using `go run` and `curl` to test its health endpoint. The Docker image was also built locally and verified to ensure the container worked properly.

GitHub Actions Pipeline

A workflow file named `.github/workflows/ci-cd.yml` was created for the pipeline. The pipeline was intentionally kept simple and triggered by a Pull Request. The jobs section specifies the following steps:

1. Checkout code using `actions/checkout@v4`

2. Set up Go using `actions/setup-go@v5`

3. Download dependencies with `go mod download`

4. Build the Go application with `go build -v ./...`

5. Run Go tests using `go test ./...`

6. Build the Docker image with `docker build -t go-rest-api:1.0 .`

Pull Request Trigger

The pipeline is triggered by a Pull Request, which allows for validating changes before merging them into the main branch. A test branch named `test-branch` was created and pushed to initiate the workflow. The workflow then automatically started and passed the GitHub Actions check.

Azure Preparation

An existing Azure Container Registry (ACR) with the name `dessydevopsacr` and login server `dessydevopsacr.azurecr.io` was prepared for this exercise. The goal was to allow GitHub Actions to push Docker images into this registry without using a client secret.

Authentication Method

Instead of using the traditional approach of GitHub Actions → Client ID + Client Secret → Azure, OIDC was chosen for authentication. This method eliminates the need for a long-lived secret to be stored and managed. The authentication flow became GitHub Actions → OIDC token → Microsoft Entra ID → Azure.

Azure App Registration

In the Azure Portal, a new app registration was created under Microsoft Entra ID with the following details:

- Application (client) ID

- Object ID

- Directory (tenant) ID

These identifiers were provided by Azure and serve as important pieces of information for the authentication process. For a public article, it is recommended to replace these real IDs with placeholders such as `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, and `AZURE_SUBSCRIPTION_ID`.

Avoiding Client Secrets

Create a client secret inside the application registration was avoided in this exercise. Instead, the application has:

1. No client secrets (federated credentials)

2. 1 federated credential, which allows GitHub Actions to authenticate without storing an Azure password/secret.

Creating the Federated Credential

Inside the app registration, a federated credential was created using GitHub Actions deploying Azure resources. This step is crucial for GitHub Actions to authenticate securely with Azure without the need for a client secret.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

More from Tuesday 8 September →