skip to content
Profile picture Oscar Corner

Building a GitOps Cluster

/ 2 min read

Bootstraping a k8s cluster.

All the code can be find in the following repo in the infra cluster folder.

Mutliple ways that we can make sure that once we have a cluster we have all the basics things installed on them:

  • Cert manager
  • Ingress controller
  • Secrets manger
  • Dns
  • Observability

We could use terraform to install along with the cluster, but that would tie the infrastructure along our apps. And if we want to scale we would need to make changes possibly to multiple places apply several clusters.

What if we could declare our applications in a stateful way and have a single source of truth?

That’s where GitOps comes to play.

First of all we need a k8s cluster check the we are going to use the 3 tier app one.

After that we make sure argo is installed this is the only app i’m going to install with terraform.


terraform {

  required_providers {
    helm = {
      source = "hashicorp/helm"
    }
  }
}
provider "helm" {
  kubernetes {
    host                   = var.clusterHost
    cluster_ca_certificate = base64decode(var.clusterToken)
    exec {
      api_version = "client.authentication.k8s.io/v1beta1"
      args        = ["eks", "get-token", "--cluster-name", var.clusterName]
      command     = "aws"
    }
  }
}
resource "helm_release" "argocd-install" {
  name             = "argocd"
  repository       = "https://argoproj.github.io/argo-helm"
  chart            = "argo-cd"
  namespace        = "argocd"
  create_namespace = true
  timeout          = 600
}

And once this is deployed we can get the credentials:

aws eks --region {{ region }} update-kubeconfig --name {{ cluster_name }}

Once this is deployed we can create an applicationset

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: dependencies
  namespace: argocd
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
    - git:
        repoURL: https://github.com/oscarsjlh/todo-app
        revision: main
        directories:
          - path: k8s/apps/*
  template:
    metadata:
      name: "{{.path.basename}}"
    spec:
      project: default
      source:
        repoURL: https://github.com/oscarsjlh/todo-app
        targetRevision: main
        helm:
          releaseName: "{{.path.basename}}"
          parameters:
          valueFiles:
            - "Values.yaml"
        path: "{{.path.path}}"
      destination:
        server: https://kubernetes.default.svc
        namespace: "{{.path.basename}}"
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
          - CreateNamespace=true

The application set allows us to use go template to parametise some parameters, so we avoid repeatng the common things.

And then we have the apps folder with the helm charts and Values we want to deploy

For example cert manager:

Chart.yaml


apiVersion: v2
name: cert-manager
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.0"
dependencies:
  - name: cert-manager
    version: v1.13.3
    repository: https://charts.jetstack.io

And Values.yaml


cert-manager:
  serviceAccount:
    annotations:
      eks.amazonaws.com/role-arn:
  securityContext:
    enabled: true
    fsGroup: 1001