Automating Kubernetes Deployments with Flux
Tags: git, devops, kubernetes, security
Published: 2023-09-27 14:06:36

Interested in making Kubernetes deployments more secure AND automated? If so, keep reading. :)

FluxCD, commonly just called Flux, is an open-source and cloud-native Continuous Delivery (CD) and GitOps tool designed to automate deployments to Kubernetes. 

And in this post, you'll learn how to install and configure Flux to automate the deployment of patched and signed containers images.

## Prerequisites

In the graphic above, you'll notice that the secure pipeline has two phases; build and deploy. This post focuses on automating the deploy phase, but that requires you already have the Azure infrastructure setup and a GitHub Action Workflow configured to handle the build or CI portion of the pipeline. So, you'll need to do some prerequisite work to follow along.

- [Setup the Azure environment](https://github.com/duffney/secure-supply-chain-on-aks/blob/GitOps/docs/setup.md)
- [Configure the GitHub Actions Workflow](https://github.com/duffney/secure-supply-chain-on-aks/blob/GitOps/docs/bonus.md)

Once you've completed the setup, you should have a working Azure environment with two signed container images for the Azure Voting app hosted in ACR, which is the necessary starting point for this post.

> Note: The setup for this is heavy, even though it's automated. So, if you'd like just continue reading and learn how Flux can be used to automate Kubernetes deployments. :)

## Setup the Local Dev Env

Flux is a GitOps tool and every GitOps tool needs a Git repository. To get the repo setup follow these steps:

1. Fork [secure-supply-chain-on-aks](https://github.com/duffney/secure-supply-chain-on-aks) repo.
2. Generate a token for Flux to access the repo. Here's a [great clip](https://youtu.be/5u45lXmhgxA?si=9mSjs_yO2bXFLI2R&t=836) to walk you through those steps.
3. Clone the repo to your local machine with, `git clone`.
4. Switch to the GitOps branch with `git checkout GitOps`

## Bootstrap FluxCD on the AKS Cluster

In order to get FluxCD working on the cluster, you're going to have to first deploy FluxCD operator to the cluster. Luckily, the FluxCLI makes this super easy. 

Here's what you need to do:

1. Install the [FluxCLI](https://fluxcd.io/flux/installation/#install-the-flux-cli)
2. Export the environment variables `GITHUB_TOKEN` and `GITHUB_USER`
    ```bash
     export GITHUB_TOKEN=<your-token>
     export GITHUB_USER=<your-username>
    ```
3. Run the `flux boostrap` command
    ```bash
    flux bootstrap github \
    --components-extra=image-reflector-controller, image-automation-controller \
    --owner=$GITHUB_USER \
    --repository=secure-supply-chain-on-aks \
    --branch=copaGitOps \
    --path=clusters/my-cluster \
    --read-write-key \
    --personal
    ```

Once this command completes, issue a `git pull` command and you'll notice a new directory call `cluster`. What the `flux bootstrap` command did was commit all the necessary manifests to deploy Flux to your cluster.

## Create a Flux Source

Now that Flux has been deployed the next thing you need to do is create a source. 

Flux supports several source options, but in this post, you'll use `git` as the source.

Run the following command to create the flux source manifest file:

```bash
flux create secret git azure-voting \
  --url=https://github.com/duffney/secure-supply-chain-on-aks \
  --username=$GITHUB_USER \
  --password=$GITHUB_TOKEN

flux create source git azure-voting \
  --url=https://github.com/duffney/secure-supply-chain-on-aks/ \
  --branch=GitOps \
  --interval=1m \
  --secret-ref azure-voting \
  --export > ./clusters/my-cluster/azure-voting-source.yaml
```

In the above, command the FluxCLI was used to generate a Kubernetes manifest file that configures the desired Git repository as a source within the Flux system. What this essentially does is makes Flux aware of the Git repository that you want to monitor for changes.

Run the following command to view all Flux Sources that use Git:

```bash
flux get sources git
```

Didn't see your repo listed⁉️ Well, that's the Flux system is looking at your GitHub repository for its changes! Flux itself uses GitOps to manage its deployments. 😅

Run the following commands to push the new Git source to the Flux system:

```bash
git add -A && git commit -m "Add azure-votiong-app GitRepository"
git push
```

Rerun `flux get sources git` again and you'll see the newly created source. Next, you'll configure which files within that repository Flux will care about.

## Create a Flux Kustomization

To use Flux with your Kubernetes deployments they need to be packaged somehow and one of the ways to do that is to use the popular resource configuration management tool, [Kustomize](https://kustomize.io/).

Kustomize gives you the ability to create a single file, called a `Kustmization.yaml` that bundles your deployment. It's that bundle, so to speak, that Flux uses to determine which files to monitor for changes in your GitRepo.

For this post, [kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/) has already been used to create a [Kustomization.yaml](https://github.com/duffney/secure-supply-chain-on-aks/blob/GitOps/manifests/kustomization.yaml) file that defines the Kubernetes manifests that are considered part of the deployment.

If you're following along, but using your own appliaction you can create a Kustomization.yaml file by running `kustomize create --autodetect` within the directory that contains the manifests.

But just having a `Kustomization.yaml` file within your repository isn't enough, Flux needs to be made aware of it and how you'd like it to run the deployment. 

So, to take care of that create a Flux Kustomization resources with the following command:

```bash
flux create kustomization azure-voting \
  --source=azure-voting \
  --path="./manifests" \
  --prune=true \
  --wait=true \
  --interval=1m \
  --retry-interval=2m \
  --health-check-timeout=3m \
  --export > ./clusters/my-cluster/azure-voting-kustomization.yaml
```

Oh, don't forget to push these changes to your repo too. :)

```bash
git add -A && git commit -m "Add azure-voting-app Kustomization"
git push
```

## Verify Azure-Voting-App deployed

Given the intervals set in the Kustomization and Source it shouldn't take long for Flux to deploy the Azure-Voting-App to the AKS cluster, but if you're eager to see what's going on you can run the following commands:

```bash
flux events
```

```bash
flux logs
```

## Test the Azure-Voting-App

Get the public IP address of the webapp with `kubectl get ingress`, and put it into a browsers and you should see the image below. 

![kubectl get ingress](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ofjz661c4u2t7ppp2tw8.png)

![Azure-voting-app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5v6dn2oo6s26fpm74sv.png)

## Next Steps

This post picked up after the build phase of the secure supply chain that is responsible for scanning, patching, and signing container images. If you'd like to learn more about that check out the following resources:

- [Securing container deployments on Azure Kubernetes Service with open-source tools | BRK264H](https://youtu.be/Mep9QWc3ByE?si=WgXJ4FE2XZrlmlzq)
- [Notation](https://notaryproject.dev/)
- [Copacetic](https://project-copacetic.github.io/copacetic/website/)

To dive deeper into GitOps, I highly recommend the follow articles written by my teammates:

- [Just Enough Git for GitOps](https://dev.to/azure/just-enough-git-for-gitops-3ok8)
- [What Really is GitOps?](https://dev.to/azure/what-really-is-gitops-4n2d)
- [Git going with GitOps on AKS: A Step-by-Step Guide using FluxCD AKS Extension](https://dev.to/azure/git-going-with-gitops-on-aks-a-step-by-step-guide-using-fluxcd-aks-extension-499m)
- [Automating Image Updates on AKS: A Step-by-Step Guide using open source FluxCD](https://dev.to/azure/automating-image-updates-with-fluxcd-on-aks-3i2d)

**Follow me** @joshduffney to catch my next post where I'll walk through using [Copacetic ](https://github.com/project-copacetic/copacetic)and FluxCD's Automate image updates to deploy patched container images.