# ArgoCD & GitOps The goal of this LCM is to create a one-click solution to spawn a fully configured OpenShift cluster. This document describes what happens after the cluster has been spawned on bare metal. We assume that we have access to the `kubeconfig` file for the `kubeadmin` which was generated by the installer. The configuration happens in two steps: 1.) A minimal ArgoCD installation and a set of credentials are bootstrapped via ansible. 2.) "Day 2" config-as-code is stored in the repo and deployed by ArgoCD. TL;DR for qa, for example: `ansible-navigator run playbooks/10_bootstrap_k8s.yaml -m stdout -i inventory/qa`. ## Step 1 - the bootstrapping This step consists of the deployment of an ArgoCD installation and the installation of required Secrets. ### Credential management We want to be able to automate the installation while at the same under no circumstances to store credentials in plain text in the version control system (VCS, git in our case). Traditional approaches to this problem include the usage of `SealedSecrets` or some other external secrets service like Hashicorps Vault. To keep things simple for now we follow a different approach and inject the credentials required for Day 2 via ansible. The role `ocp_bootstrap_secrets` expects a variable called `ocp_bootstrap_secrets` with the following format: ``` ocp_bootstrap_secrets: - name: argocd-git-repo namespace: openshift-gitops secrets: url: "{{ 'https://git.phoenix-systems.ch/redkvant/red.kvant.git' | b64encode }}" username: "{{ 'argocd' | b64encode }}" password: !vault | $ANSIBLE_VAULT;1.1;AES256 63366632623034356163336639313734363836373261623632663830643861376361343564373236 3761386163393264333162356461616136353838666138390a313530346232666365643532386339 64363535346130306338363332656432666233313266643938333535653562643231616531306665 6337356234303264360a613537626462633966366266326130646465383831323636616565306530 31313865326130303964626633363038303066326630333636663833656435363535333564646566 3232666131376166313135376633303565316362376464643037 ``` Each entry in the list needs a `name`, a `namespace` and a map of `secrets`. The implementation of the role is absolutely simple (check it out yourself!) as it just uses these values to instantiate a `Secret` template and the corresponding namespace. The actual secret data (in this case the content of the `password` field) is encrypted via `ansible-vault`. As of now there's no helpful tooling or an easy means for rotating keys but may be added in future. Or maybe not, because we switch to a more sophisticated service. #### Adding a new entry - We assume that you have access to the correct vault password file. - Add a new entry to the list. You can keep non-sensitive data in plain text but make sure to encode them with base64, e.g., by using the `| b64encode` filter. - Use the following prompt (or a derivative) to generate an encrypted field: `base64 -w 0 < mysecretfile | ansible-vault encrypt_string --name ` and copy the entry with proper indentation into the inventory variable file. - An example might be `echo -n mySuperPassword | base64 -w | ansible-vault encrypt_string --name password >> inventory/dev/group_vars/all/20_ocp_bootstrap_secrets.yaml` **Important:** Use your head! This role is just a very, very thin abstraction and doesn't cover any edge cases. It's just a utility. **Warning:** Depending on how the `Secret` and the `Namespace` are applied it is possible that certain fields can be overwritten. Use the `ocp_bootstrap_secrets` with caution for now! You may want to make use of `HISTCONTROL` to keep your shell from adding lines to the history that are prepended by a whitespace. ``` [red.kvant]$ export HISTCONTROL=ignoreboth [red.kvant]$ echo -n "mypassword" | base64 -w | ansible-vault encrypt_string >> vars/main.yaml" ``` ## ArgoCD The role `ocp_bootstrap_argocd` deploys the operator, performs basic configuration of the initial `ArgoCD` instance and sets up the so-called Application of Applications (app-of-apps). The repo is configured in the `argocd-git-repo` secret in the `openshift-gitops` namespace (see the example above). We're using Gitlab's Project Access Token (PAT) with a life time of one year. ArgoCD's service account is granted `cluster-admin` privileges so that it can operate in the entire environment. `app-of-apps` is, in a nutshell, a pattern to save you from writing unneccessary boilerplate code. There is a helm chart under `manifests/base/00-argocd-app-of-apps-chart` (copy of upstream project https://github.com/gnunn-gitops/argocd-app-of-app-chart) which essentially instantiates `Application` templates for you (see Step 2) for further information. ## Step 2 - Config-as-Code for Day 2 Config-as-Code is a pattern where instead of manually tweaking settings, you have the entire config under version control. We aim for this ideal in the cluster config. TL;DR: - Place your manifests under `manifests/base/your-app` - Optionally, create a `kustomization` under `manifests/overlays/dev/your-app` - Add an entry to the app-of-apps helm chart under `manifests/overlays/dev/00-argocd-app-of-apps-chart/values.yaml` It is easiest to check the existing entries and copy what they are doing. `base/` and `overlays/` denote `kustomize` terminology. - `base/` contains your actual manifests - `overlays/` has, as the name implies, potential overlays (patches) to adjust your resources to different environments, e.g., changing some URL endpoint. `overlays/dev` is, in this case, the overlay we use for our `dev` environment and `qa` might just get its own.