Configure Image Automation with Flux
Tags: devops, security, containers, git
Published: 2023-09-29 15:05:24

In this post you'll continue the work built in Part 1 by adding Image Automation to the Azure Voting App deployment using FluxCD.

FluxCD's Image Automation allows you to monitor container image registries, allowing it to detect new image versions and automatically triggering updates according to the policies you define.

You can accomplish this by deploying three additional FluxCD resources, an image repository, image policy, and update automation. In addition to these three resources, you'll also make a slight change to the Kustomization.yml by marking the images so Flux knows what container images to update in the deployment.

Let's get started!

## Create an Image Repository

Before Flux can monitor a registry for new images, it must know what repository to monitor and that's the purpose of the Image Repository resource.

Now, because this tutorial uses a private Azure Container Registry instance you must do a little leg work first to set up a credential that Flux can use to authenticate to the registry.

Flux has several authentication options, but in this tutorial, you'll create a Kubernetes secret that stores an ACR token.

Run the following commands to create the ACR token, then create the Kubernetes secret:

```bash
registry=s3cexampleacr.azurecr.io
tokenName=flux

tokenPassword=$(az acr token create \
        --name $tokenName \
        --registry $registry \
        --scope-map _repositories_admin \
        --query 'credentials.passwords[0].value' \
        --only-show-errors \
        --output tsv)

kubectl create secret docker-registry regcred \
  --docker-server=$registry \
  --docker-username=$tokenName \
  --docker-password=$tokenPassword \
  --docker-email=fluxcdbot@users.noreply.github.com \
  --namespace=flux-system
```

Once the ACR token is stored in a Kubernetes secret, run the following command to create the image repository:

```bash
flux create image repository azure-voting \
  --image=s3cexampleacr.azurecr.io/azure-voting-app-rust \
  --interval=1m \
  --secret-ref regcred \
  --export > ./clusters/my-cluster/azure-voting-image.yaml
```

## Create an Image Policy

Next, you'll create an image policy. An image policy is the rules Flux follows to determine what images are newer. Often these rules are written to follow semantic versioning rules.

For example, if my application's container images are begins with the tag `v0.1.0-alpha` a valid select pattern would be `>=0.1.0-0`. This would allow Flux to detect that any semver higher than `v0.1.0-alpha` should be used to update the deployment.

Run the following command to create the image polciy:

```bash
flux create image policy azure-voting \
  --image-ref=azure-voting \
  --select-semver='>=0.1.0-0' \
  --export > ./clusters/my-cluster/azure-voting-image-policy.yaml
```

## Create the image update

At this stage, Flux has knowledge of the container registry and the specific container image you intend to track. It also possesses a policy for identifying newer images; however, it lacks information on which deployment files to alter when a newer version is identified. This is where image update resources come into play, as they serve the purpose of specifying which deployment files need modification when updates are detected.

The image update is important for several reasons, but the main  reason is, it's the resource that's going to be writing to your repository. 

What do I mean it will be writing to my repository? Well, when a newer version of the container image is detected the image update resource updates the image reference in the `Kustomization.yaml` will the latest image and image tag and that commit or change to the repository is what triggers the actual redeployment of the Kubernetes manifests by the other Flux resources that handle the application deployment.

Having Flux commit directly to your existing branches might make you nervous, and for good reason. If that's the case, you can choose to have these changes staged in a new branch and merge them in before a deployment is triggered. To learn how to do that check out the Flux docs [here](https://fluxcd.io/flux/guides/image-update/#push-updates-to-a-different-branch).

But, for this tutorial, we'll keep it simple and have it commit directly to our existing branch.

Run the following command to create the image update resource:

```bash
flux create image update azure-voting \
  --interval=1m \
  --git-repo-ref=azure-voting \
  --git-repo-path="./manifests" \
  --checkout-branch=copaGitOps \
  --author-name=fluxcdbot \
  --author-email=fluxcdbot@users.noreply.github.com \
  --commit-template="{{range .Updated.Images}}{{println .}}{{end}}" \
  --export > ./clusters/my-cluster/azure-voting-image-update.yaml
```

## Mark the Kustomization manifest

The last step in setting up image automation is to mark the Kustomization.yaml manifest with comments that indicate what container image should be modified by image update when new images version become available.

To make these changes, open the `kustomization.yaml` under `/manifests` and add the following comments:

```yaml
images:
  - name: azure-voting-app-rust
    newName: s3cexampleacr.azurecr.io/azure-voting-app-rust # {"$imagepolicy": "flux-system:azure-voting:name"}
    newTag: latest # {"$imagepolicy": "flux-system:azure-voting:tag"}
```

It's crazy how often automation comes back to `string/replace`, isn't it? Anyway, that's it! You're finished. 

Now when you push a new version of the container image to your container registry Flux will pick it up, modify the `kustomization.yaml` file, and that change will in turn trigger a new deployment to the Kubernetes cluster! Pretty awesome right? 

Well, it gets even better. In the next post, you'll learn how to use a new CNCF sandbox project called [Copacetic ](https://project-copacetic.github.io/copacetic/website/)to automatically patch your container images and use FluxCD to deploy the patched version. Keep your Kubernetes environment nice and secure!

**Follow me** @joshduffney to catch my next post.

Also, a quick shout out to my teammate Paul Yu who wrote a series of awesome [articles ](https://dev.to/azure/git-going-with-gitops-on-aks-a-step-by-step-guide-using-fluxcd-aks-extension-499m) on FluxCD. I referenced them a lot while writing this post.