Flux watches a Git repository containing Kubernetes manifests and it applies changes to the cluster. Realistically, you will also use Helm charts. You can install the Flux Helm operator so that you can declare what Helm charts should be installed on the cluster.
For example, install the Helm chart realworld-backend version 0.1.0 that is stored in my Azure container Registry.
apiVersion: helm.fluxcd.io/v1
kind: HelmRelease
metadata:
name: realworld-backend
namespace: realworld
spec:
releaseName: realworld-backend
chart:
repository: https:
name: realworld-backend
version: 0.1.0
values:
image:
repository: [your registry].azurecr.io/backend/realworld-backend
tag: 20200301.5
Background
I wrote a blog post recently on how to install Flux from Azure DevOps. We’ll be extending on that today.
Also, yesterday I wrote a guide on how to publish a Helm chart to an Azure Container Registry. See Part 1 and Part 2.
Configuring Flux
Here’s the thing. It’s a bit quirky. Thankfully, other people have ran into this before. With luck, you will too.
There’s an issue on GitHub where people are trying to get this working. They discover that in order for this to work with Azure Container Registry, you have to configure Helm’s repositories.yaml explicitly.
The quirky configuration
Again, you have to configure Helm’s repositories.yaml on Flux’s Helm operator that’s running on the cluster. It’s not straight forward or well documented.
This is what the repositories.yaml has to look like on the Kubernetes cluster.
apiVersion: v1
repositories:
- caFile: ""
cache: ...
certFile: ""
keyFile: ""
name: [name of your acr or repo]
password: [service principal client secret]
url: https:
username: [service principal client id]
We must provide:
- The repo name.
- The client id of a service principal that has at least
AcrPull rights to your ACR
- The client secret of that service principal
- The url of your ACR Helm endpoint. It must end with a slash.
Thankfully, the Helm chart to install the Helm operator supports this.
This is are the possible values for Flux’s Helm chart operator.
configureRepositories:
enable: false
volumeName: repositories-yaml
secretName: flux-helm-repositories
cacheVolumeName: repositories-cache
repositories:
Great! So as you can see, we’ll be able to specify the 4 attributes we need during installation of Flux’s Helm operator.
echo "installing flux. installing the helm operator"
helm upgrade -i helm-operator fluxcd/helm-operator \
--set git.ssh.secretName=flux-git-deploy \
--namespace flux \
--set helm.versions=v3 \
--set configureRepositories.enable=true \
--set configureRepositories.repositories[0].name=$(ACR.Name),configureRepositories.repositories[0].url=$(ACR.Url),configureRepositories.repositories[0].username=$(KubernetesServicePrincipal.ClientId),configureRepositories.repositories[0].password=$(KubernetesServicePrincipal.ClientSecret)
First, we set configureRepositories.enable to true.
Then we specify the name, url, username, and password of the repository configuration. We use an array notation because there can be multiple repository configurations.
That’s it. Install/upgrade Flux’s Helm operator.
Flux should have the necessary information to authenticate against Azure Container Registry to pull down any Helm charts you might have stored there.
I am assuming you already have a service principal to plug in. It must have at least AcrPull access to the registry. If you don’t have a service principal, see the section below.
Now, from your manifests repo, you should be able to declare custom Helm charts that reside in your very own Azure Container Registry.
Then Flux will ensure this Helm chart with this specific version is on the cluster.
Tada!
Service Principal
If you don’t have a service principal, you can create one using the Azure CLI. This Microsoft docs page can be very useful to you.
Based on the Microsoft docs. Here’s a script. Your --role could be just acrpull since Flux will only need to pull Helm charts down.
#!/bin/bash
ACR_NAME=<container-registry-name>
SERVICE_PRINCIPAL_NAME=acr-service-principal
ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query id --output tsv)
SP_PASSWD=$(az ad sp create-for-rbac --name http://$SERVICE_PRINCIPAL_NAME --scopes $ACR_REGISTRY_ID --role acrpull --query password --output tsv)
SP_APP_ID=$(az ad sp show --id http://$SERVICE_PRINCIPAL_NAME --query appId --output tsv)
echo "Service principal ID: $SP_APP_ID"
echo "Service principal password: $SP_PASSWD"