Actions · Architecture · Azure · Azure CLI · FluxV2 · GitOps · Identity · Kubernetes · Kubernetes · managed-identity · Workflow

GitOps for AKS with Azure Blob Storage (Flux v2)

GitOps is a modern way of managing infrastructure and applications using Git as a single source of truth. Flux v2 is a Kubernetes-native GitOps toolkit that automates the deployment and lifecycle management of applications in Kubernetes clusters. In this blog post, we will show you how to use GitOps with Flux v2 on Azure Kubernetes service (AKS) with Azure Blob Storage instead of git repository. We will cover how to set up your AKS cluster, configure Flux v2, and deploy your application using GitOps.

Image source

Why?

You might be wondering why we need to use Azure Blob Storage while doing GitOps, instead of more commonly used cases where a Git repository is used. Well, there are scenarios, when you might have some restrictions in using Git repository with Flux, for instance, your repository is in Azure DevOps or GitHub, but your organization has policies on Personal Access Token (PAT) creations or very short lifetime enforced. In such circumstances, storing the manifest files, helm charts into Azure Blob storage could significantly simplify the problem. Given, we can also use Managed Identity, we can get rid of managing the secrets completely.

How?

The high-level architecture would look like following diagram:

The idea is still to use a repository to store the manifest files, but having a pipeline (GitHub workflow) that will publish the manifests (Kustomize files), HELM charts into a designated container in a Azure Blob storage. We will then configure the GitOps in Azure Kubernetes service to monitor the container and update/sync the cluster whenever we have “changes” published into the Blob container. Flux v2 has support for Bucket APIs that allows us to use a storage container technology instead of a Git repo, we will be using that.

Prerequisites

We would need following prerequisites:

  • Azure CLI (use the latest version, I am using 2.46.0)
  • An MSI-based AKS cluster that is provisioned and running.
Note:
Ensure that the AKS cluster is created with MSI (not SPN), because the microsoft.flux extension won't work with SPN-based AKS clusters. For new AKS clusters created with az aks create, the cluster will be MSI-based by default. For already created SPN-based clusters that need to be converted to MSI, run:
az aks update -g $RESOURCE_GROUP -n $CLUSTER_NAME --enable-managed-identity. 
  • Provider registrations (the following providers are required)
    • az provider register –namespace Microsoft.Kubernetes
    • az provider register –namespace Microsoft.ContainerService
    • az provider register –namespace Microsoft.KubernetesConfiguration
  • Following Azure CLI extensions installed.
    • az extension add -n k8s-configuration
    • az extension add -n k8s-extension
Installing Flux v2

We will begin installing the Microsoft.flux extension using Azure CLI.

ResourceGroup=aks-resource-group
AKSName=aks-demo-001

az k8s-extension create -g $ResourceGroup -c $AKSName -n flux --extension-type microsoft.flux -t managedClusters --auto-upgrade-minor-version true

Access control for AKS managed Identity to storage account

Next, we need to provide permissions for the Managed Identity for AKS so Flux can read the blobs from the blob container. Go into the AKS managed resource group and find the Managed Identity of type ‘Microsoft.ManagedIdentity/userAssignedIdentities‘ – typically it’s created with the following naming pattern: ‘ext-ab1234343xyz-cluster-name‘. Provide this identity ‘Storage Blob Contributor‘ role.

Deploy Redis with HELM

Let’s create a repo (GitHub/Azure DevOps -whatever makes you happy) with a folder named “Infra” and define some helm charts. I will be using the canonical example of redis.

We will fill out the HELM release for redis as follows:

The helm repo for redis (redis-chart.yaml) looks following:

apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
  name: redis
  namespace: cluster-config
spec:
  interval: 10m0s
  url: https://charts.bitnami.com/bitnami

And similarly, the (redis-release.yaml) looks following:

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: redis
  namespace: cluster-config
spec:
  chart:
    spec:
      chart: redis
      reconcileStrategy: ChartVersion
      sourceRef:
        kind: HelmRepository
        name: redis
  install:
    timeout: 30m
    createNamespace: true
    remediation:
      retries: 3
  interval: 1m0s
  releaseName: redis
  targetNamespace: redis

We can now create the pipeline that deploys these files into a Blob container named “infra”. For brevity, I am not including the pipeline or GitHub workflow here. (You would find myriads of examples online – or ChatGPT, how to accomplish that). Once we published these files into the blob container, let’s verify that form Storage explorer:

Creating GitOps configuration

We can now create the GitOps configuration for Flux pointing to the storage container via Azure CLI:

az k8s-configuration flux create   \
                   --resource-group $RG    \                
                   --cluster-name $CLUSTER \
                   --cluster-type managedClusters \
                   --name mygitopsconfig \
                   --scope cluster \
                   --namespace cluster-config \
                   --kind azblob \
                   --url https://gitopsmoimha.blob.core.windows.net \
                   --container-name infra \
                   --managed-identity-client-id 762e4e23-818c-453e-bbc5-96c4841e0033 \
                   --kustomization name=redis-installation  prune=true

This would create the GitOps configuration for the redis chart and we can monitor the progress in Portal from the GitOps tab:

Reconcile Flux

Now we can reconcile Flux to these changes:

flux reconcile source bucket mygitopsconfig -n cluster-config

Reconcile for the Kustomization config:

flux reconcile kustomization mygitopsconfig-redisinstallation -n cluster-config

That is it. Now we can make changes to the Git repo, which triggers our pipeline that publishes the manifest files to the Blob storage and Flux watches them and syncs the clusters.

Further reading

Leave a comment