Problem Statement:
We are using argoCD for deploying helm charts on k8s clusters, via the traditional GitOps approach. ArgoCD uses a pull mechanism to source the helm charts of the applications it has to deploy on the k8s cluster.
We need to design a solution for Scoutflo where we need to connect to the user’s git repositories, build and push charts to a Helm repository and then connect these helm repositories to the argoCD instance deployed on the k8s cluster, to set-up the entire GitOps deployment workflow
Solution: [WIP]
The approach for this design was inspired by the philosophy of giving users as much control as we can, as a product. The flow for this would look something like as follows:
Engineering App 2. Scoutflo will use this connection to create a private repository on the user’s VCS which will be used to store the helm charts’ source code. Each repository will be named after the application, meaning one repository per application. 3. Scoutflo will pull the latest public packaged helm chart from the public helm repo of the open source application (for eg. Bitnami for mongoDB) and then untar the packaged helm chart and push the files to the created git repo in the user’s VCS, via a PR. 4. This repo will also come with some pre-configured files, one of them being a CI pipeline file (for eg. Github Actions, Bitbucket Pipelines). Once the PR is merged to master, the CI pipeline will start it’s run. It will compile, lint, build and package the helm chart with the latest version that was incremented in the PR. We will also automate the helm chart version increment in every PR that is pushed to master. Once the chart is successfully packaged with no errors, it will then push this chart to the user’s AWS ECR repo. 5. Initially, Scoutflo will create an ECR repo after creating the git repo as well:
aws configure #this is to configure the user's AWS account credentials, with region, access key, secret key
aws ecr create-repository --repository-name helm-test-chart --region ap-south-1 #note that the repository name has to match with the exact name of the helm chart in Chart.yaml
aws ecr get-login-password --region ap-south-1 | helm registry login --username AWS --password-stdin <aws_account_id>.dkr.ecr.ap-south-1.amazonaws.com #to authenticate helm with this ECR
helm push helm-test-chart-0.1.0.tgz oci://<aws_account_id>.dkr.ecr.ap-south-1.amazonaws.com/
This will automatically find the ECR repo that matches this helm chart name (hence the names have to match) and will push this helm chart to this ECR Repo following the OCI standards, with proper helm chart versioning.
apiVersion: batch/v1
kind: CronJob
metadata:
name: argocd-ecr-credentials
spec:
schedule: '0 */6 * * *' # every 6 hours, since credentials expire every 12 hours
jobTemplate:
metadata:
name: argocd-ecr-credentials
spec:
template:
spec:
serviceAccountName: argocd-server
restartPolicy: OnFailure
containers:
- name: update-secret
image: alpine/k8s:1.25.16 # Anything that contains kubectl + aws cli
command:
- /bin/bash
- "-c"
- |
PASSWORD=$(aws ecr get-login-password --region ap-south-1 | base64 -w 0)
kubectl patch secret -n argo-demo repo-721780964 --type merge -p "{\\"data\\": {\\"password\\": \\"$PASSWORD\\"}}"